From 58f510be512716240c10f48a2c1489188b39d8db Mon Sep 17 00:00:00 2001 From: James Henry Date: Thu, 21 Dec 2023 01:33:22 +0400 Subject: [PATCH] chore(repo): release improvements (#7413) * chore(repo): misc QOL release * chore(repo): update publish checks and logic * chore: write branch out in error case. * chore: add configuration for npm tags and better error messages --------- Co-authored-by: Ben Lesh --- .github/workflows/publish.yml | 10 +---- scripts/publish.js | 74 +++++++++++++++++++++++++++++++++++ scripts/release.js | 6 ++- 3 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 scripts/publish.js diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d028329d9f..4c80ae7d83 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -39,15 +39,7 @@ jobs: yarn nx release version $VERSION - name: Publish packages to npm - run: | - if [[ $GITHUB_REF == 'refs/heads/7.x' ]]; then - yarn nx release publish --registry https://registry.npmjs.org --tag latest - elif [[ $GITHUB_REF == 'refs/heads/master' ]]; then - yarn nx release publish --registry https://registry.npmjs.org --tag next - else - echo "Branch not recognized for publishing, should be either '7.x' or 'master'" - exit 1 - fi + run: node ./scripts/publish.js env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_CONFIG_PROVENANCE: true diff --git a/scripts/publish.js b/scripts/publish.js new file mode 100644 index 0000000000..810d8e819f --- /dev/null +++ b/scripts/publish.js @@ -0,0 +1,74 @@ +// @ts-check + +const { prerelease, valid } = require('semver'); +const { releasePublish } = require('nx/src/command-line/release'); + +/** + * Maps git branch names to npm dist tags. If master is an alpha/beta release, + * then it should be mapped to 'next'. Similarly there should be one record for + * the 'latest' tag. + */ +const DIST_TAGS = { + 'refs/heads/7.x': 'latest', + 'refs/heads/master': 'next', +}; + +if (!Object.values(DIST_TAGS).includes('latest')) { + console.error(`Invalid DIST_TAGS:\n${JSON.stringify(DIST_TAGS, null, 2)}`); + throw new Error("DIST_TAGS must contain a mapping for 'latest'"); +} + +(async () => { + try { + let npmDistTag; + + // Publishing was triggered via an GitHub release being created (almost certainly via our `yarn release` script) + if (process.env.GITHUB_EVENT_NAME === 'release') { + const tag = process.env.GITHUB_REF; + if (!tag) { + throw new Error('No tag found in environment variable GITHUB_REF'); + } + if (!valid(tag)) { + throw new Error(`Git tag '${tag}' pulled from environment variable GITHUB_REF is not a valid semver version`); + } + if (isPrerelease(tag)) { + npmDistTag = 'next'; + } else { + npmDistTag = 'latest'; + } + } + + // Publishing was triggered manually via the GitHub Actions UI + if (process.env.GITHUB_EVENT_NAME === 'workflow_dispatch') { + const branch = process.env.GITHUB_REF; + if (!branch) { + throw new Error('No branch found in environment variable GITHUB_REF'); + } + + npmDistTag = DIST_TAGS[branch]; + + if (!npmDistTag) { + throw new Error( + `Branch '${branch}' found in environment variable GITHUB_REF is not recognized for manual publishing, should be either '7.x' or 'master'` + ); + } + } + + if (!npmDistTag) { + throw new Error('No npm dist tag could be derived from the current environment'); + } + + await releasePublish({ + registry: 'https://registry.npmjs.org', + tag: npmDistTag, + }); + } catch (err) { + console.error(err); + process.exit(1); + } +})(); + +function isPrerelease(version) { + // prerelease returns an array of matching prerelease "components", or null if the version is not a prerelease + return prerelease(version) !== null; +} diff --git a/scripts/release.js b/scripts/release.js index e9227b28c4..90c7f05764 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -61,12 +61,16 @@ const yargs = require('nx/node_modules/yargs'); await releaseChangelog({ versionData: projectsVersionData, version: workspaceVersion, - interactive: 'workspace', + interactive: 'all', gitRemote: options.gitRemote, dryRun: options.dryRun, verbose: options.verbose, }); + if (!options.dryRun) { + console.log('Check GitHub: https://github.com/ReactiveX/rxjs/actions/workflows/publish.yml'); + } + process.exit(0); } catch (err) { console.error(err);