diff --git a/.circleci/config.yml b/.circleci/config.yml index 439698d301e9aa..af889bdc060522 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -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 @@ -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 diff --git a/.circleci/configurations/jobs.yml b/.circleci/configurations/jobs.yml index d40dbc45e4a2c9..673a4dff4ec6a8 100644 --- a/.circleci/configurations/jobs.yml +++ b/.circleci/configurations/jobs.yml @@ -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: diff --git a/.circleci/configurations/top_level.yml b/.circleci/configurations/top_level.yml index 165b2be7969ee1..4c76d009a026cb 100644 --- a/.circleci/configurations/top_level.yml +++ b/.circleci/configurations/top_level.yml @@ -129,14 +129,30 @@ parameters: default: false type: boolean + run_new_release_workflow: + default: false + type: boolean + + run_nightly_workflow: + default: false + type: boolean + release_latest: default: false type: boolean release_version: - default: "9999" + 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 diff --git a/.circleci/configurations/workflows.yml b/.circleci/configurations/workflows.yml index 7bf29679184d82..cb74962959d3a1 100644 --- a/.circleci/configurations/workflows.yml +++ b/.circleci/configurations/workflows.yml @@ -6,6 +6,7 @@ # when: # and: # - equal: [ false, << pipeline.parameters.run_release_workflow >> ] +# - equal: [ false, << pipeline.parameters.run_new_release_workflow >> ] # - equal: [ false, << pipeline.parameters.run_nightly_workflow >> ] # # It's setup this way so we can trigger a release via a POST @@ -25,6 +26,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: @@ -79,6 +91,7 @@ workflows: when: and: - equal: [ false, << pipeline.parameters.run_release_workflow >> ] + - equal: [ false, << pipeline.parameters.run_new_release_workflow >> ] - equal: [ false, << pipeline.parameters.run_nightly_workflow >> ] jobs: # Run lints on every commit @@ -128,6 +141,7 @@ workflows: when: and: - equal: [ false, << pipeline.parameters.run_release_workflow >> ] + - equal: [ false, << pipeline.parameters.run_new_release_workflow >> ] - equal: [ false, << pipeline.parameters.run_nightly_workflow >> ] jobs: - find_and_publish_bumped_packages: diff --git a/scripts/releases-local/trigger-react-native-release.js b/scripts/releases-local/trigger-react-native-release.js index b9fc887741a156..6185d478a7edf1 100644 --- a/scripts/releases-local/trigger-react-native-release.js +++ b/scripts/releases-local/trigger-react-native-release.js @@ -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(), @@ -78,7 +88,6 @@ const buildExecutor = if (packageManifest.private) { return; } - if ( detectPackageUnreleasedChanges( packageRelativePathFromRoot, @@ -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 */ { + // 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) { @@ -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] @@ -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',