prCommitMessage.ts 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { DangerDSLType, DangerResults } from "danger";
  2. declare const danger: DangerDSLType;
  3. declare const warn: (message: string, results?: DangerResults) => void;
  4. interface Commit {
  5. message: string;
  6. }
  7. /**
  8. * Check if commit messages are sufficiently descriptive (not too short).
  9. *
  10. * Search for commit messages that appear to be automatically generated or temporary messages and report them.
  11. *
  12. * @dangerjs WARN
  13. */
  14. export default function (): void {
  15. const prCommits: Commit[] = danger.git.commits;
  16. const detectRegexes: RegExp[] = [
  17. /^Merge pull request #\d+ from .*/i, // Automatically generated message by GitHub
  18. /^Merged .+:.+ into .+/i, // Automatically generated message by GitHub
  19. /^Automatic merge by GitHub Action/i, // Automatically generated message by GitHub
  20. /^Merge branch '.*' of .+ into .+/i, // Automatically generated message by GitHub
  21. /^Create\s[a-zA-Z0-9_.-]+(\.[a-zA-Z0-9]{1,4})?(?=\s|$)/, // Automatically generated message by GitHub using UI
  22. /^Delete\s[a-zA-Z0-9_.-]+(\.[a-zA-Z0-9]{1,4})?(?=\s|$)/, // Automatically generated message by GitHub using UI
  23. /^Update\s[a-zA-Z0-9_.-]+(\.[a-zA-Z0-9]{1,4})?(?=\s|$)/, // Automatically generated message by GitHub using UI
  24. /^Initial commit/i, // Automatically generated message by GitHub
  25. /^WIP.*/i, // Message starts with prefix "WIP"
  26. /^Cleaned.*/i, // Message starts "Cleaned", , probably temporary
  27. /^Test:.*/i, // Message starts with "test" prefix, probably temporary
  28. /clean ?up/i, // Message contains "clean up", probably temporary
  29. /^[^A-Za-z0-9\s].*/, // Message starts with special characters
  30. ];
  31. let partMessages: string[] = [];
  32. for (const commit of prCommits) {
  33. const commitMessage: string = commit.message;
  34. const commitMessageTitle: string = commit.message.split("\n")[0];
  35. // Check if the commit message matches any regex from "detectRegexes"
  36. if (detectRegexes.some((regex) => commitMessage.match(regex))) {
  37. partMessages.push(
  38. `- the commit message \`${commitMessageTitle}\` appears to be a temporary or automatically generated message`
  39. );
  40. continue;
  41. }
  42. // Check if the commit message is not too short
  43. const shortCommitMessageThreshold: number = 20; // commit message is considered too short below this number of characters
  44. if (commitMessage.length < shortCommitMessageThreshold) {
  45. partMessages.push(
  46. `- the commit message \`${commitMessageTitle}\` may not be sufficiently descriptive`
  47. );
  48. }
  49. }
  50. // Create report
  51. if (partMessages.length) {
  52. partMessages.sort();
  53. let dangerMessage = `\nSome issues found for the commit messages in this MR:\n${partMessages.join(
  54. "\n"
  55. )}
  56. \nPlease consider updating these commit messages.`;
  57. warn(dangerMessage);
  58. }
  59. }