mirror of
https://github.com/facebook/react-native.git
synced 2024-11-21 22:10:14 +00:00
Remove the trigger-react-native-release to use the GHA workflow_dispatch UI (#44898)
Summary: This change removes the need for the trigger-react-native-release.js script. Thanks to the migration to Github Actions, we can now leverage the GHA workflow UI to trigger a Prepare Release job that creates a github tag that will spin a new release. The pro of this approach are: - less code to maintain: instead of a complex trigger release scripts, we only have to maintain two very straightforward scripts for the CI - easier to trigger a release: instead of running a script, we can now just use the GH UI The `trigger-react-native-release` script was doing the following steps: - check that we are in the release branch ==> Already implemented in the GHA workflow - Gets the branch name (not needed) ==> the job will automatically run on the stable branch - Check for unsent changes (not needed) ==> we are not in a local environment - get the gh token (not needed) ==> You need to be logged in GH and have write access to the repo - get the version ==> provided as a parameter - fails if the tag is already there ==> Functionality added in the workflow - Parse and validate the version ==> Functionality added to the action prepare-release action + the JS Script - Compute the npmTag ==> Functionality added to the action prepare-release action + the JS Script - trigger the release workflow ==> The GH UI does that for us ## Changelog: [Internal] - Remove the trigger-react-native-release.js Pull Request resolved: https://github.com/facebook/react-native/pull/44898 Test Plan: Testing in Production! Reviewed By: cortinico, huntie Differential Revision: D58461470 Pulled By: cipolleschi fbshipit-source-id: 32bb0ee91370c9483a29e2ca2e18e24557d5fd53
This commit is contained in:
parent
726a4a1e5e
commit
ece68f0efd
@ -1,24 +1,18 @@
|
||||
name: prepare_release
|
||||
description: Prepare React Native release
|
||||
name: create_release
|
||||
description: Creates a new React Native release
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Yarn install
|
||||
shell: bash
|
||||
run: yarn install --non-interactive
|
||||
- name: Versioning workspace packages
|
||||
shell: bash
|
||||
run: |
|
||||
node scripts/releases/set-version "${{ inputs.version }}" --skip-react-native-version
|
||||
- name: Versioning react-native package
|
||||
shell: bash
|
||||
run: |
|
||||
node scripts/releases/set-rn-version.js -v "<< parameters.version >>" --build-type "release"
|
||||
- name: Creating release commit
|
||||
shell: bash
|
||||
run: |
|
||||
git commit -a -m "Release ${{ inputs.version }}" -m "#publish-packages-to-npm&${{ inputs.tag }}"
|
||||
git tag -a "v${{ inputs.version }}" -m "v${{ inputs.version }}"
|
||||
node scripts/releases/create-release-commit.js \
|
||||
--reactNativeVersion "${{ inputs.version }}" \
|
||||
--tagAsLatestRelease "${{ inputs.is_latest_on_npm }}" \
|
||||
--dryRun "${{ inputs.dry_run }}"
|
||||
GIT_PAGER=cat git show HEAD
|
||||
- name: Update "latest" tag if needed
|
||||
shell: bash
|
@ -1,16 +1,17 @@
|
||||
name: Prepare Release
|
||||
name: Create release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'The version of React Native we want to release'
|
||||
description: 'The version of React Native we want to release. For example 0.75.0-rc.0'
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
description: 'The tag name that will be associated with the published npm packages. A tag of "latest" will also be written as a Git tag.'
|
||||
is_latest_on_npm:
|
||||
description: 'Whether we want to tag this release as latest on NPM'
|
||||
required: true
|
||||
type: string
|
||||
type: boolean
|
||||
default: false
|
||||
dry_run:
|
||||
description: 'Whether the job should be executed in dry-run mode or not'
|
||||
type: boolean
|
||||
@ -33,6 +34,15 @@ jobs:
|
||||
fi
|
||||
- name: Print output
|
||||
run: echo "ON_STABLE_BRANCH ${{steps.check_stable_branch.outputs.ON_STABLE_BRANCH}}"
|
||||
- name: Check if tag already exists
|
||||
id: check_if_tag_exists
|
||||
run: |
|
||||
TAG="v${{ inputs.version }}"
|
||||
TAG_EXISTS=$(git tag -l "$TAG")
|
||||
if [[ -n "$TAG_EXISTS" ]]; then
|
||||
echo "Version tag already exists!"
|
||||
echo "TAG_EXISTS=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Execute Prepare Release
|
||||
if: ${{ steps.check_stable_branch.outputs.ON_STABLE_BRANCH }}
|
||||
uses: ./.github/actions/prepare_release
|
||||
if: ${{ steps.check_stable_branch.outputs.ON_STABLE_BRANCH && !steps.check_if_tag_exists.outputs.TAG_EXISTS }}
|
||||
uses: ./.github/actions/create-release
|
@ -1,11 +0,0 @@
|
||||
# scripts/releases-local
|
||||
|
||||
Local-only release scripts.
|
||||
|
||||
## Commands
|
||||
|
||||
For information on command arguments, run `node <command> --help`.
|
||||
|
||||
### `trigger-react-native-release.js`
|
||||
|
||||
Trigger the external release publishing workflow on CircleCI.
|
@ -1,223 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const checkForGitChanges = require('../monorepo/check-for-git-changes');
|
||||
const {failIfTagExists} = require('../releases/utils/release-utils');
|
||||
const {
|
||||
isReleaseBranch,
|
||||
parseVersion,
|
||||
} = require('../releases/utils/version-utils');
|
||||
const {exitIfNotOnGit, getBranchName} = require('../scm-utils');
|
||||
const {getPackages} = require('../utils/monorepo');
|
||||
const chalk = require('chalk');
|
||||
const inquirer = require('inquirer');
|
||||
const request = require('request');
|
||||
const {echo, exit} = require('shelljs');
|
||||
const yargs = require('yargs');
|
||||
|
||||
/**
|
||||
* This script walks a releaser through bumping the version for a release
|
||||
* It will commit the appropriate tags to trigger the CircleCI jobs.
|
||||
*/
|
||||
|
||||
let argv = yargs
|
||||
.option('r', {
|
||||
alias: 'remote',
|
||||
default: 'origin',
|
||||
})
|
||||
.option('t', {
|
||||
alias: 'token',
|
||||
describe:
|
||||
'Your GitHub personal API token. See https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens.',
|
||||
required: true,
|
||||
})
|
||||
.option('v', {
|
||||
alias: 'to-version',
|
||||
describe: 'Version you aim to release, ex. 0.67.0-rc.1, 0.66.3',
|
||||
required: true,
|
||||
})
|
||||
.option('dry-run', {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
})
|
||||
.check(() => {
|
||||
const branch = exitIfNotOnGit(
|
||||
() => getBranchName(),
|
||||
"Not in git. You can't invoke trigger-react-native-release from outside a git repo.",
|
||||
);
|
||||
exitIfNotOnReleaseBranch(branch);
|
||||
return true;
|
||||
}).argv;
|
||||
|
||||
function exitIfNotOnReleaseBranch(branch /*: string */) {
|
||||
if (!isReleaseBranch(branch)) {
|
||||
console.log(
|
||||
'This script must be run in a react-native git repository checkout and on a release branch',
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next version that all workspace packages will be set to.
|
||||
*
|
||||
* This approach is specific to the 0.74 release. For 0.75, the `--to-version`
|
||||
* value will be used instead, setting all packages to a single version.
|
||||
*/
|
||||
async function getNextMonorepoPackagesVersion() /*: Promise<string | null> */ {
|
||||
// Based on last publish before this strategy
|
||||
const _0_74_MIN_PATCH = 75;
|
||||
|
||||
const packages = await getPackages({
|
||||
includeReactNative: false,
|
||||
});
|
||||
|
||||
let patchVersion = _0_74_MIN_PATCH;
|
||||
|
||||
for (const pkg of Object.values(packages)) {
|
||||
const {version} = pkg.packageJson;
|
||||
|
||||
if (!version.startsWith('0.74.') || version.endsWith('-main')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {patch} = parseVersion(version, 'release');
|
||||
patchVersion = Math.max(patchVersion, parseInt(patch, 10) + 1);
|
||||
}
|
||||
|
||||
return '0.74.' + patchVersion;
|
||||
}
|
||||
|
||||
function triggerReleaseWorkflow(options /*: $FlowFixMe */) {
|
||||
return new Promise((resolve, reject) => {
|
||||
request(options, function (error, response, body) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(body);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const branch = exitIfNotOnGit(
|
||||
() => getBranchName(),
|
||||
"Not in git. You can't invoke trigger-react-native-release from outside a git repo.",
|
||||
);
|
||||
|
||||
// check for uncommitted changes
|
||||
if (checkForGitChanges()) {
|
||||
echo(
|
||||
chalk.red(
|
||||
'Found uncommitted changes. Please commit or stash them before running this script',
|
||||
),
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// $FlowFixMe[prop-missing]
|
||||
const token = argv.token;
|
||||
// $FlowFixMe[prop-missing]
|
||||
const releaseVersion = argv.toVersion;
|
||||
failIfTagExists(releaseVersion, 'release');
|
||||
|
||||
const {pushed} = await inquirer.prompt({
|
||||
type: 'confirm',
|
||||
name: 'pushed',
|
||||
message: `This script will trigger a release with whatever changes are on the remote branch: ${branch}. \nMake sure you have pushed any updates remotely.`,
|
||||
});
|
||||
|
||||
if (!pushed) {
|
||||
// $FlowFixMe[prop-missing]
|
||||
console.log(`Please run 'git push ${argv.remote} ${branch}'`);
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
let latest = false;
|
||||
const {version, prerelease} = parseVersion(releaseVersion, 'release');
|
||||
if (!prerelease) {
|
||||
const {setLatest} = await inquirer.prompt({
|
||||
type: 'confirm',
|
||||
name: 'setLatest',
|
||||
message: `Do you want to set ${version} as "latest" release on npm?`,
|
||||
});
|
||||
latest = setLatest;
|
||||
}
|
||||
|
||||
const npmTag = latest ? 'latest' : !prerelease ? branch : 'next';
|
||||
const {confirmRelease} = await inquirer.prompt({
|
||||
type: 'confirm',
|
||||
name: 'confirmRelease',
|
||||
message: `Releasing version "${version}" with npm tag "${npmTag}". Is this correct?`,
|
||||
});
|
||||
|
||||
if (!confirmRelease) {
|
||||
console.log('Aborting.');
|
||||
return;
|
||||
}
|
||||
|
||||
let nextMonorepoPackagesVersion = await getNextMonorepoPackagesVersion();
|
||||
|
||||
if (nextMonorepoPackagesVersion == null) {
|
||||
// TODO(T182538198): Once this warning is hit, we can remove the
|
||||
// `release_monorepo_packages_version` logic from here and the CI jobs,
|
||||
// see other TODOs.
|
||||
console.warn(
|
||||
'Warning: No longer on the 0.74-stable branch, meaning we will ' +
|
||||
'write all package versions identically. Please double-check the ' +
|
||||
'generated diff to see if this is correct.',
|
||||
);
|
||||
nextMonorepoPackagesVersion = version;
|
||||
}
|
||||
|
||||
const parameters = {
|
||||
version: version,
|
||||
tag: npmTag,
|
||||
// $FlowFixMe[prop-missing]
|
||||
dry_run: argv.dryRun,
|
||||
};
|
||||
|
||||
const options = {
|
||||
method: 'POST',
|
||||
url: 'https://api.github.com/repos/facebook/react-native/actions/workflows/prepare-release/dispatches',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
Accept: 'application/vnd.github+json',
|
||||
'X-GitHub-Api-Version': '2022-11-28',
|
||||
},
|
||||
body: {
|
||||
ref: branch,
|
||||
inputs: parameters,
|
||||
},
|
||||
json: true,
|
||||
};
|
||||
|
||||
// See response: https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28#create-a-workflow-dispatch-event
|
||||
await triggerReleaseWorkflow(options);
|
||||
console.log(
|
||||
// $FlowFixMe[incompatible-use]
|
||||
'Monitor your release workflow: https://github.com/facebook/react-native/actions/workflows/prepare-release.yml',
|
||||
);
|
||||
|
||||
// TODO
|
||||
// - Output the release changelog to paste into Github releases
|
||||
// - Link to release discussions to update
|
||||
// - Verify RN-diff publish is through
|
||||
}
|
||||
|
||||
// $FlowFixMe[unused-promise]
|
||||
main().then(() => {
|
||||
exit(0);
|
||||
});
|
@ -21,3 +21,7 @@ Updates relevant files in the `react-native` package and template to materialize
|
||||
### `update-template-package`
|
||||
|
||||
Updates workspace dependencies in the template app`package.json`
|
||||
|
||||
### `create-release-commit`
|
||||
|
||||
Creates a release commit to trigger a new release
|
||||
|
72
scripts/releases/create-release-commit.js
Normal file
72
scripts/releases/create-release-commit.js
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
const setVersion = require('../releases/set-version');
|
||||
const {getBranchName} = require('../scm-utils');
|
||||
const {parseVersion} = require('./utils/version-utils');
|
||||
const {execSync} = require('child_process');
|
||||
const yargs = require('yargs');
|
||||
|
||||
async function main() {
|
||||
const argv = await yargs
|
||||
.option('reactNativeVersion', {
|
||||
describe: 'The new React Native version.',
|
||||
type: 'string',
|
||||
required: true,
|
||||
})
|
||||
.option('tagAsLatestRelease', {
|
||||
describe:
|
||||
'Whether the version should be published as the latest version on npm.',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
})
|
||||
.option('dryRun', {
|
||||
description: 'Whether we should push the commit to github or not',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
}).argv;
|
||||
|
||||
const buildType = 'release';
|
||||
const version = argv.reactNativeVersion;
|
||||
const latest = argv.tagAsLatestRelease;
|
||||
const dryRun = argv.dryRun;
|
||||
const branch = getBranchName();
|
||||
console.info(`Running on branch: ${branch}`);
|
||||
|
||||
console.info('Validating version', version);
|
||||
const {prerelease} = parseVersion(version, buildType);
|
||||
|
||||
const npmTag = latest ? 'latest' : prerelease ? 'next' : branch;
|
||||
console.info('NPM tag:', npmTag);
|
||||
|
||||
console.info('Setting version for monorepo packages and react-native');
|
||||
await setVersion(version, false); // version, skip-react-native
|
||||
|
||||
if (dryRun) {
|
||||
console.info('Running in dry-run mode, skipping git commit');
|
||||
console.info(
|
||||
`git commit -a -m "Release ${version}" -m "#publish-packages-to-npm&${npmTag}"`,
|
||||
);
|
||||
console.info(`git tag -a v${version} -m "v${version}"`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.info('Committing to git');
|
||||
execSync(
|
||||
`git commit -a -m "Release ${version}" -m "#publish-packages-to-npm&${npmTag}"`,
|
||||
);
|
||||
execSync(`git tag -a v${version} -m "v${version}"`);
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
// eslint-disable-next-line no-void
|
||||
void main();
|
||||
}
|
Loading…
Reference in New Issue
Block a user