1010'use strict' ;
1111
1212/**
13- * This script publishes a new version of react-native to NPM.
13+ * This script prepares a release version of react-native and may publish to NPM.
1414 * It is supposed to run in CI environment, not on a developer's machine.
1515 *
1616 * To make it easier for developers it uses some logic to identify with which
1717 * version to publish the package.
1818 *
1919 * To cut a branch (and release RC):
2020 * - Developer: `git checkout -b 0.XY-stable`
21- * - Developer: `./scripts/bump-oss-version.js v0.XY.0-rc.0`
21+ * - Developer: `./scripts/bump-oss-version.js -v v0.XY.0-rc.0`
2222 * - CI: test and deploy to npm (run this script) with version `0.XY.0-rc.0`
2323 * with tag "next"
2424 *
2525 * To update RC release:
2626 * - Developer: `git checkout 0.XY-stable`
2727 * - Developer: cherry-pick whatever changes needed
28- * - Developer: `./scripts/bump-oss-version.js v0.XY.0-rc.1`
28+ * - Developer: `./scripts/bump-oss-version.js -v v0.XY.0-rc.1`
2929 * - CI: test and deploy to npm (run this script) with version `0.XY.0-rc.1`
3030 * with tag "next"
3131 *
3232 * To publish a release:
3333 * - Developer: `git checkout 0.XY-stable`
3434 * - Developer: cherry-pick whatever changes needed
35- * - Developer: `./scripts/bump-oss-version.js v0.XY.0`
35+ * - Developer: `./scripts/bump-oss-version.js -v v0.XY.0`
3636 * - CI: test and deploy to npm (run this script) with version `0.XY.0`
3737 * and no tag ("latest" is implied by npm)
3838 *
4949 * If tag v0.XY.Z is present on the commit then publish to npm with version 0.XY.Z and no tag (npm will consider it latest)
5050 */
5151
52- /*eslint-disable no-undef */
53- require ( 'shelljs/global' ) ;
52+ const { exec, echo, exit, test} = require ( 'shelljs' ) ;
5453const yargs = require ( 'yargs' ) ;
54+ const { parseVersion} = require ( './version-utils' ) ;
5555
56- let argv = yargs . option ( 'n' , {
57- alias : 'nightly' ,
58- type : 'boolean' ,
59- default : false ,
60- } ) . argv ;
61-
62- const nightlyBuild = argv . nightly ;
6356const buildTag = process . env . CIRCLE_TAG ;
6457const otp = process . env . NPM_CONFIG_OTP ;
6558
66- let branchVersion = 0 ;
67- if ( nightlyBuild ) {
68- branchVersion = 0 ;
69- } else {
70- if ( ! buildTag ) {
71- echo ( 'Error: We publish only from git tags' ) ;
72- exit ( 1 ) ;
73- }
74-
75- let match = buildTag . match ( / ^ v ( \d + \. \d + ) \. \d + (?: - .+ ) ? $ / ) ;
76- if ( ! match ) {
77- echo ( 'Error: We publish only from release version git tags' ) ;
78- exit ( 1 ) ;
79- }
80- [ , branchVersion ] = match ;
81- }
82- // 0.33
59+ const argv = yargs
60+ . option ( 'n' , {
61+ alias : 'nightly' ,
62+ type : 'boolean' ,
63+ default : false ,
64+ } )
65+ . option ( 'd' , {
66+ alias : 'dry-run' ,
67+ type : 'boolean' ,
68+ default : false ,
69+ } ) . argv ;
70+ const nightlyBuild = argv . nightly ;
71+ const dryRunBuild = argv . dryRun ;
8372
8473// 34c034298dc9cad5a4553964a5a324450fda0385
85- const currentCommit = exec ( 'git rev-parse HEAD' , { silent : true } ) . stdout . trim ( ) ;
86- // [34c034298dc9cad5a4553964a5a324450fda0385, refs/heads/0.33-stable, refs/tags/latest, refs/tags/v0.33.1, refs/tags/v0.34.1-rc]
87- const tagsWithVersion = exec ( `git ls-remote origin | grep ${ currentCommit } ` , {
74+ const currentCommit = exec ( 'git rev-parse HEAD' , {
8875 silent : true ,
89- } )
90- . stdout . split ( / \s / )
91- // ['refs/tags/v0.33.0', 'refs/tags/v0.33.0-rc', 'refs/tags/v0.33.0-rc1', 'refs/tags/v0.33.0-rc2', 'refs/tags/v0.34.0']
92- . filter (
93- version =>
94- ! ! version && version . indexOf ( `refs/tags/v${ branchVersion } ` ) === 0 ,
95- )
96- // ['refs/tags/v0.33.0', 'refs/tags/v0.33.0-rc', 'refs/tags/v0.33.0-rc1', 'refs/tags/v0.33.0-rc2']
97- . filter ( version => version . indexOf ( branchVersion ) !== - 1 )
98- // ['v0.33.0', 'v0.33.0-rc', 'v0.33.0-rc1', 'v0.33.0-rc2']
99- . map ( version => version . slice ( 'refs/tags/' . length ) ) ;
100-
101- if ( ! nightlyBuild && tagsWithVersion . length === 0 ) {
102- echo (
103- 'Error: Cannot find version tag in current commit. To deploy to NPM you must add tag v0.XY.Z[-rc] to your commit' ,
104- ) ;
76+ } ) . stdout . trim ( ) ;
77+ const shortCommit = currentCommit . slice ( 0 , 9 ) ;
78+
79+ const rawVersion =
80+ // 0.0.0 triggers issues with cocoapods for codegen when building template project.
81+ dryRunBuild
82+ ? '1000.0.0'
83+ : // For nightly we continue to use 0.0.0 for clarity for npm
84+ nightlyBuild
85+ ? '0.0.0'
86+ : // For pre-release and stable releases, we use the git tag of the version we're releasing (set in bump-oss-version)
87+ buildTag ;
88+
89+ let version ,
90+ major ,
91+ minor ,
92+ prerelease = null ;
93+ try {
94+ ( { version, major, minor, prerelease} = parseVersion ( rawVersion ) ) ;
95+ } catch ( e ) {
96+ echo ( e . message ) ;
10597 exit ( 1 ) ;
10698}
10799let releaseVersion ;
100+ if ( dryRunBuild ) {
101+ releaseVersion = `${ version } -${ shortCommit } ` ;
102+ } else if ( nightlyBuild ) {
103+ // 2021-09-28T05:38:40.669Z -> 20210928-0538
104+ const dateIdentifier = new Date ( )
105+ . toISOString ( )
106+ . slice ( 0 , - 8 )
107+ . replace ( / [ - : ] / g, '' )
108+ . replace ( / [ T ] / g, '-' ) ;
109+ releaseVersion = `${ version } -${ dateIdentifier } -${ shortCommit } ` ;
110+ } else {
111+ releaseVersion = version ;
112+ }
108113
109- if ( nightlyBuild ) {
110- releaseVersion = `0.0.0-${ currentCommit . slice ( 0 , 9 ) } ` ;
111-
112- // Bump version number in various files (package.json, gradle.properties etc)
114+ // Bump version number in various files (package.json, gradle.properties etc)
115+ // For stable, pre-release releases, we manually call bump-oss-version on release branch
116+ if ( nightlyBuild || dryRunBuild ) {
113117 if (
114- exec ( `node scripts/bump-oss-version.js --nightly ${ releaseVersion } ` ) . code
118+ exec (
119+ `node scripts/bump-oss-version.js --nightly --to-version ${ releaseVersion } ` ,
120+ ) . code
115121 ) {
116122 echo ( 'Failed to bump version number' ) ;
117123 exit ( 1 ) ;
118124 }
119- } else if ( tagsWithVersion [ 0 ] . indexOf ( '-rc' ) === - 1 ) {
120- // if first tag on this commit is non -rc then we are making a stable release
121- // '0.33.0'
122- releaseVersion = tagsWithVersion [ 0 ] . slice ( 1 ) ;
123- } else {
124- // otherwise pick last -rc tag alphabetically
125- // 0.33.0-rc2
126- releaseVersion = tagsWithVersion [ tagsWithVersion . length - 1 ] . slice ( 1 ) ;
127125}
128126
129127const buildAndroid = ( rebuildOnError ) => {
@@ -175,12 +173,29 @@ artifacts.forEach(name => {
175173 }
176174} ) ;
177175
178- // if version contains -rc, tag as prerelease
176+ if ( dryRunBuild ) {
177+ echo ( 'Skipping `npm publish` because --dry-run is set.' ) ;
178+ exit ( 0 ) ;
179+ }
180+
181+ // Running to see if this commit has been git tagged as `latest`
182+ const latestCommit = exec ( "git rev-list -n 1 'latest'" , {
183+ silent : true ,
184+ } ) . stdout . replace ( '\n' , '' ) ;
185+ const isLatest = currentCommit === latestCommit ;
186+
187+ const releaseBranch = `${ major } .${ minor } -stable` ;
188+
189+ // Set the right tag for nightly and prerelease builds
190+ // If a release is not git-tagged as `latest` we use `releaseBranch` to prevent
191+ // npm from overriding the current `latest` version tag, which it will do if no tag is set.
179192const tagFlag = nightlyBuild
180193 ? '--tag nightly'
181- : releaseVersion . indexOf ( '-rc' ) === - 1
182- ? ''
183- : '--tag next' ;
194+ : prerelease != null
195+ ? '--tag next'
196+ : isLatest
197+ ? '--tag latest'
198+ : `--tag ${ releaseBranch } ` ;
184199
185200// use otp from envvars if available
186201const otpFlag = otp ? `--otp ${ otp } ` : '' ;
@@ -192,5 +207,3 @@ if (exec(`npm publish ${tagFlag} ${otpFlag}`).code) {
192207 echo ( `Published to npm ${ releaseVersion } ` ) ;
193208 exit ( 0 ) ;
194209}
195-
196- /*eslint-enable no-undef */
0 commit comments