Skip to content

Commit f6564cd

Browse files
authored
build: add otp prompt to release tool (#17035)
1 parent c29c507 commit f6564cd

File tree

3 files changed

+29
-10
lines changed

3 files changed

+29
-10
lines changed

tools/release/npm/npm-client.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,13 @@ export function npmLoginInteractive(): boolean {
2929
}
3030

3131
/** Runs NPM publish within a specified directory */
32-
export function npmPublish(packagePath: string, distTag: string): string | null {
33-
const result = spawnSync('npm', ['publish', '--access', 'public', '--tag', distTag], {
34-
cwd: packagePath,
35-
shell: true,
36-
env: npmClientEnvironment,
37-
});
32+
export function npmPublish(packagePath: string, distTag: string, otp: string): string | null {
33+
const result =
34+
spawnSync('npm', ['publish', '--access', 'public', '--tag', distTag, '--otp', otp], {
35+
cwd: packagePath,
36+
shell: true,
37+
env: npmClientEnvironment,
38+
});
3839

3940
// We only want to return an error if the exit code is not zero. NPM by default prints the
4041
// logging messages to "stdout" and therefore just checking for "stdout" is not reliable.

tools/release/prompt/npm-dist-tag-prompt.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@ export async function promptForNpmDistTag(version: Version): Promise<string> {
2424
return distTag;
2525
}
2626

27+
/**
28+
* Prompts the current user-input interface for a npm one-time password (OTP). This is required
29+
* to publish packages in the @angular namespace.
30+
*/
31+
export async function promptForNpmOtp(): Promise<string> {
32+
const {otp} = await prompt<{otp: string}>({
33+
type: 'text',
34+
name: 'otp',
35+
message: 'Enter the one-time password (OTP) for the angular npm account:',
36+
});
37+
38+
return otp;
39+
}
40+
2741
/**
2842
* Determines all allowed npm dist-tag choices for a specified version. For example,
2943
* a pre-release version should be never published to the "latest" tag.

tools/release/publish-release.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
npmLoginInteractive,
1414
npmPublish,
1515
} from './npm/npm-client';
16-
import {promptForNpmDistTag} from './prompt/npm-dist-tag-prompt';
16+
import {promptForNpmDistTag, promptForNpmOtp} from './prompt/npm-dist-tag-prompt';
1717
import {promptForUpstreamRemote} from './prompt/upstream-remote-prompt';
1818
import {releasePackages} from './release-output/release-packages';
1919
import {CHANGELOG_FILE_NAME} from './stage-release';
@@ -123,8 +123,12 @@ class PublishReleaseTask extends BaseReleaseTask {
123123
// the user to interactively confirm that the script should continue.
124124
await this._promptConfirmReleasePublish();
125125

126+
// Prompt for the OTP right before publishing so that it doesn't expire while building the
127+
// packages.
128+
const npmOtp = await promptForNpmOtp();
129+
126130
for (let packageName of releasePackages) {
127-
this._publishPackageToNpm(packageName, npmDistTag);
131+
this._publishPackageToNpm(packageName, npmDistTag, npmOtp);
128132
}
129133

130134
const newReleaseUrl = getGithubNewReleaseUrl({
@@ -237,10 +241,10 @@ class PublishReleaseTask extends BaseReleaseTask {
237241
}
238242

239243
/** Publishes the specified package within the given NPM dist tag. */
240-
private _publishPackageToNpm(packageName: string, npmDistTag: string) {
244+
private _publishPackageToNpm(packageName: string, npmDistTag: string, npmOtp: string) {
241245
console.info(green(` ⭮ Publishing "${packageName}"..`));
242246

243-
const errorOutput = npmPublish(join(this.releaseOutputPath, packageName), npmDistTag);
247+
const errorOutput = npmPublish(join(this.releaseOutputPath, packageName), npmDistTag, npmOtp);
244248

245249
if (errorOutput) {
246250
console.error(red(` ✘ An error occurred while publishing "${packageName}".`));

0 commit comments

Comments
 (0)