Skip to content

Commit 9a86d32

Browse files
feat: implement OOT release script (#43)
* feat: implement OOT release script * docs: add readme on Release process * fix: remove header file Co-authored-by: Michał Pierzchała <thymikee@gmail.com> * add reference --------- Co-authored-by: Michał Pierzchała <thymikee@gmail.com>
1 parent b089138 commit 9a86d32

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,15 @@ It's important not to cover the translucent background with a solid color, as it
5353

5454
1. Follow the same steps as in the `New project creation` section.
5555
2. Checkout `rn-tester` [README.md](./packages/rn-tester/README.md) to build React Native from source.
56+
57+
## Release process
58+
59+
We use a script called `oot-release.js` which automatically releases `visionos` packages and aligns versions of dependencies with React Native core.
60+
61+
Usage:
62+
63+
```sh
64+
node ./scripts/oot-release.js --new-version "<visionos-version>" --react-native-version "<react-native-version>" --one-time-password "<otp>"
65+
```
66+
67+
To test releases and template we use [Verdaccio](https://verdaccio.org/).

scripts/oot-release.js

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/**
2+
* Based on `scripts/trigger-react-native-release.js` and `set-rn-version.js`
3+
*
4+
* @format
5+
*/
6+
7+
'use strict';
8+
9+
const forEachPackage = require('./monorepo/for-each-package');
10+
const {applyPackageVersions, publishPackage} = require('./npm-utils');
11+
const updateTemplatePackage = require('./update-template-package');
12+
const fs = require('fs');
13+
const path = require('path');
14+
const {cat, echo, exit} = require('shelljs');
15+
const yargs = require('yargs');
16+
17+
/**
18+
* This script updates core packages to the version of React Native that we are basing on,
19+
* updates internal visionOS packages and releases them.
20+
*/
21+
if (require.main === module) {
22+
let {argv} = yargs
23+
.option('v', {
24+
alias: 'new-version',
25+
type: 'string',
26+
describe:
27+
'New version of `@callstack/react-native-visionos` to be released',
28+
required: true,
29+
})
30+
.option('r', {
31+
alias: 'react-native-version',
32+
type: 'string',
33+
describe:
34+
'React Native version that this release is based on. Ex. "0.72.7" or "0.74.0-nightly-20231130-7e5f15b88"',
35+
required: true,
36+
})
37+
.option('t', {
38+
alias: 'tag',
39+
type: 'string',
40+
describe: 'Tag to be used for publishing packages',
41+
required: false,
42+
})
43+
.option('o', {
44+
alias: 'one-time-password',
45+
type: 'string',
46+
describe: 'One time password for npm publish',
47+
required: false,
48+
});
49+
50+
releaseOOT(
51+
argv.newVersion,
52+
argv.reactNativeVersion,
53+
argv.oneTimePassword,
54+
argv.tag,
55+
);
56+
exit(0);
57+
}
58+
59+
function getPackages() {
60+
const packages = {};
61+
forEachPackage(
62+
(packageAbsolutePath, packageRelativePathFromRoot, packageManifest) => {
63+
packages[packageManifest.name] = packageRelativePathFromRoot;
64+
},
65+
{includeReactNative: true},
66+
);
67+
return packages;
68+
}
69+
70+
function setPackage(packagePath, version, dependencyVersions) {
71+
const originalPackageJson = JSON.parse(cat(`${packagePath}/package.json`));
72+
const packageJson =
73+
dependencyVersions != null
74+
? applyPackageVersions(originalPackageJson, dependencyVersions)
75+
: originalPackageJson;
76+
77+
packageJson.version = version;
78+
79+
fs.writeFileSync(
80+
`${packagePath}/package.json`,
81+
JSON.stringify(packageJson, null, 2),
82+
'utf-8',
83+
);
84+
}
85+
86+
function releaseOOT(
87+
newVersion,
88+
reactNativeVersion,
89+
oneTimePassword,
90+
tag = 'latest',
91+
) {
92+
const allPackages = getPackages();
93+
const corePackages = Object.keys(allPackages).filter(packageName =>
94+
packageName.startsWith('@react-native/'),
95+
);
96+
const visionOSPackages = Object.keys(allPackages).filter(packageName =>
97+
packageName.startsWith('@callstack/'),
98+
);
99+
100+
const corePackagesVersions = corePackages.reduce(
101+
(acc, pkg) => ({...acc, [pkg]: reactNativeVersion}),
102+
{},
103+
);
104+
105+
// Update `packges/react-native` package.json and all visionOS packages
106+
visionOSPackages.forEach(pkg => {
107+
echo(`Setting ${pkg} version to ${newVersion} `);
108+
setPackage(allPackages[pkg], newVersion, corePackagesVersions);
109+
});
110+
111+
// Update template package.json
112+
updateTemplatePackage({
113+
'react-native': reactNativeVersion,
114+
...corePackagesVersions,
115+
...visionOSPackages.reduce((acc, pkg) => ({...acc, [pkg]: newVersion}), {}),
116+
});
117+
echo(`Updating template and it's dependencies to ${reactNativeVersion}`);
118+
119+
// Release visionOS packages only if OTP is passed
120+
if (!oneTimePassword) {
121+
return;
122+
}
123+
124+
const results = visionOSPackages
125+
.map(npmPackage => {
126+
return path.join(__dirname, '..', allPackages[npmPackage]);
127+
})
128+
.map(packagePath => {
129+
echo(`Releasing ${packagePath}`);
130+
const result = publishPackage(packagePath, {
131+
tag,
132+
otp: oneTimePassword,
133+
});
134+
135+
return result.code;
136+
});
137+
138+
if (results.every(Boolean)) {
139+
echo(`Failed to publish ${visionOSPackages.join(', ')} packages to npm`);
140+
return exit(1);
141+
} else {
142+
echo(
143+
`Published ${visionOSPackages.join(
144+
', ',
145+
)} to npm with version: ${newVersion}`,
146+
);
147+
return exit(0);
148+
}
149+
}
150+
151+
module.exports = releaseOOT;

0 commit comments

Comments
 (0)