Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions scripts/release/build-commands/add-git-tag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env node

'use strict';

const chalk = require('chalk');
const {execUnlessDry, logPromise} = require('../utils');

const run = async ({cwd, dry, version}) => {
await execUnlessDry(`git tag -a ${version} -m "Tagging ${version} release"`, {
cwd,
dry,
});
};

module.exports = async ({cwd, dry, version}) => {
return logPromise(
run({cwd, dry, version}),
`Creating git tag ${chalk.yellow.bold(version)}`
);
};
23 changes: 17 additions & 6 deletions scripts/release/build-commands/print-post-build-summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,27 @@
'use strict';

const chalk = require('chalk');
const {join, relative} = require('path');
const {getUnexecutedCommands} = require('../utils');

const CHANGELOG_PATH =
'https://github.com/facebook/react/edit/master/CHANGELOG.md';

module.exports = params => {
module.exports = ({cwd, dry, path, version}) => {
const publishPath = relative(
process.env.PWD,
join(__dirname, '../publish.js')
);
const command =
`./publish.js -v ${params.version}` +
(params.path ? ` -p ${params.path}` : '') +
(params.dry ? ' --dry' : '');
`${publishPath} -v ${version}` +
(path ? ` -p ${path}` : '') +
(dry ? ' --dry' : '');

const packagingFixturesPath = join(cwd, 'fixtures/packaging');
const standaloneFixturePath = join(
cwd,
'fixtures/packaging/babel-standalone/dev.html'
);

console.log(
chalk`
Expand All @@ -29,9 +40,9 @@ module.exports = params => {

{bold.underline Step 2: Smoke test the packages}

1. Open {yellow.bold fixtures/packaging/babel-standalone/dev.html} in the browser.
1. Open {yellow.bold ${standaloneFixturePath}} in the browser.
2. It should say {italic "Hello world!"}
3. Next go to {yellow.bold fixtures/packaging} and run {bold node build-all.js}
3. Next go to {yellow.bold ${packagingFixturesPath}} and run {bold node build-all.js}
4. Install the "serve" module ({bold npm install -g serve})
5. Go to the repo root and {bold serve -s .}
6. Open {blue.bold http://localhost:5000/fixtures/packaging}
Expand Down
15 changes: 11 additions & 4 deletions scripts/release/build-commands/update-package-versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,18 @@ const update = async ({cwd, dry, version}) => {
const path = join(cwd, 'packages', project, 'package.json');
const json = await readJson(path);

// Unstable packages (eg version < 1.0) are treated differently.
// In order to simplify DX for the release engineer,
// These packages are auto-incremented by a minor version number.
// Unstable packages (eg version < 1.0) are treated specially:
// Rather than use the release version (eg 16.1.0)-
// We just auto-increment the minor version (eg 0.1.0 -> 0.2.0).
// If we're doing a prerelease, we also append the suffix (eg 0.2.0-beta).
if (semver.lt(json.version, '1.0.0')) {
json.version = `0.${semver.minor(json.version) + 1}.0`;
const prerelease = semver.prerelease(version);
let suffix = '';
if (prerelease) {
suffix = `-${prerelease.join('.')}`;
}

json.version = `0.${semver.minor(json.version) + 1}.0${suffix}`;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand the difference between when to use version and when to use json.version.

If I do two pre-releases in a row, does this increment minor once or twice? If it only increments once then sounds fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

version is coming from the user's CLI param (eg 16.0.1-beta)

The "version" in package.json will typically be the same, except for < 1.0 releases like the reconciler, when we'll increment the major (eg 0.1.0 -> 0.2.0) and now also append the prerelease suffix (eg 16.1.0-beta -> 0.2.0-beta).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll update the inline comment to be clearer.

} else {
json.version = version;
}
Expand Down
2 changes: 2 additions & 0 deletions scripts/release/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const run = async () => {
const chalk = require('chalk');
const logUpdate = require('log-update');

const addGitTag = require('./build-commands/add-git-tag');
const buildArtifacts = require('./build-commands/build-artifacts');
const checkCircleCiStatus = require('./build-commands/check-circle-ci-status');
const checkEnvironmentVariables = require('./build-commands/check-environment-variables');
Expand Down Expand Up @@ -39,6 +40,7 @@ const run = async () => {
await runAutomatedTests(params);
await updatePackageVersions(params);
await buildArtifacts(params);
await addGitTag(params);
await printPostBuildSummary(params);
} catch (error) {
logUpdate.clear();
Expand Down
30 changes: 26 additions & 4 deletions scripts/release/publish-commands/publish-to-npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,54 @@
'use strict';

const chalk = require('chalk');
const {readJson} = require('fs-extra');
const {join} = require('path');
const semver = require('semver');
const {execRead, execUnlessDry, logPromise} = require('../utils');
const {projects} = require('../config');

const push = async ({cwd, dry, version}) => {
const errors = [];
const tag = semver.prerelease(version) ? 'next' : 'latest';
const isPrerelease = semver.prerelease(version);
const tag = isPrerelease ? 'next' : 'latest';

const publishProject = async project => {
try {
const path = join(cwd, 'build', 'packages', project);
await execUnlessDry(`npm publish --tag ${tag}`, {cwd: path, dry});

const packagePath = join(
cwd,
'build',
'packages',
project,
'package.json'
);
const packageJSON = await readJson(packagePath);
const packageVersion = packageJSON.version;

if (!dry) {
const status = JSON.parse(
await execRead(`npm info ${project} dist-tags --json`)
);
const remoteVersion = status[tag];

if (remoteVersion !== version) {
// Compare remote version to package.json version,
// To better handle the case of pre-release versions.
if (remoteVersion !== packageVersion) {
throw Error(
chalk`Publised version {yellow.bold ${version}} for ` +
chalk`Publised version {yellow.bold ${packageVersion}} for ` +
`{bold ${project}} but NPM shows {yellow.bold ${remoteVersion}}`
);
}

// If we've just published a stable release,
// Update the @next tag to also point to it (so @next doens't lag behind).
if (!isPrerelease) {
await execUnlessDry(
`npm dist-tag add ${project}@${packageVersion} next`
);
}
}
} catch (error) {
errors.push(error.message);
Expand All @@ -48,5 +70,5 @@ const push = async ({cwd, dry, version}) => {
};

module.exports = async params => {
return logPromise(push(params), 'Pushing to git remote');
return logPromise(push(params), 'Publishing packages to NPM');
};