From 59ac7e642c3bdff903f614b4d23b46857eb1481a Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Wed, 29 May 2019 11:18:08 +0200 Subject: [PATCH] build: release-staging script should have option to not bump version Adds a new prompt choice when staging a new release that can be used if the version has been updated before. In that case we don't want to bump the version automatically but rather use the existing version and generate the changelog for it. Closes #16136 --- tools/release/prompt/new-version-prompt.ts | 14 +++++-- tools/release/publish-release.ts | 14 +++---- tools/release/stage-release.ts | 20 +++++++--- tools/release/version-name/parse-version.ts | 42 +++++++++++---------- 4 files changed, 55 insertions(+), 35 deletions(-) diff --git a/tools/release/prompt/new-version-prompt.ts b/tools/release/prompt/new-version-prompt.ts index 8be1183da85c..2926a3ad5565 100644 --- a/tools/release/prompt/new-version-prompt.ts +++ b/tools/release/prompt/new-version-prompt.ts @@ -1,4 +1,4 @@ -import {ChoiceType, prompt} from 'inquirer'; +import {ChoiceType, prompt, Separator} from 'inquirer'; import {createNewVersion, ReleaseType} from '../version-name/create-version'; import {parseVersionName, Version} from '../version-name/parse-version'; import {determineAllowedPrereleaseLabels} from './prerelease-labels'; @@ -17,6 +17,7 @@ type VersionPromptAnswers = { export async function promptForNewVersion(currentVersion: Version): Promise { const allowedPrereleaseChoices = determineAllowedPrereleaseLabels(currentVersion); const versionChoices: ChoiceType[] = []; + const currentVersionName = currentVersion.format(); if (currentVersion.prereleaseLabel) { versionChoices.push( @@ -39,6 +40,11 @@ export async function promptForNewVersion(currentVersion: Version): Promise([{ type: 'list', name: 'proposedVersion', @@ -48,8 +54,10 @@ export async function promptForNewVersion(currentVersion: Version): Promise + !currentVersion.prereleaseLabel && proposedVersion !== currentVersionName, default: false, }, { type: 'list', diff --git a/tools/release/publish-release.ts b/tools/release/publish-release.ts index 1b5ab3df617f..f9dc4b8dba5d 100644 --- a/tools/release/publish-release.ts +++ b/tools/release/publish-release.ts @@ -79,7 +79,7 @@ class PublishReleaseTask extends BaseReleaseTask { // Branch that will be used to build the output for the release of the current version. const publishBranch = this.switchToPublishBranch(newVersion); - this._verifyLastCommitVersionBump(); + this._verifyLastCommitFromStagingScript(); this.verifyLocalCommitsMatchUpstream(publishBranch); const upstreamRemote = await this._getProjectUpstreamRemote(); @@ -147,13 +147,13 @@ class PublishReleaseTask extends BaseReleaseTask { } /** - * Verifies that the latest commit on the current branch is a version bump from the - * staging script. + * Verifies that the latest commit on the current branch has been created + * through the release staging script. */ - private _verifyLastCommitVersionBump() { - if (!/chore: bump version/.test(this.git.getCommitTitle('HEAD'))) { - console.error(red(` ✘ The latest commit of the current branch does not seem to be a ` + - `version bump.`)); + private _verifyLastCommitFromStagingScript() { + if (!/chore: (bump version|update changelog for)/.test(this.git.getCommitTitle('HEAD'))) { + console.error(red(` ✘ The latest commit of the current branch does not seem to be ` + + ` created by the release staging script.`)); console.error(red(` Please stage the release using the staging script.`)); process.exit(1); } diff --git a/tools/release/stage-release.ts b/tools/release/stage-release.ts index 8f5d92879d2b..2464420fbffd 100644 --- a/tools/release/stage-release.ts +++ b/tools/release/stage-release.ts @@ -76,6 +76,7 @@ class StageReleaseTask extends BaseReleaseTask { const newVersion = await promptForNewVersion(this.currentVersion); const newVersionName = newVersion.format(); + const needsVersionBump = !newVersion.equalsTo(this.currentVersion); const stagingBranch = `release-stage/${newVersionName}`; // After the prompt for the new version, we print a new line because we want the @@ -97,11 +98,13 @@ class StageReleaseTask extends BaseReleaseTask { process.exit(1); } - this._updatePackageJsonVersion(newVersionName); + if (needsVersionBump) { + this._updatePackageJsonVersion(newVersionName); - console.log(green(` ✓ Updated the version to "${bold(newVersionName)}" inside of the ` + - `${italic('package.json')}`)); - console.log(); + console.log(green(` ✓ Updated the version to "${bold(newVersionName)}" inside of the ` + + `${italic('package.json')}`)); + console.log(); + } await promptAndGenerateChangelog(join(this.projectDir, CHANGELOG_FILE_NAME)); @@ -119,7 +122,14 @@ class StageReleaseTask extends BaseReleaseTask { } this.git.stageAllChanges(); - this.git.createNewCommit(`chore: bump version to ${newVersionName} w/ changelog`); + + // Note: When updating the commit messages here. Please also update the + // release publish script to detect the new commit messages. + if (needsVersionBump) { + this.git.createNewCommit(`chore: bump version to ${newVersionName} w/ changelog`); + } else { + this.git.createNewCommit(`chore: update changelog for ${newVersionName}`); + } console.info(); console.info(green(` ✓ Created the staging commit for: "${newVersionName}".`)); diff --git a/tools/release/version-name/parse-version.ts b/tools/release/version-name/parse-version.ts index bc9fba5bf76f..347b1625b06b 100644 --- a/tools/release/version-name/parse-version.ts +++ b/tools/release/version-name/parse-version.ts @@ -2,18 +2,17 @@ const versionNameRegex = /^(\d+)\.(\d+)\.(\d+)(?:-(alpha|beta|rc)\.(\d)+)?$/; export class Version { - constructor( - /** Major version number */ - public major: number, - /** Minor version number */ - public minor: number, - /** Patch version number */ - public patch: number, - /** Pre-release label for the version (e.g. alpha, beta, rc) */ - public prereleaseLabel?: string, - /** Number for the pre-release. There can be multiple pre-releases for a version. */ - public prereleaseNumber?: number) {} + /** Major version number */ + public major: number, + /** Minor version number */ + public minor: number, + /** Patch version number */ + public patch: number, + /** Pre-release label for the version (e.g. alpha, beta, rc) */ + public prereleaseLabel: string|null, + /** Number for the pre-release. There can be multiple pre-releases for a version. */ + public prereleaseNumber: number|null) {} /** Serializes the version info into a string formatted version name. */ format(): string { @@ -21,8 +20,14 @@ export class Version { } clone(): Version { - return new Version(this.major, this.minor, this.patch, this.prereleaseLabel, - this.prereleaseNumber); + return new Version( + this.major, this.minor, this.patch, this.prereleaseLabel, this.prereleaseNumber); + } + + equalsTo(other: Version): boolean { + return this.major === other.major && this.minor === other.minor && this.patch === other.patch && + this.prereleaseLabel === other.prereleaseLabel && + this.prereleaseNumber === other.prereleaseNumber; } } @@ -30,7 +35,7 @@ export class Version { * Parses the specified version and returns an object that represents the individual * version segments. */ -export function parseVersionName(version: string): Version | null { +export function parseVersionName(version: string): Version|null { const matches = version.match(versionNameRegex); if (!matches) { @@ -38,11 +43,8 @@ export function parseVersionName(version: string): Version | null { } return new Version( - Number(matches[1]), - Number(matches[2]), - Number(matches[3]), - matches[4], - Number(matches[5])); + Number(matches[1]), Number(matches[2]), Number(matches[3]), matches[4] || null, + Number(matches[5]) || null); } /** Serializes the specified version into a string. */ @@ -51,7 +53,7 @@ export function serializeVersion(newVersion: Version): string { let versionString = `${major}.${minor}.${patch}`; - if (prereleaseLabel && !isNaN(prereleaseNumber)) { + if (prereleaseLabel && prereleaseNumber !== null) { versionString += `-${prereleaseLabel}.${prereleaseNumber}`; }