Files
react-native/scripts/publish-npm.js
T
Luna Wei fe0306d637 Support specifying dist-tags for monorepo package bumps (#42146)
Summary:
Currently our CI will auto-tag any `npm publish` as `latest` for the monorepo packages. This is because [we do not specify a tag](https://github.com/facebook/react-native/blob/main/scripts/monorepo/find-and-publish-all-bumped-packages.js#L104), so npm will [default to `latest`](https://docs.npmjs.com/cli/v10/commands/npm-dist-tag#description). We encountered a similar issue for `react-native` awhile ago and fixed that with [always specifying a tag](https://github.com/facebook/react-native/blob/main/scripts/npm-utils.js#L84), with the explicit opt-in for `latest`.

yarn and npm will resolve `*` dependencies using `latest`. This will be a problem for any React Native version that uses `*` deps. We have actively tried to remove these `*` versions but older patches may still contain them.

When we do a monorepo package bump, it may be for 0.71 and for a user who is initializing a 0.72 version project (that still has * deps), they will receive monorepo packages of version `0.71.x`, which is not compatible. (React Native monorepo packages do not faithfully follow semver)

This change allows us to specify what tags to use and suggest tags based on what branch you are on and asks for confirmation

```
> branch 0.73-stable
? Select suggested npm tags. (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ "0.73-stable"
 ◉ "latest"
? Confirm these tags for *ALL* packages being bumped: "0.73-stable","latest" (Y/n)

> branch 0.72-stable
? Select suggested npm tags. (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ "0.72-stable"
 ◯ "latest"
? Confirm these tags for *ALL* packages being bumped: "0.72-stable" (Y/n)

> branch main
? Select suggested npm tags. (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ "nightly"
? Confirm these tags for *ALL* packages being bumped: "nightly" (Y/n)
```

## Changelog:

[INTERNAL] [CHANGED] - Support dist-tags in publishing monorepo packages to avoid default "latest" tag.

Pull Request resolved: https://github.com/facebook/react-native/pull/42146

Test Plan: `yarn test scripts/`

Reviewed By: NickGerleman

Differential Revision: D52551769

Pulled By: lunaleaps

fbshipit-source-id: 52f923464387cffdc6ca22c6f0a45425965a3680
2024-01-08 08:38:53 -08:00

113 lines
3.4 KiB
JavaScript
Executable File

/**
* Copyright (c) Meta Platforms, Inc. and 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';
const getAndUpdatePackages = require('./monorepo/get-and-update-packages');
const {getNpmInfo, publishPackage} = require('./npm-utils');
const {
generateAndroidArtifacts,
publishAndroidArtifactsToMaven,
} = require('./release-utils');
const removeNewArchFlags = require('./releases/remove-new-arch-flags');
const setReactNativeVersion = require('./set-rn-version');
const path = require('path');
const {echo, exit} = require('shelljs');
const yargs = require('yargs');
/**
* 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.
*
* For a dry run (commitly), this script will:
* * Version the commitly of the form `1000.0.0-<commitSha>`
* * Create Android artifacts
* * It will not publish to npm
*
* For a nightly run, this script will:
* * Version the nightly release of the form `0.0.0-<dateIdentifier>-<commitSha>`
* * Create Android artifacts
* * Publish to npm using `nightly` tag
*
* For a release run, this script will:
* * Version the release by the tag version that triggered CI
* * Create Android artifacts
* * Publish to npm
* * using `latest` tag if commit is currently tagged `latest`
* * or otherwise `{major}.{minor}-stable`
*/
if (require.main === module) {
const argv = yargs
.option('t', {
alias: 'builtType',
describe: 'The type of build you want to perform.',
choices: ['dry-run', 'nightly', 'release', 'prealpha'],
default: 'dry-run',
})
.strict().argv;
const buildType = argv.builtType;
publishNpm(buildType);
}
function publishNpm(buildType) {
const {version, tag} = getNpmInfo(buildType);
if (buildType === 'prealpha') {
removeNewArchFlags();
}
// Here we update the react-native package and template package with the right versions
// For releases, CircleCI job `prepare_package_for_release` handles this
if (['dry-run', 'nightly', 'prealpha'].includes(buildType)) {
// Publish monorepo nightlies and prealphas if there are updates, returns the new version for each package
const monorepoVersions =
buildType === 'dry-run' ? null : getAndUpdatePackages(version, buildType);
try {
// Update the react-native and template packages with the react-native version
// and nightly versions of monorepo deps
setReactNativeVersion(version, monorepoVersions, buildType);
} catch (e) {
console.error(`Failed to set version number to ${version}`);
console.error(e);
return exit(1);
}
}
generateAndroidArtifacts(version);
if (buildType === 'dry-run') {
echo('Skipping `npm publish` because --dry-run is set.');
return exit(0);
}
// We first publish on Maven Central all the necessary artifacts.
// NPM publishing is done just after.
publishAndroidArtifactsToMaven(version, buildType);
const packagePath = path.join(__dirname, '..', 'packages', 'react-native');
const result = publishPackage(packagePath, {
tags: [tag],
otp: process.env.NPM_CONFIG_OTP,
});
if (result.code) {
echo('Failed to publish package to npm');
return exit(1);
} else {
echo(`Published to npm ${version}`);
return exit(0);
}
}
module.exports = publishNpm;