Skip to content

Commit 41b6021

Browse files
devversionjosephperrott
authored andcommitted
build: staging script should switch to publish branch (angular#14448)
* Rather than throwing an exception if an unexpected branch is currently checked out, we should just try switching to the expected publish branch.
1 parent 51b2c51 commit 41b6021

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

tools/release/git/git-client.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ export class GitClient {
3333
return spawnSync('git', ['diff-index', '--quiet', 'HEAD'], {cwd: this.projectDir}).status !== 0;
3434
}
3535

36+
/** Checks out an existing branch with the specified name. */
37+
checkoutBranch(branchName: string): boolean {
38+
return spawnSync('git', ['checkout', branchName], {cwd: this.projectDir}).status === 0;
39+
}
40+
3641
/** Creates a new branch which is based on the previous active branch. */
3742
checkoutNewBranch(branchName: string): boolean {
3843
return spawnSync('git', ['checkout', '-b', branchName], {cwd: this.projectDir}).status === 0;

tools/release/stage-release.ts

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ const CHANGELOG_FILE_NAME = 'CHANGELOG.md';
2020
*
2121
* 1) Prompt for release type (with version suggestion)
2222
* 2) Prompt for version name if no suggestions has been selected
23-
* 3) Assert that the proper publish branch is checked out (e.g. 6.4.x for patches)
24-
* 4) Assert that there are no local changes which are uncommitted.
25-
* 5) Assert that the local branch is up to date with the remote branch.
26-
* 6) Creates a new branch for the release staging (release-stage/{VERSION})
27-
* 7) Switches to the staging branch and updates the package.json
28-
* 8) Waits for the user to continue (users can generate the changelog in the meanwhile)
29-
* 9) Create a commit that includes all changes in the staging branch.
23+
* 3) Assert that there are no local changes which are uncommitted.
24+
* 4) Assert that the proper publish branch is checked out. (e.g. 6.4.x for patches)
25+
* If a different branch is used, try switching to the publish branch automatically
26+
* 5) Assert that the Github status checks pass for the publish branch.
27+
* 6) Assert that the local branch is up to date with the remote branch.
28+
* 7) Creates a new branch for the release staging (release-stage/{VERSION})
29+
* 8) Switches to the staging branch and updates the package.json
30+
* 9) Prompt for release name and generate changelog
31+
* 10) Wait for the user to continue (users can customize generated changelog)
32+
* 11) Create a commit that includes all changes in the staging branch.
3033
*/
3134
class StageReleaseTask {
3235

@@ -86,9 +89,10 @@ class StageReleaseTask {
8689
// new log messages to be more in the foreground.
8790
console.log();
8891

89-
this.verifyPublishBranch(expectedPublishBranch);
90-
this.verifyLocalCommitsMatchUpstream(expectedPublishBranch);
9192
this.verifyNoUncommittedChanges();
93+
this.switchToPublishBranch(expectedPublishBranch);
94+
95+
this.verifyLocalCommitsMatchUpstream(expectedPublishBranch);
9296
await this.verifyPassingGithubStatus();
9397

9498
const newVersionName = newVersion.format();
@@ -137,16 +141,28 @@ class StageReleaseTask {
137141
// TODO(devversion): automatic push and PR open URL shortcut.
138142
}
139143

140-
/** Verifies that the user is on the specified publish branch. */
141-
private verifyPublishBranch(expectedPublishBranch: string) {
144+
/**
145+
* Checks if the user is on the expected publish branch. If the user is on a different branch,
146+
* this function automatically tries to checkout the publish branch.
147+
*/
148+
private switchToPublishBranch(expectedPublishBranch: string): boolean {
142149
const currentBranchName = this.git.getCurrentBranch();
143150

144-
// Check if current branch matches the expected publish branch.
145-
if (expectedPublishBranch !== currentBranchName) {
146-
console.error(red(` ✘ Cannot stage release from "${italic(currentBranchName)}". Please ` +
147-
`stage the release from "${bold(expectedPublishBranch)}".`));
151+
// If current branch already matches the expected publish branch, just continue
152+
// by exiting this function.
153+
if (expectedPublishBranch === currentBranchName) {
154+
return;
155+
}
156+
157+
if (!this.git.checkoutBranch(expectedPublishBranch)) {
158+
console.error(red(` ✘ Could not switch to the "${italic(expectedPublishBranch)}" ` +
159+
`branch.`));
160+
console.error(red(` Please ensure that the branch exists or manually switch to the ` +
161+
`branch.`));
148162
process.exit(1);
149163
}
164+
165+
console.log(green(` ✓ Switched to the "${italic(expectedPublishBranch)}" branch.`));
150166
}
151167

152168
/** Verifies that the local branch is up to date with the given publish branch. */
@@ -166,8 +182,8 @@ class StageReleaseTask {
166182
/** Verifies that there are no uncommitted changes in the project. */
167183
private verifyNoUncommittedChanges() {
168184
if (this.git.hasUncommittedChanges()) {
169-
console.error(red(` ✘ Cannot stage release. There are changes which are not committed and ` +
170-
`should be stashed.`));
185+
console.error(red(` ✘ Cannot stage release. There are changes which are not committed ` +
186+
`and should be discarded.`));
171187
process.exit(1);
172188
}
173189
}

0 commit comments

Comments
 (0)