From 5bc12891ba71e5f34cbbff9e972f1a2503e78a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Mon, 29 Jan 2024 09:55:38 +0100 Subject: [PATCH] feat: Automate releases to GitHub (#83) fix: adjust oot-release script for stable releases (#85) --- scripts/new-github-release-url.js | 37 +++++++++++++++++++ scripts/oot-release.js | 61 ++++++++++++++++++++++++++++--- 2 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 scripts/new-github-release-url.js diff --git a/scripts/new-github-release-url.js b/scripts/new-github-release-url.js new file mode 100644 index 00000000000000..3292eda6b6ac63 --- /dev/null +++ b/scripts/new-github-release-url.js @@ -0,0 +1,37 @@ +function newGithubReleaseUrl(options = {}) { + let repoUrl; + if (options.repoUrl) { + repoUrl = options.repoUrl; + } else if (options.user && options.repo) { + repoUrl = `https://github.com/${options.user}/${options.repo}`; + } else { + throw new Error('You need to specify either the `repoUrl` option or both the `user` and `repo` options'); + } + + const url = new URL(`${repoUrl}/releases/new`); + + const types = [ + 'tag', + 'target', + 'title', + 'body', + 'isPrerelease', + ]; + + for (let type of types) { + const value = options[type]; + if (value === undefined) { + continue; + } + + if (type === 'isPrerelease') { + type = 'prerelease'; + } + + url.searchParams.set(type, value); + } + + return url.toString(); +} + +module.exports = newGithubReleaseUrl; diff --git a/scripts/oot-release.js b/scripts/oot-release.js index 21e281e78b148e..2e9f216b6b3360 100644 --- a/scripts/oot-release.js +++ b/scripts/oot-release.js @@ -7,13 +7,18 @@ 'use strict'; const forEachPackage = require('./monorepo/for-each-package'); +const newGithubReleaseUrl = require('./new-github-release-url'); const {applyPackageVersions, publishPackage} = require('./npm-utils'); +const {failIfTagExists} = require('./release-utils'); const updateTemplatePackage = require('./update-template-package'); +const {execSync} = require('child_process'); const fs = require('fs'); const path = require('path'); const {cat, echo, exit} = require('shelljs'); const yargs = require('yargs'); +const REPO_ROOT = path.resolve(__dirname, '../'); + /** * This script updates core packages to the version of React Native that we are basing on, * updates internal visionOS packages and releases them. @@ -89,6 +94,7 @@ function releaseOOT( oneTimePassword, tag = 'latest', ) { + const isNightly = tag === 'nightly'; const allPackages = getPackages(); const corePackages = Object.keys(allPackages).filter(packageName => packageName.startsWith('@react-native/'), @@ -102,25 +108,55 @@ function releaseOOT( {}, ); + const visionOSPackagesVersions = visionOSPackages.reduce( + (acc, pkg) => ({...acc, [pkg]: newVersion}), + {}, + ); + // Update `packges/react-native` package.json and all visionOS packages - visionOSPackages.forEach(pkg => { - echo(`Setting ${pkg} version to ${newVersion} `); - setPackage(allPackages[pkg], newVersion, corePackagesVersions); - }); + if (isNightly) { + visionOSPackages.forEach(pkg => { + echo(`Setting ${pkg} version to ${newVersion} `); + setPackage(allPackages[pkg], newVersion, corePackagesVersions); + }); + } else { + visionOSPackages.forEach(pkg => { + echo(`Setting ${pkg} version to ${newVersion} `); + setPackage(allPackages[pkg], newVersion, visionOSPackagesVersions); + }); + } // Update template package.json updateTemplatePackage({ 'react-native': reactNativeVersion, - ...corePackagesVersions, - ...visionOSPackages.reduce((acc, pkg) => ({...acc, [pkg]: newVersion}), {}), + ...visionOSPackagesVersions, }); + + if (isNightly) { + updateTemplatePackage(corePackagesVersions); + } + echo(`Updating template and it's dependencies to ${reactNativeVersion}`); + echo('Building packages...\n'); + execSync('node ./scripts/build/build.js', { + cwd: REPO_ROOT, + stdio: [process.stdin, process.stdout, process.stderr], + }); + // Release visionOS packages only if OTP is passed if (!oneTimePassword) { return; } + const gitTag = `v${newVersion}-visionos`; + failIfTagExists(gitTag, 'release'); + // Create git tag + execSync(`git tag -a ${gitTag} -m "Release ${newVersion}"`, { + cwd: REPO_ROOT, + stdio: [process.stdin, process.stdout, process.stderr], + }); + const results = visionOSPackages .map(npmPackage => { return path.join(__dirname, '..', allPackages[npmPackage]); @@ -144,6 +180,19 @@ function releaseOOT( ', ', )} to npm with version: ${newVersion}`, ); + + const releaseURL = newGithubReleaseUrl({ + tag: gitTag, + title: `Release ${newVersion}`, + repo: 'react-native-visionos', + user: 'callstack', + }); + + echo('\n\n'); + echo('-------------------------------------------\n'); + echo(`Create a new release here: ${releaseURL}\n`); + echo('-------------------------------------------'); + return exit(0); } }