mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
Next/experimental release versions include commit date (#21700)
Change format of @next and @experimental release versions from <number>-<sha> to <number>-<sha>-<date> to make them more human readable. This format still preserves the ability for us to easily map a version number to the changes it contains, while also being able to more easily know at a glance how recent a release is.
This commit is contained in:
parent
d7dce572c7
commit
355591add4
|
|
@ -14,9 +14,9 @@
|
|||
//
|
||||
// 18.0.0-alpha-a1c2d3e4
|
||||
//
|
||||
// The @experimental channel doesn't include a version, only a sha, e.g.:
|
||||
// The @experimental channel doesn't include a version, only a date and a sha, e.g.:
|
||||
//
|
||||
// 0.0.0-experimental-a1c2d3e4
|
||||
// 0.0.0-experimental-241c4467e-20200129
|
||||
|
||||
const ReactVersion = '18.0.0';
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ Stable releases should always be created from the "next" channel. This encourage
|
|||
To prepare a stable release, choose a "next" version and run the [`prepare-release-from-npm`](#prepare-release-from-npm) script <sup>1</sup>:
|
||||
|
||||
```sh
|
||||
scripts/release/prepare-release-from-npm.js --version=0.0.0-241c4467e
|
||||
scripts/release/prepare-release-from-npm.js --version=0.0.0-241c4467e-20200129
|
||||
```
|
||||
|
||||
This script will prompt you to select stable version numbers for each of the packages. It will update the package JSON versions (and dependencies) based on the numbers you select.
|
||||
|
|
@ -165,9 +165,9 @@ This script prompts for new (stable) release versions for each public package an
|
|||
"Next" releases have already been tested but it is still a good idea to **manually test and verify a release** before publishing to ensure that e.g. version numbers are correct. Upon completion, this script prints manual testing instructions.
|
||||
|
||||
#### Example usage
|
||||
To promote the "next" release `0.0.0-241c4467e` (aka commit [241c4467e](https://github.com/facebook/react/commit/241c4467e)) to stable:
|
||||
To promote the "next" release `0.0.0-241c4467e-20200129` (aka commit [241c4467e](https://github.com/facebook/react/commit/241c4467e)) to stable:
|
||||
```sh
|
||||
scripts/release/prepare-release-from-npm.js --version=0.0.0-241c4467e
|
||||
scripts/release/prepare-release-from-npm.js --version=0.0.0-241c4467e-20200129
|
||||
```
|
||||
|
||||
## `publish`
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ const paramDefinitions = [
|
|||
{
|
||||
name: 'version',
|
||||
type: String,
|
||||
description: 'Version of published "next" release (e.g. 0.0.0-ddaf2b07c)',
|
||||
description:
|
||||
'Version of published "next" release (e.g. 0.0.0-0e526bcec-20210202)',
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ const run = async ({cwd, packages, version}, versionsMap) => {
|
|||
// (e.g. scheduler@^0.11.0 becomes scheduler@^0.12.0 when we release scheduler 0.12.0).
|
||||
// Otherwise we leave the constraint alone (e.g. react@^16.0.0 doesn't change between releases).
|
||||
// Note that in both cases, we must update the target package JSON,
|
||||
// since "next" releases are all locked to the version (e.g. 0.0.0-ddaf2b07c).
|
||||
// since "next" releases are all locked to the version (e.g. 0.0.0-0e526bcec-20210202).
|
||||
if (
|
||||
sourceDependencyVersion ===
|
||||
sourceDependencyConstraint.replace(/^[\^\~]/, '')
|
||||
|
|
@ -69,7 +69,7 @@ const run = async ({cwd, packages, version}, versionsMap) => {
|
|||
// Update all package JSON versions and their dependencies/peerDependencies.
|
||||
// This must be done in a way that respects semver constraints (e.g. 16.7.0, ^16.7.0, ^16.0.0).
|
||||
// To do this, we use the dependencies defined in the source package JSONs,
|
||||
// because the "next" dependencies have already been flattened to an exact match (e.g. 0.0.0-ddaf2b07c).
|
||||
// because the "next" dependencies have already been flattened to an exact match (e.g. 0.0.0-0e526bcec-20210202).
|
||||
for (let i = 0; i < packages.length; i++) {
|
||||
const packageName = packages[i];
|
||||
const packageJSONPath = join(nodeModulesPath, packageName, 'package.json');
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const {exec, spawn} = require('child-process-promise');
|
|||
const {join} = require('path');
|
||||
const {readFileSync} = require('fs');
|
||||
const theme = require('./theme');
|
||||
const {logPromise, printDiff} = require('./utils');
|
||||
const {getDateStringForCommit, logPromise, printDiff} = require('./utils');
|
||||
|
||||
const cwd = join(__dirname, '..', '..');
|
||||
|
||||
|
|
@ -37,6 +37,8 @@ const run = async () => {
|
|||
);
|
||||
await promise;
|
||||
|
||||
const dateString = await getDateStringForCommit(COMMIT);
|
||||
|
||||
// Upgrade the above build top a known React version.
|
||||
// Note that using the --local flag skips NPM checkout.
|
||||
// This isn't totally necessary but is useful if we want to test an unpublished "next" build.
|
||||
|
|
@ -44,7 +46,7 @@ const run = async () => {
|
|||
'node',
|
||||
[
|
||||
'./scripts/release/prepare-release-from-npm.js',
|
||||
`--version=0.0.0-${COMMIT}`,
|
||||
`--version=0.0.0-${COMMIT}-${dateString}`,
|
||||
'--local',
|
||||
],
|
||||
defaultOptions
|
||||
|
|
|
|||
|
|
@ -49,9 +49,9 @@ const execRead = async (command, options) => {
|
|||
};
|
||||
|
||||
const extractCommitFromVersionNumber = version => {
|
||||
// Support stable version format e.g. "0.0.0-0e526bcec"
|
||||
// and experimental version format e.g. "0.0.0-experimental-0e526bcec"
|
||||
const match = version.match(/0\.0\.0\-([a-z]+\-){0,1}(.+)/);
|
||||
// Support stable version format e.g. "0.0.0-0e526bcec-20210202"
|
||||
// and experimental version format e.g. "0.0.0-experimental-0e526bcec-20210202"
|
||||
const match = version.match(/0\.0\.0\-([a-z]+\-){0,1}([^-]+).+/);
|
||||
if (match === null) {
|
||||
throw Error(`Could not extra commit from version "${version}"`);
|
||||
}
|
||||
|
|
@ -74,9 +74,10 @@ const getBuildInfo = async () => {
|
|||
});
|
||||
const commit = await execRead('git show -s --format=%h', {cwd});
|
||||
const checksum = await getChecksumForCurrentRevision(cwd);
|
||||
const dateString = await getDateStringForCommit(commit);
|
||||
const version = isExperimental
|
||||
? `0.0.0-experimental-${commit}`
|
||||
: `0.0.0-${commit}`;
|
||||
? `0.0.0-experimental-${commit}-${dateString}`
|
||||
: `0.0.0-${commit}-${dateString}`;
|
||||
|
||||
// Only available for Circle CI builds.
|
||||
// https://circleci.com/docs/2.0/env-vars/
|
||||
|
|
@ -88,8 +89,8 @@ const getBuildInfo = async () => {
|
|||
join(cwd, 'packages', 'react', 'package.json')
|
||||
);
|
||||
const reactVersion = isExperimental
|
||||
? `${packageJSON.version}-experimental-${commit}`
|
||||
: `${packageJSON.version}-${commit}`;
|
||||
? `${packageJSON.version}-experimental-${commit}-${dateString}`
|
||||
: `${packageJSON.version}-${commit}-${dateString}`;
|
||||
|
||||
return {branch, buildNumber, checksum, commit, reactVersion, version};
|
||||
};
|
||||
|
|
@ -103,6 +104,19 @@ const getChecksumForCurrentRevision = async cwd => {
|
|||
return hashedPackages.hash.slice(0, 7);
|
||||
};
|
||||
|
||||
const getDateStringForCommit = async commit => {
|
||||
let dateString = await execRead(
|
||||
`git show -s --format=%cd --date=format:%Y%m%d ${commit}`
|
||||
);
|
||||
|
||||
// On CI environment, this string is wrapped with quotes '...'s
|
||||
if (dateString.startsWith("'")) {
|
||||
dateString = dateString.substr(1, 8);
|
||||
}
|
||||
|
||||
return dateString;
|
||||
};
|
||||
|
||||
const getCommitFromCurrentBuild = async () => {
|
||||
const cwd = join(__dirname, '..', '..');
|
||||
|
||||
|
|
@ -194,10 +208,10 @@ const splitCommaParams = array => {
|
|||
// This method is used by both local Node release scripts and Circle CI bash scripts.
|
||||
// It updates version numbers in package JSONs (both the version field and dependencies),
|
||||
// As well as the embedded renderer version in "packages/shared/ReactVersion".
|
||||
// Canaries version numbers use the format of 0.0.0-<sha> to be easily recognized (e.g. 0.0.0-01974a867).
|
||||
// Canaries version numbers use the format of 0.0.0-<sha>-<date> to be easily recognized (e.g. 0.0.0-01974a867-20200129).
|
||||
// A separate "React version" is used for the embedded renderer version to support DevTools,
|
||||
// since it needs to distinguish between different version ranges of React.
|
||||
// It is based on the version of React in the local package.json (e.g. 16.12.0-01974a867).
|
||||
// It is based on the version of React in the local package.json (e.g. 16.12.0-01974a867-20200129).
|
||||
// Both numbers will be replaced if the "next" release is promoted to a stable release.
|
||||
const updateVersionsForNext = async (cwd, reactVersion, version) => {
|
||||
const isExperimental = reactVersion.includes('experimental');
|
||||
|
|
@ -258,6 +272,7 @@ module.exports = {
|
|||
getBuildInfo,
|
||||
getChecksumForCurrentRevision,
|
||||
getCommitFromCurrentBuild,
|
||||
getDateStringForCommit,
|
||||
getPublicPackages,
|
||||
handleError,
|
||||
logPromise,
|
||||
|
|
|
|||
|
|
@ -22,6 +22,16 @@ const sha = (
|
|||
spawnSync('git', ['show', '-s', '--format=%h']).stdout + ''
|
||||
).trim();
|
||||
|
||||
let dateString = (
|
||||
spawnSync('git', ['show', '-s', '--format=%cd', '--date=format:%Y%m%d', sha])
|
||||
.stdout + ''
|
||||
).trim();
|
||||
|
||||
// On CI environment, this string is wrapped with quotes '...'s
|
||||
if (dateString.startsWith("'")) {
|
||||
dateString = dateString.substr(1, 8);
|
||||
}
|
||||
|
||||
if (process.env.CIRCLE_NODE_TOTAL) {
|
||||
// In CI, we use multiple concurrent processes. Allocate half the processes to
|
||||
// build the stable channel, and the other half for experimental. Override
|
||||
|
|
@ -32,14 +42,16 @@ if (process.env.CIRCLE_NODE_TOTAL) {
|
|||
if (index < halfTotal) {
|
||||
const nodeTotal = halfTotal;
|
||||
const nodeIndex = index;
|
||||
updateTheReactVersionThatDevToolsReads(ReactVersion + '-' + sha);
|
||||
updateTheReactVersionThatDevToolsReads(
|
||||
ReactVersion + '-' + sha + '-' + dateString
|
||||
);
|
||||
buildForChannel('stable', nodeTotal, nodeIndex);
|
||||
processStable('./build');
|
||||
} else {
|
||||
const nodeTotal = total - halfTotal;
|
||||
const nodeIndex = index - halfTotal;
|
||||
updateTheReactVersionThatDevToolsReads(
|
||||
ReactVersion + '-experimental-' + sha
|
||||
ReactVersion + '-experimental-' + sha + '-' + dateString
|
||||
);
|
||||
buildForChannel('experimental', nodeTotal, nodeIndex);
|
||||
processExperimental('./build');
|
||||
|
|
@ -51,12 +63,16 @@ if (process.env.CIRCLE_NODE_TOTAL) {
|
|||
} else {
|
||||
// Running locally, no concurrency. Move each channel's build artifacts into
|
||||
// a temporary directory so that they don't conflict.
|
||||
updateTheReactVersionThatDevToolsReads(ReactVersion + '-' + sha);
|
||||
updateTheReactVersionThatDevToolsReads(
|
||||
ReactVersion + '-' + sha + '-' + dateString
|
||||
);
|
||||
buildForChannel('stable', '', '');
|
||||
const stableDir = tmp.dirSync().name;
|
||||
crossDeviceRenameSync('./build', stableDir);
|
||||
processStable(stableDir);
|
||||
updateTheReactVersionThatDevToolsReads(ReactVersion + '-experimental-' + sha);
|
||||
updateTheReactVersionThatDevToolsReads(
|
||||
ReactVersion + '-experimental-' + sha + '-' + dateString
|
||||
);
|
||||
buildForChannel('experimental', '', '');
|
||||
const experimentalDir = tmp.dirSync().name;
|
||||
crossDeviceRenameSync('./build', experimentalDir);
|
||||
|
|
@ -88,13 +104,13 @@ function buildForChannel(channel, nodeTotal, nodeIndex) {
|
|||
|
||||
function processStable(buildDir) {
|
||||
if (fs.existsSync(buildDir + '/node_modules')) {
|
||||
const defaultVersionIfNotFound = '0.0.0' + '-' + sha;
|
||||
const defaultVersionIfNotFound = '0.0.0' + '-' + sha + '-' + dateString;
|
||||
const versionsMap = new Map();
|
||||
for (const moduleName in stablePackages) {
|
||||
const version = stablePackages[moduleName];
|
||||
versionsMap.set(
|
||||
moduleName,
|
||||
version + '-' + nextChannelLabel + '-' + sha,
|
||||
version + '-' + nextChannelLabel + '-' + sha + '-' + dateString,
|
||||
defaultVersionIfNotFound
|
||||
);
|
||||
}
|
||||
|
|
@ -143,7 +159,8 @@ function processStable(buildDir) {
|
|||
|
||||
function processExperimental(buildDir, version) {
|
||||
if (fs.existsSync(buildDir + '/node_modules')) {
|
||||
const defaultVersionIfNotFound = '0.0.0' + '-' + 'experimental' + '-' + sha;
|
||||
const defaultVersionIfNotFound =
|
||||
'0.0.0' + '-' + 'experimental' + '-' + sha + '-' + dateString;
|
||||
const versionsMap = new Map();
|
||||
for (const moduleName in stablePackages) {
|
||||
versionsMap.set(moduleName, defaultVersionIfNotFound);
|
||||
|
|
@ -195,7 +212,7 @@ function crossDeviceRenameSync(source, destination) {
|
|||
|
||||
/*
|
||||
* Grabs the built packages in ${tmp_build_dir}/node_modules and updates the
|
||||
* `version` key in their package.json to 0.0.0-${commitHash} for the commit
|
||||
* `version` key in their package.json to 0.0.0-${date}-${commitHash} for the commit
|
||||
* you're building. Also updates the dependencies and peerDependencies
|
||||
* to match this version for all of the 'React' packages
|
||||
* (packages available in this repo).
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user