Skip to content

Commit 406dd87

Browse files
j-piaseckimeta-codesync[bot]
authored andcommitted
Update release processes to update the Hermes versions independently from React Native (#53985)
Summary: Pull Request resolved: #53985 Changelog: [Internal] Updates the release scripts to set the Hermes version independently from React Native. Reviewed By: cipolleschi Differential Revision: D82438054 fbshipit-source-id: 154c19d1d0d16fd5879ad663428d803ceadc5a1f
1 parent 93c17cd commit 406dd87

9 files changed

Lines changed: 267 additions & 23 deletions

File tree

packages/react-native/scripts/hermes/__tests__/hermes-utils-test.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const {
2222
getHermesTagSHA,
2323
getHermesTarballDownloadPath,
2424
readHermesTag,
25+
readHermesV1Tag,
2526
setHermesTag,
2627
shouldUsePrebuiltHermesC,
2728
} = require('../hermes-utils');
@@ -31,6 +32,7 @@ const os = require('os');
3132

3233
const hermesTag =
3334
'hermes-2022-04-28-RNv0.69.0-15d07c2edd29a4ea0b8f15ab0588a0c1adb1200f';
35+
const hermesV1Tag = '250829098.0.0';
3436
const tarballContents = 'dummy string';
3537
const hermescContents = 'dummy string';
3638
const hermesTagSha = '5244f819b2f3949ca94a3a1bf75d54a8ed59d94a';
@@ -182,18 +184,26 @@ describe('hermes-utils', () => {
182184
});
183185

184186
describe('setHermesTag', () => {
185-
it('should write tag to .hermesversion file', () => {
186-
setHermesTag(hermesTag);
187+
it('should write tag to .hermesversion file', async () => {
188+
await setHermesTag(hermesTag, hermesV1Tag);
187189
expect(
188190
fs.readFileSync(path.join(SDKS_DIR, '.hermesversion'), {
189191
encoding: 'utf8',
190192
flag: 'r',
191193
}),
192194
).toEqual(hermesTag);
195+
196+
expect(
197+
fs.readFileSync(path.join(SDKS_DIR, '.hermesv1version'), {
198+
encoding: 'utf8',
199+
flag: 'r',
200+
}),
201+
).toEqual(hermesV1Tag);
193202
});
194-
it('should set Hermes tag and read it back', () => {
195-
setHermesTag(hermesTag);
203+
it('should set Hermes tag and read it back', async () => {
204+
await setHermesTag(hermesTag, hermesV1Tag);
196205
expect(readHermesTag()).toEqual(hermesTag);
206+
expect(readHermesV1Tag()).toEqual(hermesV1Tag);
197207
});
198208
});
199209

packages/react-native/scripts/hermes/bump-hermes-version.js

Lines changed: 78 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111

1212
'use strict';
1313

14+
const {
15+
updateHermesCompilerVersionInDependencies,
16+
updateHermesRuntimeDependenciesVersions,
17+
} = require('../../../../scripts/releases/utils/hermes-utils');
18+
const {
19+
getPackageVersionStrByTag,
20+
} = require('../../../../scripts/releases/utils/npm-utils');
1421
const {setHermesTag} = require('./hermes-utils');
1522
// $FlowFixMe[untyped-import]
1623
const inquirer = require('inquirer');
@@ -21,28 +28,88 @@ const inquirer = require('inquirer');
2128
const {exit} = require('shelljs');
2229
const yargs = require('yargs');
2330

24-
let argv = yargs.option('t', {
25-
alias: 'tag',
26-
describe:
27-
'Hermes release tag to use for this React Native release, ex. hermes-2022-02-21-RNv0.68.0',
28-
required: true,
29-
}).argv;
31+
let argv = yargs
32+
.option('t', {
33+
alias: 'tag',
34+
describe:
35+
'Hermes release tag to use for this React Native release, ex. hermes-2022-02-21-RNv0.68.0. This tag will be used when building Hermes from source.',
36+
required: true,
37+
})
38+
.option('s', {
39+
alias: 'v1-tag',
40+
describe:
41+
'Hermes V1 release tag to use for this React Native release, ex. 250829098.0.0. This tag will be used when building Hermes V1 from source.',
42+
required: true,
43+
})
44+
.option('h', {
45+
alias: 'hermes-version',
46+
describe:
47+
'Hermes version to use for this React Native release, ex. 250829098.0.0. This version will be used when consuming Hermes from a prebuilt package.',
48+
required: false,
49+
})
50+
.option('v', {
51+
alias: 'hermes-v1-version',
52+
describe:
53+
'Hermes V1 version to use for this React Native release, ex. 250829098.0.0. This version will be used when consuming Hermes V1 from a prebuilt package.',
54+
required: false,
55+
}).argv;
3056

3157
async function main() {
3258
// $FlowFixMe[prop-missing]
3359
const hermesTag = argv.tag;
34-
const {confirmHermesTag} = await inquirer.prompt({
60+
// $FlowFixMe[prop-missing]
61+
const hermesV1Tag = argv['v1-tag'];
62+
// $FlowFixMe[prop-missing]
63+
let hermesVersion = argv['hermes-version'];
64+
// $FlowFixMe[prop-missing]
65+
let hermesV1Version = argv['hermes-v1-version'];
66+
67+
if (!hermesVersion) {
68+
console.log(
69+
'No Hermes version provided. Fetching the latest version from NPM...',
70+
);
71+
hermesVersion = await getPackageVersionStrByTag(
72+
'hermes-compiler',
73+
'latest-v0',
74+
);
75+
}
76+
77+
if (!hermesV1Version) {
78+
console.log(
79+
'No Hermes V1 version provided. Fetching the latest version from NPM...',
80+
);
81+
hermesV1Version = await getPackageVersionStrByTag(
82+
'hermes-compiler',
83+
'latest-v1',
84+
);
85+
}
86+
87+
const {confirmHermesVersions} = await inquirer.prompt({
3588
type: 'confirm',
36-
name: 'confirmHermesTag',
37-
message: `Do you want to use the Hermes release tagged "${hermesTag}"?`,
89+
name: 'confirmHermesVersions',
90+
message: `Do you want to use the Hermes version "${hermesVersion}" and Hermes V1 version "${hermesV1Version}" (for prebuilt)?`,
3891
});
3992

40-
if (!confirmHermesTag) {
93+
if (!confirmHermesVersions) {
4194
console.log('Aborting.');
4295
return;
4396
}
4497

45-
setHermesTag(hermesTag);
98+
const {confirmHermesTags} = await inquirer.prompt({
99+
type: 'confirm',
100+
name: 'confirmHermesTags',
101+
message: `Do you want to use the Hermes release tagged "${hermesTag}" and Hermes V1 release tagged "${hermesV1Tag}" (for building from source)?`,
102+
});
103+
104+
if (!confirmHermesTags) {
105+
console.log('Aborting.');
106+
return;
107+
}
108+
109+
await setHermesTag(hermesTag, hermesV1Tag);
110+
111+
await updateHermesCompilerVersionInDependencies(hermesVersion);
112+
await updateHermesRuntimeDependenciesVersions(hermesVersion, hermesV1Version);
46113
}
47114

48115
void main().then(() => {

packages/react-native/scripts/hermes/hermes-utils.js

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
const {execSync, spawnSync} = require('child_process');
1414
const fs = require('fs');
15+
// $FlowFixMe[untyped-import]
16+
const inquirer = require('inquirer');
1517
const os = require('os');
1618
const path = require('path');
1719

@@ -22,6 +24,7 @@ type BuildType = 'dry-run' | 'release' | 'nightly';
2224
const SDKS_DIR = path.normalize(path.join(__dirname, '..', '..', 'sdks'));
2325
const HERMES_DIR = path.join(SDKS_DIR, 'hermes');
2426
const HERMES_TAG_FILE_PATH = path.join(SDKS_DIR, '.hermesversion');
27+
const HERMES_V1_TAG_FILE_PATH = path.join(SDKS_DIR, '.hermesv1version');
2528
const HERMES_SOURCE_TARBALL_BASE_URL =
2629
'https://github.com/facebook/hermes/tarball/';
2730
const HERMES_TARBALL_DOWNLOAD_DIR = path.join(SDKS_DIR, 'download');
@@ -66,17 +69,66 @@ function readHermesTag() /*: string */ {
6669
return 'main';
6770
}
6871

69-
function setHermesTag(hermesTag /*: string */) {
70-
if (readHermesTag() === hermesTag) {
71-
// No need to update.
72-
return;
72+
function readHermesV1Tag() /*: string */ {
73+
if (fs.existsSync(HERMES_V1_TAG_FILE_PATH)) {
74+
const data = fs
75+
.readFileSync(HERMES_V1_TAG_FILE_PATH, {
76+
encoding: 'utf8',
77+
flag: 'r',
78+
})
79+
.trim();
80+
81+
if (data.length > 0) {
82+
return data;
83+
} else {
84+
throw new Error('[Hermes] .hermesv1version file is empty.');
85+
}
7386
}
7487

88+
throw new Error('[Hermes] .hermesv1version does not exist.');
89+
}
90+
91+
async function updateHermesTag(
92+
tagFile /*: string */,
93+
hermesTag /*: string */,
94+
prompt /*: string */,
95+
) {
96+
if (!fs.existsSync(tagFile)) {
97+
fs.writeFileSync(tagFile, hermesTag.trim());
98+
} else {
99+
const previousHermesTag = fs.readFileSync(tagFile, {
100+
encoding: 'utf8',
101+
flag: 'r',
102+
});
103+
104+
if (previousHermesTag.trim() !== hermesTag.trim()) {
105+
const {confirmHermesTag} = await inquirer.prompt({
106+
type: 'confirm',
107+
name: 'confirmHermesTag',
108+
message: `Do you want to use updtate release tag for ${prompt} from "${previousHermesTag}" to "${hermesTag}"?`,
109+
});
110+
111+
if (confirmHermesTag) {
112+
fs.writeFileSync(tagFile, hermesTag.trim());
113+
} else {
114+
console.log(`[${prompt}] .hermesversion file is unchanged.`);
115+
}
116+
} else {
117+
console.log(`[${prompt}] .hermesversion file is unchanged.`);
118+
}
119+
}
120+
}
121+
122+
async function setHermesTag(
123+
hermesTag /*: string */,
124+
hermesV1Tag /*: string */,
125+
) {
75126
if (!fs.existsSync(SDKS_DIR)) {
76127
fs.mkdirSync(SDKS_DIR, {recursive: true});
77128
}
78-
fs.writeFileSync(HERMES_TAG_FILE_PATH, hermesTag.trim());
79-
console.log('Hermes tag has been updated. Please commit your changes.');
129+
130+
await updateHermesTag(HERMES_TAG_FILE_PATH, hermesTag, 'Hermes');
131+
await updateHermesTag(HERMES_V1_TAG_FILE_PATH, hermesV1Tag, 'Hermes V1');
80132
}
81133

82134
function getHermesTagSHA(hermesTag /*: string */) /*: string */ {
@@ -337,6 +389,7 @@ module.exports = {
337389
getHermesTarballDownloadPath,
338390
getHermesPrebuiltArtifactsTarballName,
339391
readHermesTag,
392+
readHermesV1Tag,
340393
setHermesTag,
341394
shouldBuildHermesFromSource,
342395
shouldUsePrebuiltHermesC,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
HERMES_VERSION_NAME=1000.0.0
12
HERMES_V1_VERSION_NAME=250829098.0.1

scripts/releases-ci/__tests__/publish-npm-test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const publishPackageMock = jest.fn();
2020
const getNpmInfoMock = jest.fn();
2121
const generateAndroidArtifactsMock = jest.fn();
2222
const getPackagesMock = jest.fn();
23+
const updateHermesVersionsToNightlyMock = jest.fn();
2324

2425
const {REPO_ROOT} = require('../../shared/consts');
2526
const {publishNpm} = require('../publish-npm');
@@ -53,6 +54,9 @@ describe('publish-npm', () => {
5354
...jest.requireActual('../../releases/utils/npm-utils'),
5455
publishPackage: publishPackageMock,
5556
getNpmInfo: getNpmInfoMock,
57+
}))
58+
.mock('../../releases/utils/hermes-utils', () => ({
59+
updateHermesVersionsToNightly: updateHermesVersionsToNightlyMock,
5660
}));
5761
});
5862

@@ -98,6 +102,7 @@ describe('publish-npm', () => {
98102

99103
await publishNpm('dry-run');
100104

105+
expect(updateHermesVersionsToNightlyMock).toHaveBeenCalled();
101106
expect(setVersionMock).not.toBeCalled();
102107
expect(updateReactNativeArtifactsMock).toBeCalledWith(version, 'dry-run');
103108

@@ -155,6 +160,8 @@ describe('publish-npm', () => {
155160
// Generate Android artifacts is now delegate to build_android entirely
156161
expect(generateAndroidArtifactsMock).not.toHaveBeenCalled();
157162

163+
expect(updateHermesVersionsToNightlyMock).toHaveBeenCalled();
164+
158165
expect(publishPackageMock.mock.calls).toEqual([
159166
[
160167
'path/to/monorepo/pkg-a',

scripts/releases-ci/publish-npm.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ const {
1818
updateReactNativeArtifacts,
1919
} = require('../releases/set-rn-artifacts-version');
2020
const {setVersion} = require('../releases/set-version');
21+
const {
22+
updateHermesVersionsToNightly,
23+
} = require('../releases/utils/hermes-utils');
2124
const {getNpmInfo, publishPackage} = require('../releases/utils/npm-utils');
2225
const {
2326
publishAndroidArtifactsToMaven,
@@ -96,6 +99,9 @@ async function publishNpm(buildType /*: BuildType */) /*: Promise<void> */ {
9699

97100
// For stable releases, ci job `prepare_package_for_release` handles this
98101
if (buildType === 'nightly') {
102+
// Set hermes versions to latest available
103+
await updateHermesVersionsToNightly();
104+
99105
// Set same version for all monorepo packages
100106
await setVersion(version);
101107
await publishMonorepoPackages(tag);
@@ -113,6 +119,8 @@ async function publishNpm(buildType /*: BuildType */) /*: Promise<void> */ {
113119
const packageJson = JSON.parse(packageJsonContent);
114120

115121
if (packageJson.version === '1000.0.0') {
122+
// Set hermes versions to latest available
123+
await updateHermesVersionsToNightly();
116124
await updateReactNativeArtifacts(version, buildType);
117125
}
118126
}

scripts/releases/set-rn-artifacts-version.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,6 @@ function updateTestFiles(
155155
async function updateGradleFile(version /*: string */) /*: Promise<void> */ {
156156
const contents = await fs.readFile(GRADLE_FILE_PATH, 'utf-8');
157157

158-
// TODO: T231755027 set HERMES_VERSION_NAME
159-
160158
return fs.writeFile(
161159
GRADLE_FILE_PATH,
162160
contents.replace(/^VERSION_NAME=.*/, `VERSION_NAME=${version}`),

0 commit comments

Comments
 (0)