Skip to content

Commit 74cb278

Browse files
devversionjelbourn
authored andcommitted
build: publish script should prompt for upstream remote (#15092)
1 parent 241dc94 commit 74cb278

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

tools/release/git/git-client.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,19 @@ export class GitClient {
9191
}
9292

9393
/** Pushes the specified tag to the remote git repository. */
94-
pushTagToRemote(tagName: string): boolean {
95-
return this._spawnGitProcess(['push', this.remoteGitUrl, `refs/tags/${tagName}`]).status === 0;
94+
pushTagToRemote(tagName: string, remoteName: string = this.remoteGitUrl): boolean {
95+
return this._spawnGitProcess(['push', remoteName, `refs/tags/${tagName}`]).status === 0;
96+
}
97+
98+
/** Checks whether the given remote has been set up. */
99+
hasRemote(remoteName: string): boolean {
100+
return this._spawnGitProcess(['remote', 'get-url', remoteName], false).status == 0;
101+
}
102+
103+
/** Gets a list of all available remotes set up. */
104+
getAvailableRemotes(): string[] {
105+
// Note that "git" always uses a line feed for new lines.
106+
return this._spawnGitProcess(['remote']).stdout.trim().split('\n');
96107
}
97108
}
98109

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {prompt} from 'inquirer';
2+
3+
/**
4+
* Prompts the current user-input interface for a Git remote that refers to the upstream
5+
* of the current Git project.
6+
*/
7+
export async function promptForUpstreamRemote(availableRemotes: string[]): Promise<string> {
8+
const {distTag} = await prompt<{ distTag: string }>({
9+
type: 'list',
10+
name: 'distTag',
11+
message: 'What is the Git remote for pushing changes upstream?',
12+
choices: availableRemotes.map(remoteName => ({value: remoteName, name: remoteName})),
13+
});
14+
15+
return distTag;
16+
}

tools/release/publish-release.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {GitClient} from './git/git-client';
99
import {getGithubNewReleaseUrl} from './git/github-urls';
1010
import {isNpmAuthenticated, runInteractiveNpmLogin, runNpmPublish} from './npm/npm-client';
1111
import {promptForNpmDistTag} from './prompt/npm-dist-tag-prompt';
12+
import {promptForUpstreamRemote} from './prompt/upstream-remote-prompt';
1213
import {releasePackages} from './release-output/release-packages';
1314
import {CHANGELOG_FILE_NAME} from './stage-release';
1415
import {parseVersionName, Version} from './version-name/parse-version';
@@ -76,6 +77,7 @@ class PublishReleaseTask extends BaseReleaseTask {
7677
this.verifyLastCommitVersionBump();
7778
this.verifyLocalCommitsMatchUpstream(publishBranch);
7879

80+
const upstreamRemote = await this.getProjectUpstreamRemote();
7981
const npmDistTag = await promptForNpmDistTag(newVersion);
8082

8183
// In case the user wants to publish a stable version to the "next" npm tag, we want
@@ -101,7 +103,7 @@ class PublishReleaseTask extends BaseReleaseTask {
101103

102104
// Create and push the release tag before publishing to NPM.
103105
this.createReleaseTag(newVersionName, releaseNotes);
104-
this.pushReleaseTag(newVersionName);
106+
this.pushReleaseTag(newVersionName, upstreamRemote);
105107

106108
// Ensure that we are authenticated before running "npm publish" for each package.
107109
this.checkNpmAuthentication();
@@ -250,7 +252,7 @@ class PublishReleaseTask extends BaseReleaseTask {
250252
}
251253

252254
/** Pushes the release tag to the remote repository. */
253-
private pushReleaseTag(tagName: string) {
255+
private pushReleaseTag(tagName: string, upstreamRemote: string) {
254256
const remoteTagSha = this.git.getShaOfRemoteTag(tagName);
255257
const expectedSha = this.git.getLocalCommitSha('HEAD');
256258

@@ -267,15 +269,27 @@ class PublishReleaseTask extends BaseReleaseTask {
267269
return;
268270
}
269271

270-
if (!this.git.pushTagToRemote(tagName)) {
271-
console.error(red(` ✘ Could not push the "${tagName} "tag upstream.`));
272+
if (!this.git.pushTagToRemote(tagName, upstreamRemote)) {
273+
console.error(red(` ✘ Could not push the "${tagName}" tag upstream.`));
272274
console.error(red(` Please make sure you have permission to push to the ` +
273275
`"${this.git.remoteGitUrl}" remote.`));
274276
process.exit(1);
275277
}
276278

277279
console.info(green(` ✓ Pushed release tag upstream.`));
278280
}
281+
282+
/**
283+
* Determines the name of the Git remote that is used for pushing changes
284+
* upstream to github.
285+
*/
286+
private async getProjectUpstreamRemote() {
287+
const remoteName = this.git.hasRemote('upstream') ?
288+
'upstream' : await promptForUpstreamRemote(this.git.getAvailableRemotes());
289+
290+
console.info(green(` ✓ Using the "${remoteName}" remote for pushing changes upstream.`));
291+
return remoteName;
292+
}
279293
}
280294

281295
/** Entry-point for the create release script. */

0 commit comments

Comments
 (0)