From ea6e34da772eec7cd1c2189a4a29318e64d7ea63 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Tue, 30 Nov 2021 16:48:47 -0800 Subject: [PATCH] Extract release agnostic logic in bump-oss-version to set-rn-version Summary: Changelog: [Internal] Copy over universal (across dry-run, nightly, release) work in `bump-oss-version` script This work is part of an effort to automate the release process by using a push to a release branch as a trigger to prepare, package and deploy react-native to npm from CircleCI The following diagram describes the context (what kind of releases we do, relevant scripts and what they do), the pre-existing process for the different types of release and how I've modified the process. {F683387103} This diff creates the `set-rn-version` script referenced by extracting it out of `bump-oss-version` Reviewed By: sota000 Differential Revision: D32556608 fbshipit-source-id: 6c2868c01ddd930375279a5105bcd0d447f65734 --- scripts/set-rn-version.js | 163 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100755 scripts/set-rn-version.js diff --git a/scripts/set-rn-version.js b/scripts/set-rn-version.js new file mode 100755 index 00000000000..4afde0c86c6 --- /dev/null +++ b/scripts/set-rn-version.js @@ -0,0 +1,163 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +'use strict'; + +/** + * This script updates relevant React Native files with supplied version: + * * Prepares a package.json suitable for package consumption + * * Updates package.json for template project + * * Updates the version in gradle files and makes sure they are consistent between each other + * * Creates a gemfile + */ +const fs = require('fs'); +const {cat, echo, exec, exit, sed} = require('shelljs'); +const yargs = require('yargs'); +const {parseVersion} = require('./version-utils'); + +let argv = yargs.option('v', { + alias: 'to-version', + type: 'string', +}).argv; + +const version = argv.toVersion; + +if (!version) { + echo('You must specify a version using -v'); + exit(1); +} + +let major, + minor, + patch, + prerelease = -1; +try { + ({major, minor, patch, prerelease} = parseVersion(version)); +} catch (e) { + echo(e.message); + exit(1); +} + +fs.writeFileSync( + 'ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java', + cat('scripts/versiontemplates/ReactNativeVersion.java.template') + .replace('${major}', major) + .replace('${minor}', minor) + .replace('${patch}', patch) + .replace( + '${prerelease}', + prerelease !== undefined ? `"${prerelease}"` : 'null', + ), + 'utf-8', +); + +fs.writeFileSync( + 'React/Base/RCTVersion.m', + cat('scripts/versiontemplates/RCTVersion.m.template') + .replace('${major}', `@(${major})`) + .replace('${minor}', `@(${minor})`) + .replace('${patch}', `@(${patch})`) + .replace( + '${prerelease}', + prerelease !== undefined ? `@"${prerelease}"` : '[NSNull null]', + ), + 'utf-8', +); + +fs.writeFileSync( + 'ReactCommon/cxxreact/ReactNativeVersion.h', + cat('scripts/versiontemplates/ReactNativeVersion.h.template') + .replace('${major}', major) + .replace('${minor}', minor) + .replace('${patch}', patch) + .replace( + '${prerelease}', + prerelease !== undefined ? `"${prerelease}"` : '""', + ), + 'utf-8', +); + +fs.writeFileSync( + 'Libraries/Core/ReactNativeVersion.js', + cat('scripts/versiontemplates/ReactNativeVersion.js.template') + .replace('${major}', major) + .replace('${minor}', minor) + .replace('${patch}', patch) + .replace( + '${prerelease}', + prerelease !== undefined ? `'${prerelease}'` : 'null', + ), + 'utf-8', +); + +let packageJson = JSON.parse(cat('package.json')); +packageJson.version = version; +delete packageJson.workspaces; +delete packageJson.private; + +// Copy dependencies over from repo-config/package.json +const repoConfigJson = JSON.parse(cat('repo-config/package.json')); +packageJson.devDependencies = { + ...packageJson.devDependencies, + ...repoConfigJson.dependencies, +}; +// Make react-native-codegen a direct dependency of react-native +delete packageJson.devDependencies['react-native-codegen']; +packageJson.dependencies = { + ...packageJson.dependencies, + 'react-native-codegen': repoConfigJson.dependencies['react-native-codegen'], +}; +fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2), 'utf-8'); + +// Change ReactAndroid/gradle.properties +if ( + sed( + '-i', + /^VERSION_NAME=.*/, + `VERSION_NAME=${version}`, + 'ReactAndroid/gradle.properties', + ).code +) { + echo("Couldn't update version for Gradle"); + exit(1); +} + +// Change react-native version in the template's package.json +exec(`node scripts/set-rn-template-version.js ${version}`); + +// Make sure to update ruby version +if (exec('scripts/update-ruby.sh').code) { + echo('Failed to update Ruby version'); + exit(1); +} + +// Verify that files changed, we just do a git diff and check how many times version is added across files +const filesToValidate = [ + 'package.json', + 'ReactAndroid/gradle.properties', + 'template/package.json', +]; +const numberOfChangedLinesWithNewVersion = exec( + `git diff -U0 ${filesToValidate.join( + ' ', + )}| grep '^[+]' | grep -c ${version} `, + {silent: true}, +).stdout.trim(); + +if (+numberOfChangedLinesWithNewVersion !== filesToValidate.length) { + echo( + `Failed to update all the files: [${filesToValidate.join( + ', ', + )}] must have versions in them`, + ); + echo('Fix the issue and try again'); + exit(1); +} + +exit(0);