Skip to content

Commit 27d3b02

Browse files
devversionjelbourn
authored andcommitted
build: publish release script should add release notes to tag (#14599)
1 parent 0ba6057 commit 27d3b02

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {readFileSync} from 'fs';
2+
3+
/** Extracts the release notes for a specific release from a given changelog file. */
4+
export function extractReleaseNotes(changelogPath: string, versionName: string) {
5+
const changelogContent = readFileSync(changelogPath, 'utf8');
6+
const escapedVersion = versionName.replace('.', '\\.');
7+
8+
// Regular expression that matches the release notes for the given version. Note that we specify
9+
// the "s" RegExp flag so that the line breaks will be ignored within our regex. We determine the
10+
// section of a version by starting with the release header which can either use the markdown
11+
// "h1" or "h2" syntax. The end of the section will be matched by just looking for the first
12+
// subsequent release header.
13+
const releaseNotesRegex = new RegExp(`(##? ${escapedVersion}.*?)##? 7\\.`, 's');
14+
const matches = releaseNotesRegex.exec(changelogContent);
15+
16+
return matches ? matches[1].trim() : null;
17+
}

tools/release/publish-release.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import {execSync} from 'child_process';
33
import {readFileSync} from 'fs';
44
import {join} from 'path';
55
import {BaseReleaseTask} from './base-release-task';
6+
import {extractReleaseNotes} from './extract-release-notes';
67
import {GitClient} from './git/git-client';
78
import {getGithubReleasesUrl} from './git/github-urls';
89
import {isNpmAuthenticated, runInteractiveNpmLogin, runNpmPublish} from './npm/npm-client';
910
import {promptForNpmDistTag} from './prompt/npm-dist-tag-prompt';
1011
import {checkReleasePackage} from './release-output/check-packages';
1112
import {releasePackages} from './release-output/release-packages';
13+
import {CHANGELOG_FILE_NAME} from './stage-release';
1214
import {parseVersionName, Version} from './version-name/parse-version';
1315

1416
/** Maximum allowed tries to authenticate NPM. */
@@ -88,8 +90,17 @@ class PublishReleaseTask extends BaseReleaseTask {
8890
this.checkReleaseOutput();
8991
console.info(green(` ✓ Release output passed validation checks.`));
9092

93+
// Extract the release notes for the new version from the changelog file.
94+
const releaseNotes = extractReleaseNotes(
95+
join(this.projectDir, CHANGELOG_FILE_NAME), newVersionName);
96+
97+
if (!releaseNotes) {
98+
console.error(red(` ✘ Could not find release notes in the changelog.`));
99+
process.exit(1);
100+
}
101+
91102
// Create and push the release tag before publishing to NPM.
92-
this.createAndPushReleaseTag(newVersionName);
103+
this.createAndPushReleaseTag(newVersionName, releaseNotes);
93104

94105
// Ensure that we are authenticated before running "npm publish" for each package.
95106
this.checkNpmAuthentication();
@@ -230,9 +241,9 @@ class PublishReleaseTask extends BaseReleaseTask {
230241
}
231242

232243
/** Creates a specified tag and pushes it to the remote repository */
233-
private createAndPushReleaseTag(tagName: string) {
244+
private createAndPushReleaseTag(tagName: string, releaseNotes: string) {
234245
// TODO(devversion): find a way to extract the changelog part just for this version.
235-
if (!this.git.createTag('HEAD', tagName, '')) {
246+
if (!this.git.createTag('HEAD', tagName, releaseNotes)) {
236247
console.error(red(` ✘ Could not create the "${tagName}" tag.`));
237248
console.error(red(` Please make sure there is no existing tag with the same name.`));
238249
process.exit(1);

tools/release/stage-release.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {promptForNewVersion} from './prompt/new-version-prompt';
1010
import {parseVersionName, Version} from './version-name/parse-version';
1111

1212
/** Default filename for the changelog. */
13-
const CHANGELOG_FILE_NAME = 'CHANGELOG.md';
13+
export const CHANGELOG_FILE_NAME = 'CHANGELOG.md';
1414

1515
/**
1616
* Class that can be instantiated in order to stage a new release. The tasks requires user

0 commit comments

Comments
 (0)