From e63487583c87c08f95084763bc9e7ec426bdd6ec Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Thu, 3 Jun 2021 12:20:24 -0400 Subject: [PATCH] Prepare semver (`@latest`) releases in CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that we track package versions in source, `@latest` builds should be fully reproducible for a given commit. We can prepare the packages in CI and store them as artifacts, the same way we do for `@next` and `@experimental`. Eventually this can replace the interactive script that we currently use to swap out the version numbers. The other nice thing about this approach is that we can run tests in CI to verify that the packages are releasable, instead of waiting until right before publish. I named the output directory `oss-stable-semver`, to distinguish from the `@next` prereleases that are located at `oss-stable`. I don't love this naming. I'd prefer to use the name of the corresponding npm dist tag. I'll do that in a follow-up, though, since the `oss-stable` name is referenced in a handful of places. Current naming (after this PR): - `oss-experimental` → `@experimental` - `oss-stable` → `@next` - `oss-stable-semver` → `@latest` Proposed naming (not yet implemented, requires more work): - `oss-experimental` → `@experimental` - `oss-next` → `@next` - `oss-latest` → `@latest` --- scripts/rollup/build-all-release-channels.js | 36 +++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/scripts/rollup/build-all-release-channels.js b/scripts/rollup/build-all-release-channels.js index 3cbd73565da16..0346996ac4e18 100644 --- a/scripts/rollup/build-all-release-channels.js +++ b/scripts/rollup/build-all-release-channels.js @@ -98,9 +98,29 @@ function processStable(buildDir) { updatePackageVersions( buildDir + '/node_modules', versionsMap, - defaultVersionIfNotFound + defaultVersionIfNotFound, + true ); fs.renameSync(buildDir + '/node_modules', buildDir + '/oss-stable'); + + // Identical to `oss-stable` but with real, semver versions. This is what + // will get published to @latest. + spawnSync('cp', [ + '-r', + buildDir + '/oss-stable', + buildDir + '/oss-stable-semver', + ]); + const semverVersionsMap = new Map(); + for (const moduleName in stablePackages) { + const version = stablePackages[moduleName]; + semverVersionsMap.set(moduleName, version); + } + updatePackageVersions( + buildDir + '/oss-stable-semver', + semverVersionsMap, + defaultVersionIfNotFound, + false + ); } if (fs.existsSync(buildDir + '/facebook-www')) { @@ -131,7 +151,8 @@ function processExperimental(buildDir, version) { updatePackageVersions( buildDir + '/node_modules', versionsMap, - defaultVersionIfNotFound + defaultVersionIfNotFound, + true ); fs.renameSync(buildDir + '/node_modules', buildDir + '/oss-experimental'); } @@ -179,7 +200,8 @@ function crossDeviceRenameSync(source, destination) { function updatePackageVersions( modulesDir, versionsMap, - defaultVersionIfNotFound + defaultVersionIfNotFound, + pinToExactVersion ) { for (const moduleName of fs.readdirSync(modulesDir)) { let version = versionsMap.get(moduleName); @@ -199,14 +221,18 @@ function updatePackageVersions( if (packageInfo.dependencies) { for (const dep of Object.keys(packageInfo.dependencies)) { if (versionsMap.has(dep)) { - packageInfo.dependencies[dep] = version; + packageInfo.dependencies[dep] = pinToExactVersion + ? version + : '^' + version; } } } if (packageInfo.peerDependencies) { for (const dep of Object.keys(packageInfo.peerDependencies)) { if (versionsMap.has(dep)) { - packageInfo.peerDependencies[dep] = version; + packageInfo.peerDependencies[dep] = pinToExactVersion + ? version + : '^' + version; } } }