Use one time password when publishing to npm (#20701)
Summary: This pull request addresses the failing publish-npm.js script from earlier this week. For background, last month we reset all npm access tokens for any package related to Facebook, and we now require all accounts with publish permissions to have two factor enabled. The publish-npm.js script relied on one such token that is configured in Circle CI as a envvar. The token has been updated in Circle CI, but we now need a way of passing the one time password to npm. With this PR, we can now grab the otp from Circle CI's envvars. Considering otps are ephemeral, this requires the NPM_CONFIG_OTP envvar to be set by someone with publishing permissions anytime a new release will be pushed to npm. The token is short lived, but it would still be good to clear the envvar after the package is published. Circle CI envvars are not passed on to PR/forked builds. This PR is effectively a breaking change for the release process, as the publish step will not succeed if the OTP is not valid. OTPs are short-lived, and the publish_npm_package job will definitely outlive the token. Unfortunately this will require some timing to get right, but the alternative is to ssh into the Circle CI machine and re-run the `npm publish --otp` command, which again would still require someone with publish access to provide the otp. Pull Request resolved: https://github.com/facebook/react-native/pull/20701 Differential Revision: D9478488 Pulled By: hramos fbshipit-source-id: 6af631a9cb425271b98c03d158aec390ebc95304
This commit is contained in:
parent
8103c431c8
commit
aae3a7816e
|
@ -596,8 +596,10 @@ jobs:
|
|||
publish_npm_package:
|
||||
<<: *android_defaults
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ~/react-native
|
||||
- checkout
|
||||
|
||||
- restore-cache: *restore-yarn-cache
|
||||
- run: *yarn
|
||||
|
||||
# Configure Android SDK and related dependencies
|
||||
- run: *configure-android-path
|
||||
|
@ -624,13 +626,19 @@ jobs:
|
|||
- run: *yarn
|
||||
|
||||
- run:
|
||||
name: Publish React Native Package
|
||||
name: Authenticate with npm
|
||||
command: echo "//registry.npmjs.org/:_authToken=${CIRCLE_NPM_TOKEN}" > ~/.npmrc
|
||||
|
||||
- run:
|
||||
name: Authenticate git user
|
||||
command: |
|
||||
echo "//registry.npmjs.org/:_authToken=${CIRCLE_NPM_TOKEN}" > ~/.npmrc
|
||||
git config --global user.email "reactjs-bot@users.noreply.github.com"
|
||||
git config --global user.email "react-native-bot@users.noreply.github.com"
|
||||
git config --global user.name "npm Deployment Script"
|
||||
echo "machine github.com login reactjs-bot password $GITHUB_TOKEN" > ~/.netrc
|
||||
node ./scripts/publish-npm.js
|
||||
echo "machine github.com login react-native-bot password $GITHUB_TOKEN" > ~/.netrc
|
||||
|
||||
- run:
|
||||
name: Publish React Native Package
|
||||
command: node ./scripts/publish-npm.js
|
||||
|
||||
# Workflows enables us to run multiple jobs in parallel
|
||||
workflows:
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
require('shelljs/global');
|
||||
|
||||
const buildBranch = process.env.CIRCLE_BRANCH;
|
||||
const otp = process.env.NPM_CONFIG_OTP;
|
||||
|
||||
let branchVersion;
|
||||
if (buildBranch.indexOf('-stable') !== -1) {
|
||||
|
@ -79,7 +80,7 @@ const tagsWithVersion = exec(`git ls-remote origin | grep ${currentCommit}`, {
|
|||
|
||||
if (tagsWithVersion.length === 0) {
|
||||
echo(
|
||||
"Error: Can't find version tag in current commit. To deploy to NPM you must add tag v0.XY.Z[-rc] to your commit",
|
||||
'Error: Cannot find version tag in current commit. To deploy to NPM you must add tag v0.XY.Z[-rc] to your commit',
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -96,7 +97,7 @@ if (tagsWithVersion[0].indexOf('-rc') === -1) {
|
|||
|
||||
// -------- Generating Android Artifacts with JavaDoc
|
||||
if (exec('./gradlew :ReactAndroid:installArchives').code) {
|
||||
echo("Couldn't generate artifacts");
|
||||
echo('Could not generate artifacts');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -121,15 +122,18 @@ artifacts.forEach(name => {
|
|||
}
|
||||
});
|
||||
|
||||
if (releaseVersion.indexOf('-rc') === -1) {
|
||||
// release, package will be installed by default
|
||||
exec('npm publish');
|
||||
// if version contains -rc, tag as prerelease
|
||||
const tagFlag = releaseVersion.indexOf('-rc') === -1 ? '' : '--tag next';
|
||||
|
||||
// use otp from envvars if available
|
||||
const otpFlag = otp ? `--otp ${otp}` : '';
|
||||
|
||||
if (exec(`npm publish ${tagFlag} ${otpFlag}`).code) {
|
||||
echo('Failed to publish package to npm');
|
||||
exit(1);
|
||||
} else {
|
||||
// RC release, package will be installed only if users specifically do it
|
||||
exec('npm publish --tag next');
|
||||
echo(`Published to npm ${releaseVersion}`);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
echo(`Published to npm ${releaseVersion}`);
|
||||
|
||||
exit(0);
|
||||
/*eslint-enable no-undef */
|
||||
|
|
Loading…
Reference in New Issue