mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
[LOCAL] backport from 0.66 the logic to deploy new releases
This commit is contained in:
+43
-22
@@ -19,6 +19,7 @@
|
||||
const fs = require('fs');
|
||||
const {cat, echo, exec, exit, sed} = require('shelljs');
|
||||
const yargs = require('yargs');
|
||||
const {parseVersion} = require('./version-utils');
|
||||
|
||||
let argv = yargs
|
||||
.option('r', {
|
||||
@@ -29,17 +30,27 @@ let argv = yargs
|
||||
alias: 'nightly',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
})
|
||||
.option('v', {
|
||||
alias: 'to-version',
|
||||
type: 'string',
|
||||
})
|
||||
.option('l', {
|
||||
alias: 'latest',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
}).argv;
|
||||
|
||||
const nightlyBuild = argv.nightly;
|
||||
const version = argv.toVersion;
|
||||
|
||||
let version, branch;
|
||||
if (nightlyBuild) {
|
||||
const currentCommit = exec('git rev-parse HEAD', {
|
||||
silent: true,
|
||||
}).stdout.trim();
|
||||
version = `0.0.0-${currentCommit.slice(0, 9)}`;
|
||||
} else {
|
||||
if (!version) {
|
||||
echo('You must specify a version using -v');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
let branch;
|
||||
if (!nightlyBuild) {
|
||||
// Check we are in release branch, e.g. 0.33-stable
|
||||
branch = exec('git symbolic-ref --short HEAD', {
|
||||
silent: true,
|
||||
@@ -55,24 +66,24 @@ if (nightlyBuild) {
|
||||
|
||||
// - check that argument version matches branch
|
||||
// e.g. 0.33.1 or 0.33.0-rc4
|
||||
version = argv._[0];
|
||||
if (!version || version.indexOf(versionMajor) !== 0) {
|
||||
if (version.indexOf(versionMajor) !== 0) {
|
||||
echo(
|
||||
`You must pass a tag like 0.${versionMajor}.[X]-rc[Y] to bump a version`,
|
||||
`You must specify a version tag like 0.${versionMajor}.[X]-rc[Y] to bump a version`,
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate version files to detect mismatches between JS and native.
|
||||
let match = version.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
|
||||
if (!match) {
|
||||
echo(
|
||||
`You must pass a correctly formatted version; couldn't parse ${version}`,
|
||||
);
|
||||
let major,
|
||||
minor,
|
||||
patch,
|
||||
prerelease = -1;
|
||||
try {
|
||||
({major, minor, patch, prerelease} = parseVersion(version));
|
||||
} catch (e) {
|
||||
echo(e.message);
|
||||
exit(1);
|
||||
}
|
||||
let [, major, minor, patch, prerelease] = match;
|
||||
|
||||
fs.writeFileSync(
|
||||
'ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java',
|
||||
@@ -149,17 +160,26 @@ if (
|
||||
exec(`node scripts/set-rn-template-version.js ${version}`);
|
||||
|
||||
// Verify that files changed, we just do a git diff and check how many times version is added across files
|
||||
const filesToValidate = [
|
||||
'package.json',
|
||||
'ReactAndroid/gradle.properties',
|
||||
'template/package.json',
|
||||
];
|
||||
let numberOfChangedLinesWithNewVersion = exec(
|
||||
`git diff -U0 | grep '^[+]' | grep -c ${version} `,
|
||||
`git diff -U0 ${filesToValidate.join(
|
||||
' ',
|
||||
)}| grep '^[+]' | grep -c ${version} `,
|
||||
{silent: true},
|
||||
).stdout.trim();
|
||||
|
||||
// Release builds should commit the version bumps, and create tags.
|
||||
// Nightly builds do not need to do that.
|
||||
if (!nightlyBuild) {
|
||||
if (+numberOfChangedLinesWithNewVersion !== 3) {
|
||||
if (+numberOfChangedLinesWithNewVersion !== filesToValidate.length) {
|
||||
echo(
|
||||
'Failed to update all the files. package.json and gradle.properties must have versions in them',
|
||||
`Failed to update all the files: [${filesToValidate.join(
|
||||
', ',
|
||||
)}] must have versions in them`,
|
||||
);
|
||||
echo('Fix the issue, revert and try again');
|
||||
exec('git diff');
|
||||
@@ -186,8 +206,9 @@ if (!nightlyBuild) {
|
||||
let remote = argv.remote;
|
||||
exec(`git push ${remote} v${version}`);
|
||||
|
||||
// Tag latest if doing stable release
|
||||
if (version.indexOf('rc') === -1) {
|
||||
// Tag latest if doing stable release.
|
||||
// This will also tag npm release as `latest`
|
||||
if (prerelease == null && argv.latest) {
|
||||
exec('git tag -d latest');
|
||||
exec(`git push ${remote} :latest`);
|
||||
exec('git tag latest');
|
||||
|
||||
+80
-67
@@ -10,7 +10,7 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* This script publishes a new version of react-native to NPM.
|
||||
* 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
|
||||
@@ -18,21 +18,21 @@
|
||||
*
|
||||
* To cut a branch (and release RC):
|
||||
* - Developer: `git checkout -b 0.XY-stable`
|
||||
* - Developer: `./scripts/bump-oss-version.js v0.XY.0-rc.0`
|
||||
* - 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 v0.XY.0-rc.1`
|
||||
* - 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 v0.XY.0`
|
||||
* - 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)
|
||||
*
|
||||
@@ -49,81 +49,79 @@
|
||||
* 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)
|
||||
*/
|
||||
|
||||
/*eslint-disable no-undef */
|
||||
require('shelljs/global');
|
||||
const {exec, echo, exit, test} = require('shelljs');
|
||||
const yargs = require('yargs');
|
||||
const {parseVersion} = require('./version-utils');
|
||||
|
||||
let argv = yargs.option('n', {
|
||||
alias: 'nightly',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
}).argv;
|
||||
|
||||
const nightlyBuild = argv.nightly;
|
||||
const buildTag = process.env.CIRCLE_TAG;
|
||||
const otp = process.env.NPM_CONFIG_OTP;
|
||||
|
||||
let branchVersion = 0;
|
||||
if (nightlyBuild) {
|
||||
branchVersion = 0;
|
||||
} else {
|
||||
if (!buildTag) {
|
||||
echo('Error: We publish only from git tags');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
let match = buildTag.match(/^v(\d+\.\d+)\.\d+(?:-.+)?$/);
|
||||
if (!match) {
|
||||
echo('Error: We publish only from release version git tags');
|
||||
exit(1);
|
||||
}
|
||||
[, branchVersion] = match;
|
||||
}
|
||||
// 0.33
|
||||
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();
|
||||
// [34c034298dc9cad5a4553964a5a324450fda0385, refs/heads/0.33-stable, refs/tags/latest, refs/tags/v0.33.1, refs/tags/v0.34.1-rc]
|
||||
const tagsWithVersion = exec(`git ls-remote origin | grep ${currentCommit}`, {
|
||||
const currentCommit = exec('git rev-parse HEAD', {
|
||||
silent: true,
|
||||
})
|
||||
.stdout.split(/\s/)
|
||||
// ['refs/tags/v0.33.0', 'refs/tags/v0.33.0-rc', 'refs/tags/v0.33.0-rc1', 'refs/tags/v0.33.0-rc2', 'refs/tags/v0.34.0']
|
||||
.filter(
|
||||
version =>
|
||||
!!version && version.indexOf(`refs/tags/v${branchVersion}`) === 0,
|
||||
)
|
||||
// ['refs/tags/v0.33.0', 'refs/tags/v0.33.0-rc', 'refs/tags/v0.33.0-rc1', 'refs/tags/v0.33.0-rc2']
|
||||
.filter(version => version.indexOf(branchVersion) !== -1)
|
||||
// ['v0.33.0', 'v0.33.0-rc', 'v0.33.0-rc1', 'v0.33.0-rc2']
|
||||
.map(version => version.slice('refs/tags/'.length));
|
||||
}).stdout.trim();
|
||||
const shortCommit = currentCommit.slice(0, 9);
|
||||
|
||||
if (!nightlyBuild && tagsWithVersion.length === 0) {
|
||||
echo(
|
||||
'Error: Cannot find version tag in current commit. To deploy to NPM you must add tag v0.XY.Z[-rc] to your commit',
|
||||
);
|
||||
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;
|
||||
}
|
||||
|
||||
if (nightlyBuild) {
|
||||
releaseVersion = `0.0.0-${currentCommit.slice(0, 9)}`;
|
||||
|
||||
// Bump version number in various files (package.json, gradle.properties etc)
|
||||
// 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 ${releaseVersion}`).code
|
||||
exec(
|
||||
`node scripts/bump-oss-version.js --nightly --to-version ${releaseVersion}`,
|
||||
).code
|
||||
) {
|
||||
echo('Failed to bump version number');
|
||||
exit(1);
|
||||
}
|
||||
} else if (tagsWithVersion[0].indexOf('-rc') === -1) {
|
||||
// if first tag on this commit is non -rc then we are making a stable release
|
||||
// '0.33.0'
|
||||
releaseVersion = tagsWithVersion[0].slice(1);
|
||||
} else {
|
||||
// otherwise pick last -rc tag alphabetically
|
||||
// 0.33.0-rc2
|
||||
releaseVersion = tagsWithVersion[tagsWithVersion.length - 1].slice(1);
|
||||
}
|
||||
|
||||
const buildAndroid = (rebuildOnError) => {
|
||||
@@ -175,12 +173,29 @@ artifacts.forEach(name => {
|
||||
}
|
||||
});
|
||||
|
||||
// if version contains -rc, tag as prerelease
|
||||
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'
|
||||
: releaseVersion.indexOf('-rc') === -1
|
||||
? ''
|
||||
: '--tag next';
|
||||
: prerelease != null
|
||||
? '--tag next'
|
||||
: isLatest
|
||||
? '--tag latest'
|
||||
: `--tag ${releaseBranch}`;
|
||||
|
||||
// use otp from envvars if available
|
||||
const otpFlag = otp ? `--otp ${otp}` : '';
|
||||
@@ -192,5 +207,3 @@ if (exec(`npm publish ${tagFlag} ${otpFlag}`).code) {
|
||||
echo(`Published to npm ${releaseVersion}`);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*eslint-enable no-undef */
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
function parseVersion(versionStr) {
|
||||
const match = versionStr.match(/^v?((\d+)\.(\d+)\.(\d+)(?:-(.+))?)$/);
|
||||
if (!match) {
|
||||
throw new Error(
|
||||
`You must pass a correctly formatted version; couldn't parse ${versionStr}`,
|
||||
);
|
||||
}
|
||||
const [, version, major, minor, patch, prerelease] = match;
|
||||
return {
|
||||
version,
|
||||
major,
|
||||
minor,
|
||||
patch,
|
||||
prerelease,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseVersion,
|
||||
};
|
||||
Reference in New Issue
Block a user