updateChangelog.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. const fs = require("fs");
  2. const util = require("util");
  3. const exec = util.promisify(require("child_process").exec);
  4. const excalidrawDir = `${__dirname}/../packages/excalidraw`;
  5. const excalidrawPackage = `${excalidrawDir}/package.json`;
  6. const pkg = require(excalidrawPackage);
  7. const lastVersion = pkg.version;
  8. const existingChangeLog = fs.readFileSync(
  9. `${excalidrawDir}/CHANGELOG.md`,
  10. "utf8",
  11. );
  12. const supportedTypes = ["feat", "fix", "style", "refactor", "perf", "build"];
  13. const headerForType = {
  14. feat: "Features",
  15. fix: "Fixes",
  16. style: "Styles",
  17. refactor: " Refactor",
  18. perf: "Performance",
  19. build: "Build",
  20. };
  21. const badCommits = [];
  22. const getCommitHashForLastVersion = async () => {
  23. try {
  24. const commitMessage = `"release @excalidraw/excalidraw"`;
  25. const { stdout } = await exec(
  26. `git log --format=format:"%H" --grep=${commitMessage}`,
  27. );
  28. // take commit hash from latest release
  29. return stdout.split(/\r?\n/)[0];
  30. } catch (error) {
  31. console.error(error);
  32. }
  33. };
  34. const getLibraryCommitsSinceLastRelease = async () => {
  35. const commitHash = await getCommitHashForLastVersion();
  36. const { stdout } = await exec(
  37. `git log --pretty=format:%s ${commitHash}...master`,
  38. );
  39. const commitsSinceLastRelease = stdout.split("\n");
  40. const commitList = {};
  41. supportedTypes.forEach((type) => {
  42. commitList[type] = [];
  43. });
  44. commitsSinceLastRelease.forEach((commit) => {
  45. const indexOfColon = commit.indexOf(":");
  46. const type = commit.slice(0, indexOfColon);
  47. if (!supportedTypes.includes(type)) {
  48. return;
  49. }
  50. const messageWithoutType = commit.slice(indexOfColon + 1).trim();
  51. const messageWithCapitalizeFirst =
  52. messageWithoutType.charAt(0).toUpperCase() + messageWithoutType.slice(1);
  53. const prMatch = commit.match(/\(#([0-9]*)\)/);
  54. if (prMatch) {
  55. const prNumber = prMatch[1];
  56. // return if the changelog already contains the pr number which would happen for package updates
  57. if (existingChangeLog.includes(prNumber)) {
  58. return;
  59. }
  60. const prMarkdown = `[#${prNumber}](https://github.com/excalidraw/excalidraw/pull/${prNumber})`;
  61. const messageWithPRLink = messageWithCapitalizeFirst.replace(
  62. /\(#[0-9]*\)/,
  63. prMarkdown,
  64. );
  65. commitList[type].push(messageWithPRLink);
  66. } else {
  67. badCommits.push(commit);
  68. commitList[type].push(messageWithCapitalizeFirst);
  69. }
  70. });
  71. console.info("Bad commits:", badCommits);
  72. return commitList;
  73. };
  74. const updateChangelog = async (nextVersion) => {
  75. const commitList = await getLibraryCommitsSinceLastRelease();
  76. let changelogForLibrary =
  77. "## Excalidraw Library\n\n**_This section lists the updates made to the excalidraw library and will not affect the integration._**\n\n";
  78. supportedTypes.forEach((type) => {
  79. if (commitList[type].length) {
  80. changelogForLibrary += `### ${headerForType[type]}\n\n`;
  81. const commits = commitList[type];
  82. commits.forEach((commit) => {
  83. changelogForLibrary += `- ${commit}\n\n`;
  84. });
  85. }
  86. });
  87. changelogForLibrary += "---\n";
  88. const lastVersionIndex = existingChangeLog.indexOf(`## ${lastVersion}`);
  89. let updatedContent =
  90. existingChangeLog.slice(0, lastVersionIndex) +
  91. changelogForLibrary +
  92. existingChangeLog.slice(lastVersionIndex);
  93. const currentDate = new Date().toISOString().slice(0, 10);
  94. const newVersion = `## ${nextVersion} (${currentDate})`;
  95. updatedContent = updatedContent.replace(`## Unreleased`, newVersion);
  96. fs.writeFileSync(`${excalidrawDir}/CHANGELOG.md`, updatedContent, "utf8");
  97. };
  98. module.exports = updateChangelog;