Skip to content

Commit 3b170a0

Browse files
committed
Add prepare_release_new workflow, configure via flag (facebook#43518)
Summary: Pull Request resolved: facebook#43518 This is a minimum approach to achieve a **single-command publish flow** for React Native, unifying the previous `yarn bump-all-updated-packages` and `yarn trigger-react-native-release` workflow entry points. This diff aims to change as little as possible to achieve the above — introducing a new job that merges operations to create the versioning commit. The triggered publish jobs are unchanged. In future, we may follow this change with further simplifications down the workflow tree. **Key changes** - Adds a new CircleCI workflow, `prepare_release_new`, which versions **all packages** and writes a single release commit. - This replaces `yarn bump-all-updated-packages`, now implemented with the newer `set-version` script. - Wires this up as an experiment within `trigger-react-native-release.js`, conditionally running the new workflow when `--use-new-workflow` is passed. **Not changed** - The single release commit written will continue to trigger both of the existing CI workflows on push (`publish_release` and `publish_bumped_packages`), which are unchanged. - The commit summary now includes the `#publish-packages-to-npm` marker, in order to trigger `publish_bumped_packages`. - Usage: Release Crew members will continue to use the existing local script entry point (as [documented in the releases repo](https://github.com/reactwg/react-native-releases/blob/main/docs/guide-release-process.md#step-7-publish-react-native)), with the opt in flag. ``` yarn trigger-react-native-release --use-new-workflow [...args] ``` After we're happy with the E2E behaviour of this workflow in the next 0.74 RC, I will follow up by dropping the `--use-new-workflow` flag and removing the old scripts (T182533699). Changelog: [Internal] Reviewed By: cortinico Differential Revision: D54956345 fbshipit-source-id: 35fd7af8f3e60a39507b5d978ccd97472bf03ddb
1 parent 680bfaf commit 3b170a0

File tree

5 files changed

+197
-13
lines changed

5 files changed

+197
-13
lines changed

.circleci/config.yml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ parameters:
1212
default: false
1313
type: boolean
1414

15+
# Experimental unified release workflow
16+
run_new_release_workflow:
17+
default: false
18+
type: boolean
19+
20+
run_nightly_workflow:
21+
default: false
22+
type: boolean
23+
1524
release_latest:
1625
default: false
1726
type: boolean
@@ -20,7 +29,15 @@ parameters:
2029
default: ""
2130
type: string
2231

23-
run_nightly_workflow:
32+
release_monorepo_packages_version:
33+
default: ""
34+
type: string
35+
36+
release_tag:
37+
default: ""
38+
type: string
39+
40+
release_dry_run:
2441
default: false
2542
type: boolean
2643

.circleci/configurations/jobs.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,71 @@ jobs:
11071107
11081108
node ./scripts/releases-ci/prepare-package-for-release.js -v "$VERSION" -l << parameters.latest >> --dry-run << parameters.dryrun >>
11091109
1110+
# Experimental unified release workflow
1111+
# Replaces `prepare_package_for_release`
1112+
#
1113+
# Writes a new commit and tag(s), which will trigger the `publish_release`
1114+
# and `publish_bumped_packages` workflows.
1115+
prepare_release_new:
1116+
parameters:
1117+
version:
1118+
type: string
1119+
# TODO(T182538198): Required for 0.74.x, where workspace packages are out
1120+
# of sync with react-native. This will be removed for 0.75+.
1121+
monorepo_packages_version:
1122+
type: string
1123+
tag:
1124+
type: string
1125+
dry_run:
1126+
type: boolean
1127+
default: false
1128+
executor: reactnativeios
1129+
steps:
1130+
- checkout_code_with_cache
1131+
- run_yarn
1132+
- add_ssh_keys:
1133+
fingerprints:
1134+
- "1f:c7:61:c4:e2:ff:77:e3:cc:ca:a7:34:c2:79:e3:3c"
1135+
- brew_install:
1136+
package: cmake
1137+
- run:
1138+
name: Versioning workspace packages
1139+
command: |
1140+
node scripts/releases/set-version "<< parameters.monorepo_packages_version >>" --skip-react-native-version
1141+
- run:
1142+
name: Versioning react-native package
1143+
command: |
1144+
node scripts/releases/set-rn-version.js -v "<< parameters.version >>" --build-type "release"
1145+
- run:
1146+
name: Updating RNTester Podfile.lock
1147+
command: |
1148+
cd packages/rn-tester/
1149+
bundle install
1150+
bundle exec pod install
1151+
- run:
1152+
name: Creating release commit
1153+
command: |
1154+
git commit -a -m "Release << parameters.version >>\n\n#publish-packages-to-npm&<< parameters.tag >>"
1155+
git tag -a "v<< parameters.version >>" -m "v<< parameters.version >>"
1156+
git show HEAD
1157+
- when:
1158+
condition:
1159+
equal: ["latest", << parameters.tag >>]
1160+
steps:
1161+
- run:
1162+
name: Updating "latest" tag
1163+
command: |
1164+
git tag -d "latest"
1165+
git push origin :latest
1166+
git tag -a "latest" -m "latest"
1167+
- unless:
1168+
condition: << parameters.dry_run >>
1169+
steps:
1170+
run:
1171+
name: Pushing release commit
1172+
command: |
1173+
git push origin $CIRCLE_BRANCH --follow-tags
1174+
11101175
build_npm_package:
11111176
parameters:
11121177
release_type:

.circleci/configurations/top_level.yml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,30 @@ parameters:
129129
default: false
130130
type: boolean
131131

132+
run_new_release_workflow:
133+
default: false
134+
type: boolean
135+
136+
run_nightly_workflow:
137+
default: false
138+
type: boolean
139+
132140
release_latest:
133141
default: false
134142
type: boolean
135143

136144
release_version:
137-
default: "9999"
145+
default: ""
138146
type: string
139147

140-
run_nightly_workflow:
148+
release_monorepo_packages_version:
149+
default: ""
150+
type: string
151+
152+
release_tag:
153+
default: ""
154+
type: string
155+
156+
release_dry_run:
141157
default: false
142158
type: boolean

.circleci/configurations/workflows.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# when:
77
# and:
88
# - equal: [ false, << pipeline.parameters.run_release_workflow >> ]
9+
# - equal: [ false, << pipeline.parameters.run_new_release_workflow >> ]
910
# - equal: [ false, << pipeline.parameters.run_nightly_workflow >> ]
1011
#
1112
# It's setup this way so we can trigger a release via a POST
@@ -25,6 +26,17 @@ workflows:
2526
version: << pipeline.parameters.release_version >>
2627
latest : << pipeline.parameters.release_latest >>
2728

29+
# Experimental unified release workflow
30+
create_release_new:
31+
when: << pipeline.parameters.run_new_release_workflow >>
32+
jobs:
33+
- prepare_release_new:
34+
name: prepare_release_new
35+
version: << pipeline.parameters.release_version >>
36+
monorepo_packages_version: << pipeline.parameters.release_monorepo_packages_version >>
37+
tag: << pipeline.parameters.release_tag >>
38+
dry_run: << pipeline.parameters.release_dry_run >>
39+
2840
# This job will run only when a tag is published due to all the jobs being filtered.
2941
publish_release:
3042
jobs:
@@ -79,6 +91,7 @@ workflows:
7991
when:
8092
and:
8193
- equal: [ false, << pipeline.parameters.run_release_workflow >> ]
94+
- equal: [ false, << pipeline.parameters.run_new_release_workflow >> ]
8295
- equal: [ false, << pipeline.parameters.run_nightly_workflow >> ]
8396
jobs:
8497
# Run lints on every commit
@@ -127,6 +140,7 @@ workflows:
127140
when:
128141
and:
129142
- equal: [ false, << pipeline.parameters.run_release_workflow >> ]
143+
- equal: [ false, << pipeline.parameters.run_new_release_workflow >> ]
130144
- equal: [ false, << pipeline.parameters.run_nightly_workflow >> ]
131145
jobs:
132146
- find_and_publish_bumped_packages:

scripts/releases-local/trigger-react-native-release.js

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ let argv = yargs
4848
describe: 'Version you aim to release, ex. 0.67.0-rc.1, 0.66.3',
4949
required: true,
5050
})
51+
.option('dry-run', {
52+
type: 'boolean',
53+
default: false,
54+
})
55+
// TODO(T182533699): Remove arg once new workflow is default
56+
.option('use-new-workflow', {
57+
describe: 'When set, triggers the experimental unified release workflow.',
58+
type: 'boolean',
59+
default: false,
60+
})
5161
.check(() => {
5262
const branch = exitIfNotOnGit(
5363
() => getBranchName(),
@@ -77,7 +87,6 @@ const buildExecutor =
7787
if (packageManifest.private) {
7888
return;
7989
}
80-
8190
if (
8291
detectPackageUnreleasedChanges(
8392
packageRelativePathFromRoot,
@@ -116,6 +125,36 @@ async function exitIfUnreleasedPackages() {
116125
}
117126
}
118127

128+
/**
129+
* Get the next version that all workspace packages will be set to.
130+
*
131+
* This approach is specific to the 0.74 release. For 0.75, the `--to-version`
132+
* value will be used instead, setting all packages to a single version.
133+
*/
134+
async function getNextMonorepoPackagesVersion() /*: Promise<string | null> */ {
135+
// Based on @react-native/[email protected]
136+
const _0_74_MIN_PATCH = 6;
137+
138+
const packages = await getPackages({
139+
includeReactNative: false,
140+
});
141+
142+
let patchVersion = _0_74_MIN_PATCH;
143+
144+
for (const pkg of Object.values(packages)) {
145+
const {version} = pkg.packageJson;
146+
147+
if (!version.startsWith('0.74.') || version.endsWith('-main')) {
148+
return null;
149+
}
150+
151+
const {minor} = parseVersion(version, 'release');
152+
patchVersion = Math.max(patchVersion, parseInt(minor, 10) + 1);
153+
}
154+
155+
return '0.74.' + patchVersion;
156+
}
157+
119158
function triggerReleaseWorkflow(options /*: $FlowFixMe */) {
120159
return new Promise((resolve, reject) => {
121160
request(options, function (error, response, body) {
@@ -144,11 +183,16 @@ async function main() {
144183
exit(1);
145184
}
146185

186+
// $FlowFixMe[prop-missing]
187+
const useNewWorkflow: boolean = argv.useNewWorkflow;
188+
147189
// now check for unreleased packages
148-
try {
149-
await exitIfUnreleasedPackages();
150-
} catch (error) {
151-
exit(1);
190+
if (!useNewWorkflow) {
191+
try {
192+
await exitIfUnreleasedPackages();
193+
} catch (error) {
194+
exit(1);
195+
}
152196
}
153197

154198
// $FlowFixMe[prop-missing]
@@ -193,11 +237,39 @@ async function main() {
193237
return;
194238
}
195239

196-
const parameters = {
197-
release_version: version,
198-
release_latest: latest,
199-
run_release_workflow: true,
200-
};
240+
let nextMonorepoPackagesVersion;
241+
242+
if (useNewWorkflow) {
243+
nextMonorepoPackagesVersion = await getNextMonorepoPackagesVersion();
244+
245+
if (nextMonorepoPackagesVersion == null) {
246+
// TODO(T182538198): Once this warning is hit, we can remove the
247+
// `release_monorepo_packages_version` logic from here and the CI jobs,
248+
// see other TODOs.
249+
console.warn(
250+
'Warning: No longer on the 0.74-stable branch, meaning we will ' +
251+
'write all package versions identically. Please double-check the ' +
252+
'generated diff to see if this is correct.',
253+
);
254+
nextMonorepoPackagesVersion = version;
255+
}
256+
}
257+
258+
const parameters = useNewWorkflow
259+
? {
260+
release_version: version,
261+
release_latest: latest,
262+
run_release_workflow: true,
263+
}
264+
: {
265+
run_new_release_workflow: true,
266+
release_version: version,
267+
release_tag: npmTag,
268+
// NOTE: Necessary for 0.74, should be dropped for 0.75+
269+
release_monorepo_packages_version: nextMonorepoPackagesVersion,
270+
// $FlowFixMe[prop-missing]
271+
release_dry_run: argv.dryRun,
272+
};
201273

202274
const options = {
203275
method: 'POST',

0 commit comments

Comments
 (0)