mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
f35369e304
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/32543 Changelog: [Internal] Fix npm `latest` tag issue that occurs when we release a patch on an older minor version Context: * There are two types of tags, git and npm, they are unrelated. * When we publish a stable release, we set the git tag `latest`. This logic is faulty when we release a patch to an older version. * When publishing a package to npm, if you don't provide an explicit tag, the `latest` tag will be applied -- at least that's how I've understood the [docs here](https://docs.npmjs.com/cli/v7/commands/npm-dist-tag#description). This again is faulty logic when we release a patch to an older version. * npm and git's `latest` tag should always point to our most recent stable version This change: * Introduces a `--latest` flag for `bump-oss-script` that will indicate that the release we're running (either a stable or pre-release) should really be considered "latest" * If the version is not a pre-release and the `--latest` flag is set, we will set the git `latest` tag * Later, in the circleCI job that we use to publish the npm package, we will see if the current commit is git-tagged as `latest`. If it is, then we'll explicitly tell npm to use `latest` tag but most importantly, if it's not, we'll set a tag of the form `{major}.{minor}-stable`. * This type of tag (ex. `0.66-stable`) is new and the intention is that it will always point to latest of that minor version. Reviewed By: hramos Differential Revision: D32196239 fbshipit-source-id: 4c881851eebcad8585732ff0c07322413ac46ce5
188 lines
5.5 KiB
JavaScript
188 lines
5.5 KiB
JavaScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @format
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* This script prepares a release version of react-native and may publish to NPM.
|
|
* It is supposed to run in CI environment, not on a developer's machine.
|
|
*
|
|
* To make it easier for developers it uses some logic to identify with which
|
|
* version to publish the package.
|
|
*
|
|
* To cut a branch (and release RC):
|
|
* - Developer: `git checkout -b 0.XY-stable`
|
|
* - Developer: `./scripts/bump-oss-version.js -v v0.XY.0-rc.0`
|
|
* - CI: test and deploy to npm (run this script) with version `0.XY.0-rc.0`
|
|
* with tag "next"
|
|
*
|
|
* To update RC release:
|
|
* - Developer: `git checkout 0.XY-stable`
|
|
* - Developer: cherry-pick whatever changes needed
|
|
* - Developer: `./scripts/bump-oss-version.js -v v0.XY.0-rc.1`
|
|
* - CI: test and deploy to npm (run this script) with version `0.XY.0-rc.1`
|
|
* with tag "next"
|
|
*
|
|
* To publish a release:
|
|
* - Developer: `git checkout 0.XY-stable`
|
|
* - Developer: cherry-pick whatever changes needed
|
|
* - Developer: `./scripts/bump-oss-version.js -v v0.XY.0`
|
|
* - CI: test and deploy to npm (run this script) with version `0.XY.0`
|
|
* and no tag ("latest" is implied by npm)
|
|
*
|
|
* To patch old release:
|
|
* - Developer: `git checkout 0.XY-stable`
|
|
* - Developer: cherry-pick whatever changes needed
|
|
* - Developer: `git tag v0.XY.Z`
|
|
* - Developer: `git push` to git@github.com:facebook/react-native.git (or merge as pull request)
|
|
* - CI: test and deploy to npm (run this script) with version 0.XY.Z with no tag, npm will not mark it as latest if
|
|
* there is a version higher than XY
|
|
*
|
|
* Important tags:
|
|
* If tag v0.XY.0-rc.Z is present on the commit then publish to npm with version 0.XY.0-rc.Z and tag next
|
|
* If tag v0.XY.Z is present on the commit then publish to npm with version 0.XY.Z and no tag (npm will consider it latest)
|
|
*/
|
|
|
|
const {exec, echo, exit, test} = require('shelljs');
|
|
const yargs = require('yargs');
|
|
const {parseVersion} = require('./version-utils');
|
|
|
|
const buildTag = process.env.CIRCLE_TAG;
|
|
const otp = process.env.NPM_CONFIG_OTP;
|
|
|
|
const argv = yargs
|
|
.option('n', {
|
|
alias: 'nightly',
|
|
type: 'boolean',
|
|
default: false,
|
|
})
|
|
.option('d', {
|
|
alias: 'dry-run',
|
|
type: 'boolean',
|
|
default: false,
|
|
}).argv;
|
|
const nightlyBuild = argv.nightly;
|
|
const dryRunBuild = argv.dryRun;
|
|
|
|
// 34c034298dc9cad5a4553964a5a324450fda0385
|
|
const currentCommit = exec('git rev-parse HEAD', {
|
|
silent: true,
|
|
}).stdout.trim();
|
|
const shortCommit = currentCommit.slice(0, 9);
|
|
|
|
const rawVersion =
|
|
// 0.0.0 triggers issues with cocoapods for codegen when building template project.
|
|
dryRunBuild
|
|
? '1000.0.0'
|
|
: // For nightly we continue to use 0.0.0 for clarity for npm
|
|
nightlyBuild
|
|
? '0.0.0'
|
|
: // For pre-release and stable releases, we use the git tag of the version we're releasing (set in bump-oss-version)
|
|
buildTag;
|
|
|
|
let version,
|
|
major,
|
|
minor,
|
|
prerelease = null;
|
|
try {
|
|
({version, major, minor, prerelease} = parseVersion(rawVersion));
|
|
} catch (e) {
|
|
echo(e.message);
|
|
exit(1);
|
|
}
|
|
let releaseVersion;
|
|
if (dryRunBuild) {
|
|
releaseVersion = `${version}-${shortCommit}`;
|
|
} else if (nightlyBuild) {
|
|
// 2021-09-28T05:38:40.669Z -> 20210928-0538
|
|
const dateIdentifier = new Date()
|
|
.toISOString()
|
|
.slice(0, -8)
|
|
.replace(/[-:]/g, '')
|
|
.replace(/[T]/g, '-');
|
|
releaseVersion = `${version}-${dateIdentifier}-${shortCommit}`;
|
|
} else {
|
|
releaseVersion = version;
|
|
}
|
|
|
|
// Bump version number in various files (package.json, gradle.properties etc)
|
|
// For stable, pre-release releases, we manually call bump-oss-version on release branch
|
|
if (nightlyBuild || dryRunBuild) {
|
|
if (
|
|
exec(
|
|
`node scripts/bump-oss-version.js --nightly --to-version ${releaseVersion}`,
|
|
).code
|
|
) {
|
|
echo('Failed to bump version number');
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
// -------- Generating Android Artifacts with JavaDoc
|
|
if (exec('./gradlew :ReactAndroid:installArchives').code) {
|
|
echo('Could not generate artifacts');
|
|
exit(1);
|
|
}
|
|
|
|
// undo uncommenting javadoc setting
|
|
exec('git checkout ReactAndroid/gradle.properties');
|
|
|
|
echo('Generated artifacts for Maven');
|
|
|
|
let artifacts = ['.aar', '.pom'].map(suffix => {
|
|
return `react-native-${releaseVersion}${suffix}`;
|
|
});
|
|
|
|
artifacts.forEach(name => {
|
|
if (
|
|
!test(
|
|
'-e',
|
|
`./android/com/facebook/react/react-native/${releaseVersion}/${name}`,
|
|
)
|
|
) {
|
|
echo(`file ${name} was not generated`);
|
|
exit(1);
|
|
}
|
|
});
|
|
|
|
if (dryRunBuild) {
|
|
echo('Skipping `npm publish` because --dry-run is set.');
|
|
exit(0);
|
|
}
|
|
|
|
// Running to see if this commit has been git tagged as `latest`
|
|
const latestCommit = exec("git rev-list -n 1 'latest'", {
|
|
silent: true,
|
|
}).stdout.replace('\n', '');
|
|
const isLatest = currentCommit === latestCommit;
|
|
|
|
const releaseBranch = `${major}.${minor}-stable`;
|
|
|
|
// Set the right tag for nightly and prerelease builds
|
|
// If a release is not git-tagged as `latest` we use `releaseBranch` to prevent
|
|
// npm from overriding the current `latest` version tag, which it will do if no tag is set.
|
|
const tagFlag = nightlyBuild
|
|
? '--tag nightly'
|
|
: prerelease != null
|
|
? '--tag next'
|
|
: isLatest
|
|
? '--tag latest'
|
|
: `--tag ${releaseBranch}`;
|
|
|
|
// 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 {
|
|
echo(`Published to npm ${releaseVersion}`);
|
|
exit(0);
|
|
}
|