diff --git a/.github/actions/publish-npm/action.yml b/.github/actions/publish-npm/action.yml index 27886876..8904e0e2 100644 --- a/.github/actions/publish-npm/action.yml +++ b/.github/actions/publish-npm/action.yml @@ -70,6 +70,13 @@ runs: shell: bash run: node scripts/verify-android-so.js + # The release tag is the version: no version-bump commit precedes a + # release, so write it into package.json and oh-package.json5 before the + # HAR build and npm publish read them. + - name: Stamp the release version + shell: bash + run: node scripts/stamp-release-version.js + - name: Build Harmony HAR if: inputs.harmony-har == 'build' shell: bash @@ -98,10 +105,6 @@ runs: shell: bash run: test -f harmony/pushy.har - - name: Verify release tag matches package version - shell: bash - run: node scripts/check-release-version.js - - name: Verify publish file list shell: bash run: node scripts/check-packlist.js --release diff --git a/harmony/pushy/src/README.md b/harmony/pushy/src/README.md index d307bfdd..5210a5d7 100644 --- a/harmony/pushy/src/README.md +++ b/harmony/pushy/src/README.md @@ -66,9 +66,9 @@ so a debug rebuild does not look like a new binary. Add the generated file to ## Versioning -`oh-package.json5` `version` mirrors the npm package version; -`scripts/build-harmony-har.js` rewrites it before `assembleHar` and -`scripts/check-release-version.js` asserts the committed value matches. +`oh-package.json5` `version` mirrors the npm package version: the publish +workflow writes the release tag's version into both (`scripts/stamp-release-version.js`), +and `scripts/build-harmony-har.js` syncs it from `package.json` before `assembleHar`. This file is packaged with the npm module (`harmony/pushy/src/`) so it is available next to the sources in `node_modules/react-native-update`. diff --git a/scripts/build-harmony-har.js b/scripts/build-harmony-har.js index 22621092..496ef9f5 100644 --- a/scripts/build-harmony-har.js +++ b/scripts/build-harmony-har.js @@ -157,7 +157,7 @@ function buildHar() { // The HAR carries its own version in oh-package.json5. Consumers' // oh-package-lock.json5 and diagnostics can only tell installs apart when it // equals the npm version, so rewrite it from package.json before assembleHar -// (scripts/check-release-version.js keeps the committed value honest). +// (scripts/stamp-release-version.js writes both from the release tag). function syncOhPackageVersion() { const packageJsonPath = path.join(projectRoot, 'package.json'); const ohPackagePath = path.join(harmonyModuleDir, 'oh-package.json5'); @@ -166,7 +166,7 @@ function syncOhPackageVersion() { fail('package.json has no version to write into oh-package.json5'); } const content = fs.readFileSync(ohPackagePath, 'utf8'); - // JSON5 allows the key bare or quoted (check-release-version.js matches + // JSON5 allows the key bare or quoted (stamp-release-version.js matches // the same shapes). const versionLine = /^(\s*(?:"version"|'version'|version)\s*:\s*)(['"])([^'"]*)\2(\s*,?)/m; diff --git a/scripts/check-release-version.js b/scripts/check-release-version.js deleted file mode 100644 index 580d22a3..00000000 --- a/scripts/check-release-version.js +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env node -// The release tag (vX.Y.Z) must be the package.json version being published: -// a mismatch means the tag points at the wrong commit or the version bump -// was forgotten, and npm would happily publish under the stale number. -const pkg = require('../package.json'); -const tag = process.env.RELEASE_VERSION || ''; -if (!tag) { - console.error('check-release-version: RELEASE_VERSION is not set'); - process.exit(1); -} -const expected = `v${pkg.version}`; -if (tag !== expected && tag !== pkg.version) { - console.error( - `check-release-version: tag ${tag} does not match package.json version ${pkg.version}` - ); - process.exit(1); -} - -// The Harmony HAR carries its own version (oh-package.json5); consumers' -// oh-package-lock.json5 and diagnostics can only tell installs apart when it -// tracks package.json. scripts/build-harmony-har.js rewrites it before -// assembleHar, and this check keeps the committed value from drifting. -const fs = require('fs'); -const path = require('path'); -const ohPackagePath = path.join(__dirname, '..', 'harmony/pushy/oh-package.json5'); -const ohPackage = fs.readFileSync(ohPackagePath, 'utf8'); -// JSON5 allows the key bare or quoted; the regex is shared in spirit with -// syncOhPackageVersion in scripts/build-harmony-har.js. -const ohVersion = (ohPackage.match( - /^\s*(?:"version"|'version'|version)\s*:\s*['"]([^'"]+)['"]/m -) || [])[1]; -if (ohVersion !== pkg.version) { - console.error( - `check-release-version: harmony/pushy/oh-package.json5 version ${ohVersion} does not match package.json version ${pkg.version}` - ); - process.exit(1); -} -console.log( - `check-release-version: ${tag} matches package.json and oh-package.json5 ${pkg.version}` -); diff --git a/scripts/stamp-release-version.js b/scripts/stamp-release-version.js new file mode 100644 index 00000000..6d841b65 --- /dev/null +++ b/scripts/stamp-release-version.js @@ -0,0 +1,50 @@ +#!/usr/bin/env node +// Releases are cut from the GitHub Release tag alone (vX.Y.Z on a green +// master commit, no version-bump commit), so the version is written into the +// package here, before the HAR build and npm publish: +// - package.json: the version npm publishes and the podspec reads. +// - harmony/pushy/oh-package.json5: the HAR's own version. Consumers' +// oh-package-lock.json5 and diagnostics can only tell installs apart when it +// equals the npm version (scripts/build-harmony-har.js syncs it from +// package.json again before assembleHar). +const fs = require('fs'); +const path = require('path'); + +const tag = process.env.RELEASE_VERSION || ''; +const version = tag.replace(/^v/, ''); +// semver: X.Y.Z with an optional prerelease (10.62.0-beta.1). +if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/.test(version)) { + console.error( + `stamp-release-version: release tag '${tag}' is not vX.Y.Z or vX.Y.Z-prerelease` + ); + process.exit(1); +} + +const root = path.join(__dirname, '..'); +const packageJsonPath = path.join(root, 'package.json'); +const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); +pkg.version = version; +fs.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\n`); + +const ohPackagePath = path.join(root, 'harmony/pushy/oh-package.json5'); +const ohPackage = fs.readFileSync(ohPackagePath, 'utf8'); +// JSON5 allows the key bare or quoted (syncOhPackageVersion in +// scripts/build-harmony-har.js matches the same shapes). +const versionLine = + /^(\s*(?:"version"|'version'|version)\s*:\s*)(['"])([^'"]*)\2(\s*,?)/m; +if (!versionLine.test(ohPackage)) { + console.error( + 'stamp-release-version: no version field in harmony/pushy/oh-package.json5' + ); + process.exit(1); +} +fs.writeFileSync( + ohPackagePath, + ohPackage.replace( + versionLine, + (_, prefix, quote, __, suffix) => `${prefix}${quote}${version}${quote}${suffix}` + ) +); +console.log( + `stamp-release-version: package.json and oh-package.json5 set to ${version} from ${tag}` +);