generate-changelog.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import fs from 'fs-extra';
  2. import path from 'path';
  3. import { addStream } from './add-stream';
  4. // eslint-disable-next-line @typescript-eslint/no-var-requires
  5. const conventionalChangelogCore = require('conventional-changelog-core');
  6. let changelogFileName = 'CHANGELOG.md';
  7. if (process.argv.includes('--next') || process.env.npm_config_argv?.includes('publish-prerelease')) {
  8. changelogFileName = 'CHANGELOG_NEXT.md';
  9. }
  10. /**
  11. * The types of commit which will be included in the changelog.
  12. */
  13. const VALID_TYPES = ['feat', 'fix', 'perf'];
  14. /**
  15. * Define which packages to create changelog entries for.
  16. */
  17. const VALID_SCOPES: string[] = [
  18. 'admin-ui-plugin',
  19. 'admin-ui',
  20. 'asset-server',
  21. 'asset-server-plugin',
  22. 'cli',
  23. 'common',
  24. 'core',
  25. 'create',
  26. 'dashboard',
  27. 'elasticsearch-plugin',
  28. 'email-plugin',
  29. 'email',
  30. 'job-queue-plugin',
  31. 'payments-plugin',
  32. 'testing',
  33. 'ui-devkit',
  34. 'harden-plugin',
  35. 'stellate-plugin',
  36. 'sentry-plugin',
  37. 'graphiql-plugin',
  38. 'telemetry-plugin',
  39. ];
  40. const mainTemplate = fs.readFileSync(path.join(__dirname, 'template.hbs'), 'utf-8');
  41. const commitTemplate = fs.readFileSync(path.join(__dirname, 'commit.hbs'), 'utf-8');
  42. generateChangelogForPackage();
  43. /**
  44. * Generates changelog entries based on the conventional commits data.
  45. */
  46. function generateChangelogForPackage() {
  47. const changelogPath = path.join(__dirname, '../../', changelogFileName);
  48. const inStream = fs.createReadStream(changelogPath, { flags: 'a+' });
  49. const tempFile = path.join(__dirname, `__temp_changelog__`);
  50. conventionalChangelogCore(
  51. {
  52. transform: (commit: any, context: any) => {
  53. const includeCommit = VALID_TYPES.includes(commit.type) && scopeIsValid(commit.scope);
  54. if (includeCommit) {
  55. return context(null, commit);
  56. } else {
  57. return context(null, null);
  58. }
  59. },
  60. releaseCount: 1,
  61. outputUnreleased: true,
  62. },
  63. {
  64. version: require('../../lerna.json').version,
  65. },
  66. null,
  67. null,
  68. {
  69. mainTemplate,
  70. commitPartial: commitTemplate,
  71. finalizeContext(context: any, options: any, commits: any) {
  72. context.commitGroups.forEach(addHeaderToCommitGroup);
  73. return context;
  74. },
  75. },
  76. )
  77. .pipe(addStream(inStream))
  78. .pipe(fs.createWriteStream(tempFile))
  79. .on('finish', () => {
  80. fs.createReadStream(tempFile)
  81. .pipe(fs.createWriteStream(changelogPath))
  82. .on('finish', () => {
  83. fs.unlinkSync(tempFile);
  84. });
  85. });
  86. }
  87. function scopeIsValid(scope?: string): boolean {
  88. for (const validScope of VALID_SCOPES) {
  89. if (scope && scope.includes(validScope)) {
  90. return true;
  91. }
  92. }
  93. return false;
  94. }
  95. /**
  96. * The `header` is a more human-readable version of the commit type, as used in the
  97. * template.hbs as a sub-heading.
  98. */
  99. function addHeaderToCommitGroup(commitGroup: any) {
  100. switch (commitGroup.title) {
  101. case 'fix':
  102. commitGroup.header = 'Fixes';
  103. break;
  104. case 'feat':
  105. commitGroup.header = 'Features';
  106. break;
  107. default:
  108. commitGroup.header = commitGroup.title.charAt(0).toUpperCase() + commitGroup.title.slice(1);
  109. break;
  110. }
  111. }