Skip to content

build: publish release script should add release notes to tag #14599

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions tools/release/extract-release-notes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {readFileSync} from 'fs';

/** Extracts the release notes for a specific release from a given changelog file. */
export function extractReleaseNotes(changelogPath: string, versionName: string) {
const changelogContent = readFileSync(changelogPath, 'utf8');
const escapedVersion = versionName.replace('.', '\\.');

// Regular expression that matches the release notes for the given version. Note that we specify
// the "s" RegExp flag so that the line breaks will be ignored within our regex. We determine the
// section of a version by starting with the release header which can either use the markdown
// "h1" or "h2" syntax. The end of the section will be matched by just looking for the first
// subsequent release header.
const releaseNotesRegex = new RegExp(`(##? ${escapedVersion}.*?)##? 7\\.`, 's');
const matches = releaseNotesRegex.exec(changelogContent);

return matches ? matches[1].trim() : null;
Copy link
Member Author

@devversion devversion Dec 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to think about a more efficient way and initially used a read stream since the changelog file can technically become huge over the years, but that was just so much overhead, so I just went with the simple approach.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should move all the pre 5.0.0 stuff to another file at some point

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}
17 changes: 14 additions & 3 deletions tools/release/publish-release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import {execSync} from 'child_process';
import {readFileSync} from 'fs';
import {join} from 'path';
import {BaseReleaseTask} from './base-release-task';
import {extractReleaseNotes} from './extract-release-notes';
import {GitClient} from './git/git-client';
import {getGithubReleasesUrl} from './git/github-urls';
import {isNpmAuthenticated, runInteractiveNpmLogin, runNpmPublish} from './npm/npm-client';
import {promptForNpmDistTag} from './prompt/npm-dist-tag-prompt';
import {checkReleasePackage} from './release-output/check-packages';
import {releasePackages} from './release-output/release-packages';
import {CHANGELOG_FILE_NAME} from './stage-release';
import {parseVersionName, Version} from './version-name/parse-version';

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

// Extract the release notes for the new version from the changelog file.
const releaseNotes = extractReleaseNotes(
join(this.projectDir, CHANGELOG_FILE_NAME), newVersionName);

if (!releaseNotes) {
console.error(red(` ✘ Could not find release notes in the changelog.`));
process.exit(1);
}

// Create and push the release tag before publishing to NPM.
this.createAndPushReleaseTag(newVersionName);
this.createAndPushReleaseTag(newVersionName, releaseNotes);

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

/** Creates a specified tag and pushes it to the remote repository */
private createAndPushReleaseTag(tagName: string) {
private createAndPushReleaseTag(tagName: string, releaseNotes: string) {
// TODO(devversion): find a way to extract the changelog part just for this version.
if (!this.git.createTag('HEAD', tagName, '')) {
if (!this.git.createTag('HEAD', tagName, releaseNotes)) {
console.error(red(` ✘ Could not create the "${tagName}" tag.`));
console.error(red(` Please make sure there is no existing tag with the same name.`));
process.exit(1);
Expand Down
2 changes: 1 addition & 1 deletion tools/release/stage-release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {promptForNewVersion} from './prompt/new-version-prompt';
import {parseVersionName, Version} from './version-name/parse-version';

/** Default filename for the changelog. */
const CHANGELOG_FILE_NAME = 'CHANGELOG.md';
export const CHANGELOG_FILE_NAME = 'CHANGELOG.md';

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