generate-changelog.ts 3.0 KB

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