Skip to content

Commit

Permalink
Add prepare_release_new workflow, enable via flag
Browse files Browse the repository at this point in the history
Summary:
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 — it's a merge of 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 `set-version` script.
- Updates `trigger-react-native-release.js` to conditionally run this 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.

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D54956345
  • Loading branch information
huntie authored and facebook-github-bot committed Mar 15, 2024
1 parent 0277871 commit 3f3731c
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 11 deletions.
19 changes: 18 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ parameters:
default: false
type: boolean

# Experimental unified release workflow
run_new_release_workflow:
default: false
type: boolean

run_nightly_workflow:
default: false
type: boolean

release_latest:
default: false
type: boolean
Expand All @@ -20,7 +29,15 @@ parameters:
default: ""
type: string

run_nightly_workflow:
release_monorepo_packages_version:
default: ""
type: string

release_tag:
default: ""
type: string

release_dry_run:
default: false
type: boolean

Expand Down
65 changes: 65 additions & 0 deletions .circleci/configurations/jobs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,71 @@ jobs:
node ./scripts/releases-ci/prepare-package-for-release.js -v "$VERSION" -l << parameters.latest >> --dry-run << parameters.dryrun >>
# Experimental unified release workflow
# Replaces `prepare_package_for_release`
#
# Writes a new commit and tag(s), which will trigger the `publish_release`
# and `publish_bumped_packages` workflows.
prepare_release_new:
parameters:
version:
type: string
# TODO(T182538198): Required for 0.74.x, where workspace packages are out
# of sync with react-native. This will be removed for 0.75+.
monorepo_packages_version:
type: string
tag:
type: string
dry_run:
type: boolean
default: false
executor: reactnativeios
steps:
- checkout_code_with_cache
- run_yarn
- add_ssh_keys:
fingerprints:
- "1f:c7:61:c4:e2:ff:77:e3:cc:ca:a7:34:c2:79:e3:3c"
- brew_install:
package: cmake
- run:
name: Versioning workspace packages
command: |
node scripts/releases/set-version "<< parameters.monorepo_packages_version >>" --skip-react-native-version
- run:
name: Versioning react-native package
command: |
node scripts/releases/set-rn-version.js -v "<< parameters.version >>" --build-type "release"
- run:
name: Updating RNTester Podfile.lock
command: |
cd packages/rn-tester/
bundle install
bundle exec pod install
- run:
name: Creating release commit
command: |
git commit -a -m "Release << parameters.version >>\n\n#publish-packages-to-npm&<< parameters.tag >>"
git tag -a "v<< parameters.version >>" -m "v<< parameters.version >>"
git show HEAD
- when:
condition:
equal: ["latest", << parameters.tag >>]
steps:
- run:
name: Updating "latest" tag
command: |
git tag -d "latest"
git push origin :latest
git tag -a "latest" -m "latest"
- unless:
condition: << parameters.dry_run >>
steps:
run:
name: Pushing release commit
command: |
git push origin $CIRCLE_BRANCH --follow-tags
build_npm_package:
parameters:
release_type:
Expand Down
11 changes: 11 additions & 0 deletions .circleci/configurations/workflows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ workflows:
version: << pipeline.parameters.release_version >>
latest : << pipeline.parameters.release_latest >>

# Experimental unified release workflow
create_release_new:
when: << pipeline.parameters.run_new_release_workflow >>
jobs:
- prepare_release_new:
name: prepare_release_new
version: << pipeline.parameters.release_version >>
monorepo_packages_version: << pipeline.parameters.release_monorepo_packages_version >>
tag: << pipeline.parameters.release_tag >>
dry_run: << pipeline.parameters.release_dry_run >>

# This job will run only when a tag is published due to all the jobs being filtered.
publish_release:
jobs:
Expand Down
92 changes: 82 additions & 10 deletions scripts/releases-local/trigger-react-native-release.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ let argv = yargs
describe: 'Version you aim to release, ex. 0.67.0-rc.1, 0.66.3',
required: true,
})
.option('dry-run', {
type: 'boolean',
default: false,
})
// TODO(T182533699): Remove arg once new workflow is default
.option('use-new-workflow', {
describe: 'When set, triggers the experimental unified release workflow.',
type: 'boolean',
default: false,
})
.check(() => {
const branch = exitIfNotOnGit(
() => getBranchName(),
Expand Down Expand Up @@ -78,7 +88,6 @@ const buildExecutor =
if (packageManifest.private) {
return;
}

if (
detectPackageUnreleasedChanges(
packageRelativePathFromRoot,
Expand Down Expand Up @@ -117,6 +126,36 @@ async function exitIfUnreleasedPackages() {
}
}

/**
* 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 @react-native/dev-middleware@0.74.5
const _0_74_MIN_PATCH = 6;

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 {minor} = parseVersion(version, 'release');
patchVersion = Math.max(patchVersion, parseInt(minor, 10) + 1);
}

return '0.74.' + patchVersion;
}

function triggerReleaseWorkflow(options /*: $FlowFixMe */) {
return new Promise((resolve, reject) => {
request(options, function (error, response, body) {
Expand Down Expand Up @@ -145,11 +184,16 @@ async function main() {
exit(1);
}

// $FlowFixMe[prop-missing]
const useNewWorkflow: boolean = argv.useNewWorkflow;

// now check for unreleased packages
try {
await exitIfUnreleasedPackages();
} catch (error) {
exit(1);
if (!useNewWorkflow) {
try {
await exitIfUnreleasedPackages();
} catch (error) {
exit(1);
}
}

// $FlowFixMe[prop-missing]
Expand Down Expand Up @@ -194,11 +238,39 @@ async function main() {
return;
}

const parameters = {
release_version: version,
release_latest: latest,
run_release_workflow: true,
};
let nextMonorepoPackagesVersion;

if (useNewWorkflow) {
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 = useNewWorkflow
? {
release_version: version,
release_latest: latest,
run_release_workflow: true,
}
: {
run_new_release_workflow: true,
release_version: version,
release_tag: npmTag,
// NOTE: Necessary for 0.74, should be dropped for 0.75+
release_monorepo_packages_version: nextMonorepoPackagesVersion,
// $FlowFixMe[prop-missing]
release_dry_run: argv.dryRun,
};

const options = {
method: 'POST',
Expand Down

0 comments on commit 3f3731c

Please sign in to comment.