From c0948606586cfe416f139e1ae9781154d7b279ca Mon Sep 17 00:00:00 2001 From: Jeremy Elbourn Date: Mon, 11 Feb 2019 15:59:05 -0800 Subject: [PATCH] build(release-script): npm logout after publishing --- tools/release/npm/npm-client.ts | 12 ++++++++++-- tools/release/publish-release.ts | 17 ++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/tools/release/npm/npm-client.ts b/tools/release/npm/npm-client.ts index f741d3eda276..81d49f623a3e 100644 --- a/tools/release/npm/npm-client.ts +++ b/tools/release/npm/npm-client.ts @@ -20,7 +20,7 @@ export function isNpmAuthenticated(): boolean { } /** Runs "npm login" interactively by piping stdin/stderr/stdout to the current tty. */ -export function runInteractiveNpmLogin(): boolean { +export function npmLoginInteractive(): boolean { return spawnSync('npm', ['login'], { stdio: 'inherit', shell: true, @@ -29,7 +29,7 @@ export function runInteractiveNpmLogin(): boolean { } /** Runs NPM publish within a specified directory */ -export function runNpmPublish(packagePath: string, distTag: string): string | null { +export function npmPublish(packagePath: string, distTag: string): string | null { const result = spawnSync('npm', ['publish', '--access', 'public', '--tag', distTag], { cwd: packagePath, shell: true, @@ -42,3 +42,11 @@ export function runNpmPublish(packagePath: string, distTag: string): string | nu return result.stderr.toString(); } } + +/** Log out of npm. */ +export function npmLogout(): boolean { + return spawnSync('npm', ['logout'], { + shell: true, + env: npmClientEnvironment, + }).status === 0; +} diff --git a/tools/release/publish-release.ts b/tools/release/publish-release.ts index 1e547597c5a8..39b6b81cb0e1 100644 --- a/tools/release/publish-release.ts +++ b/tools/release/publish-release.ts @@ -7,7 +7,12 @@ import {checkReleaseOutput} from './check-release-output'; import {extractReleaseNotes} from './extract-release-notes'; import {GitClient} from './git/git-client'; import {getGithubNewReleaseUrl} from './git/github-urls'; -import {isNpmAuthenticated, runInteractiveNpmLogin, runNpmPublish} from './npm/npm-client'; +import { + isNpmAuthenticated, + npmLogout, + npmLoginInteractive, + npmPublish, +} from './npm/npm-client'; import {promptForNpmDistTag} from './prompt/npm-dist-tag-prompt'; import {promptForUpstreamRemote} from './prompt/upstream-remote-prompt'; import {releasePackages} from './release-output/release-packages'; @@ -125,6 +130,12 @@ class PublishReleaseTask extends BaseReleaseTask { console.log(); console.info(green(bold(` ✓ Published all packages successfully`))); + + // Always log out of npm after releasing to prevent unintentional changes to + // any packages. + npmLogout(); + console.info(green(bold(` ✓ Logged out of npm`))); + console.info(yellow(` ⚠ Please draft a new release of the version on Github.`)); console.info(yellow(` ${newReleaseUrl}`)); } @@ -194,7 +205,7 @@ class PublishReleaseTask extends BaseReleaseTask { console.log(yellow(` ⚠ NPM is currently not authenticated. Running "npm login"..`)); for (let i = 0; i < MAX_NPM_LOGIN_TRIES; i++) { - if (runInteractiveNpmLogin()) { + if (npmLoginInteractive()) { // In case the user was able to login properly, we want to exit the loop as we // don't need to ask for authentication again. break; @@ -217,7 +228,7 @@ class PublishReleaseTask extends BaseReleaseTask { private publishPackageToNpm(packageName: string, npmDistTag: string) { console.info(green(` ⭮ Publishing "${packageName}"..`)); - const errorOutput = runNpmPublish(join(this.releaseOutputPath, packageName), npmDistTag); + const errorOutput = npmPublish(join(this.releaseOutputPath, packageName), npmDistTag); if (errorOutput) { console.error(red(` ✘ An error occurred while publishing "${packageName}".`));