From ee30e613612bac0ded0709bb42e4f17d3175b222 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Mon, 10 Jul 2023 12:48:28 -0700 Subject: [PATCH] fix: add correct publish tag for backports --- .github/workflows/release.yml | 27 ++++++-- bin/release-manager.js | 4 +- bin/release-please.js | 19 +++++- lib/config.js | 7 +- lib/content/_job-release-integration.yml | 45 +++++++------ lib/content/index.js | 4 +- lib/content/release.yml | 4 +- lib/release-please/get-publish-tag.js | 13 ++++ lib/release-please/index.js | 7 +- lib/util/dependabot.js | 6 +- .../test/apply/source-snapshots.js.test.cjs | 66 ++++++++++--------- 11 files changed, 134 insertions(+), 68 deletions(-) create mode 100644 lib/release-please/get-publish-tag.js diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ae19cd6f..54495c2d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,7 +55,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - npx --offline template-oss-release-please "${{ github.ref_name }}" "${{ inputs.release-pr }}" + npx --offline template-oss-release-please --branch="${{ github.ref_name }}" --force-pr="${{ inputs.release-pr }}" --backport=false - name: Post Pull Request Comment if: steps.release.outputs.pr-number uses: actions/github-script@v6 @@ -169,7 +169,7 @@ jobs: RELEASE_COMMENT_ID: ${{ needs.release.outputs.comment-id }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - npm exec --offline -- template-oss-release-manager --lockfile=false --publish=true + npm exec --offline -- template-oss-release-manager --lockfile=false --publish=true --backport=false npm run rp-pull-request --ignore-scripts -ws -iwr --if-present - name: Commit id: commit @@ -326,18 +326,37 @@ jobs: uses: actions/checkout@v3 with: ref: ${{ fromJSON(needs.release.outputs.release).tagName }} + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" - name: Setup Node uses: actions/setup-node@v3 with: node-version: 18.x - name: Install npm@latest + run: npm i --prefer-online --no-fund --no-audit -g npm@latest + - name: npm Version + run: npm -v + - name: Set Publish Token run: | - npm i --prefer-online --no-fund --no-audit -g npm@latest npm config set '//registry.npmjs.org/:_authToken'=\${PUBLISH_TOKEN} - name: Publish env: PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }} - run: npm publish --provenance + run: | + for release in $(echo '${{ needs.release.outputs.releases }}' | jq -r '.[] | @base64'); do + function decode { + echo "$release" | base64 --decode | jq -r ".$1" + } + + PUBLISH_FLAGS="--provenance --tag=$(decode "publishTag")" + if [[ "$(decode "isWorkspace")" == "false" ]]; then + PUBLISH_FLAGS="$PUBLISH_FLAGS --workspace=$(decode "pkgName")" + fi + + npm publish $PUBLISH_FLAGS + done post-release-integration: needs: [ release, release-integration ] diff --git a/bin/release-manager.js b/bin/release-manager.js index b56695af..8b1d2947 100755 --- a/bin/release-manager.js +++ b/bin/release-manager.js @@ -4,6 +4,7 @@ const { Octokit } = require('@octokit/rest') const semver = require('semver') const mapWorkspaces = require('@npmcli/map-workspaces') const { join } = require('path') +const getPublishTag = require('../lib/release-please/get-publish-tag.js') const log = (...logs) => console.error('LOG', ...logs) @@ -127,6 +128,7 @@ const getPrReleases = async (pr) => { const prerelease = !!version.prerelease.length const tag = `${name ? `${name}-` : ''}v${rawVersion}` const workspace = workspaces[name] + const publishTag = getPublishTag({ backport: args.backport, version: rawVersion }) return { name, @@ -135,7 +137,7 @@ const getPrReleases = async (pr) => { version: rawVersion, major: version.major, url: `https://github.com/${pr.base.repo.full_name}/releases/tag/${tag}`, - flags: `${name ? `-w ${workspace}` : ''} ${prerelease ? `--tag prerelease` : ''}`.trim(), + flags: `${name ? `-w ${workspace}` : ''} --tag ${publishTag}`.trim(), } } diff --git a/bin/release-please.js b/bin/release-please.js index 6237d02b..beb7186e 100755 --- a/bin/release-please.js +++ b/bin/release-please.js @@ -4,7 +4,19 @@ const core = require('@actions/core') const main = require('../lib/release-please/index.js') const dryRun = !process.env.CI -const [branch, forcePullRequest] = process.argv.slice(2) +const args = process.argv.slice(2).reduce((acc, a) => { + const [k, v = ''] = a.replace(/^--/, '').split('=') + if (v === 'true') { + acc[k] = true + } else if (v === 'false') { + acc[k] = false + } else if (/^\d+$/.test(v)) { + acc[k] = Number.parseInt(v.trim()) + } else if (v) { + acc[k] = v.trim() + } + return acc +}, {}) const debugPr = (val) => { if (dryRun) { @@ -44,8 +56,9 @@ main({ token: process.env.GITHUB_TOKEN, repo: process.env.GITHUB_REPOSITORY, dryRun, - branch, - forcePullRequest: forcePullRequest ? +forcePullRequest : null, + branch: args.branch, + backport: args.backport, + forcePullRequest: args['force-pr'], }).then(({ pr, release, releases }) => { if (pr) { debugPr(pr) diff --git a/lib/config.js b/lib/config.js index 3e461a5c..6aa9f6f0 100644 --- a/lib/config.js +++ b/lib/config.js @@ -158,7 +158,7 @@ const getFullConfig = async ({ const branches = uniq([...pkgConfig.branches ?? [], pkgConfig.releaseBranch]).filter(Boolean) const gitBranches = await git.getBranches(rootPkg.path, branches) const currentBranch = await git.currentBranch(rootPkg.path) - const isReleaseBranch = currentBranch ? minimatch(currentBranch, pkgConfig.releaseBranch) : false + const isBackport = currentBranch ? minimatch(currentBranch, pkgConfig.releaseBranch) : false const defaultBranch = await git.defaultBranch(rootPkg.path) ?? 'main' // all derived keys @@ -180,10 +180,11 @@ const getFullConfig = async ({ isMonoPublic: isMono && !!publicPkgs.filter(p => p.path !== rootPkg.path).length, // git defaultBranch, - baseBranch: isReleaseBranch ? currentBranch : defaultBranch, + baseBranch: isBackport ? currentBranch : defaultBranch, branches: gitBranches.branches, branchPatterns: gitBranches.patterns, - isReleaseBranch, + // publish + isBackport, // dependabot dependabot: parseDependabot(pkgConfig, defaultConfig, gitBranches.branches), // repo diff --git a/lib/content/_job-release-integration.yml b/lib/content/_job-release-integration.yml index 49ade657..c2ddadd6 100644 --- a/lib/content/_job-release-integration.yml +++ b/lib/content/_job-release-integration.yml @@ -7,22 +7,27 @@ permissions: deployments: write id-token: write steps: - - name: Checkout - uses: actions/checkout@v3 - with: - ref: $\{{ fromJSON(needs.release.outputs.release).tagName }} - - name: Setup Node - uses: actions/setup-node@v3 - with: - node-version: 18.x - - name: Install npm@latest + {{> stepGit jobCheckout=(obj ref="${{ fromJSON(needs.release.outputs.release).tagName }}") }} + {{> stepNode lockfile=false }} + - name: Set Publish Token run: | - npm i --prefer-online --no-fund --no-audit -g npm@latest npm config set '//registry.npmjs.org/:_authToken'=\${PUBLISH_TOKEN} - name: Publish env: PUBLISH_TOKEN: $\{{ secrets.PUBLISH_TOKEN }} - run: npm publish --provenance + run: | + for release in $(echo '$\{{ needs.release.outputs.releases }}' | jq -r '.[] | @base64'); do + function decode { + echo "$release" | base64 --decode | jq -r ".$1" + } + + PUBLISH_FLAGS="--provenance --tag=$(decode "publishTag")" + if [[ "$(decode "isWorkspace")" == "false" ]]; then + PUBLISH_FLAGS="$PUBLISH_FLAGS --workspace=$(decode "pkgName")" + fi + + npm publish $PUBLISH_FLAGS + done {{else}} runs-on: ubuntu-latest defaults: @@ -43,15 +48,17 @@ steps: } for release in $(echo '$\{{ needs.release.outputs.releases }}' | jq -r '.[] | @base64'); do - name=$(echo "$release" | base64 --decode | jq -r .pkgName) - version=$(echo "$release" | base64 --decode | jq -r .version) - spec="$name@$version" - status=$(is_published "$spec") - if [[ "$status" -eq 1 ]]; then - echo "$spec ERROR" - EXIT_CODE=$status + function decode { + echo "$release" | base64 --decode | jq -r ".$1" + } + + PKG_SPEC=$(decode "pkgName")@$(decode "version") + + if [[ "$(is_published "$PKG_SPEC")" -eq 1 ]]; then + echo "$PKG_SPEC ERROR" + EXIT_CODE=$PKG_STATUS else - echo "$spec OK" + echo "$PKG_SPEC OK" fi done diff --git a/lib/content/index.js b/lib/content/index.js index dfd94ff1..c0fa16e5 100644 --- a/lib/content/index.js +++ b/lib/content/index.js @@ -45,7 +45,7 @@ const sharedRootAdd = (name) => ({ }, '.github/settings.yml': { file: 'settings.yml', - filter: (p) => !p.config.isReleaseBranch, + filter: (p) => !p.config.isBackport, }, }) @@ -54,7 +54,7 @@ const sharedRootRm = () => ({ filter: (p) => p.config.allPrivate, }, '.github/settings.yml': { - filter: (p) => p.config.isReleaseBranch, + filter: (p) => p.config.isBackport, }, }) diff --git a/lib/content/release.yml b/lib/content/release.yml index 976e1e90..1a2a8d92 100644 --- a/lib/content/release.yml +++ b/lib/content/release.yml @@ -33,7 +33,7 @@ jobs: env: GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }} run: | - {{ rootNpxPath }} --offline template-oss-release-please "$\{{ github.ref_name }}" "$\{{ inputs.release-pr }}" + {{ rootNpxPath }} --offline template-oss-release-please --branch="$\{{ github.ref_name }}" --force-pr="$\{{ inputs.release-pr }}" --backport={{ isBackport }} - name: Post Pull Request Comment if: steps.release.outputs.pr-number uses: actions/github-script@v6 @@ -84,7 +84,7 @@ jobs: RELEASE_COMMENT_ID: $\{{ needs.release.outputs.comment-id }} GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }} run: | - {{ rootNpmPath }} exec --offline -- template-oss-release-manager --lockfile={{ lockfile }} --publish={{ publish }} + {{ rootNpmPath }} exec --offline -- template-oss-release-manager --lockfile={{ lockfile }} --publish={{ publish }} --backport={{ isBackport }} {{ rootNpmPath }} run rp-pull-request --ignore-scripts {{~#if allFlags}} {{ allFlags }}{{else}} --if-present{{/if}} - name: Commit id: commit diff --git a/lib/release-please/get-publish-tag.js b/lib/release-please/get-publish-tag.js new file mode 100644 index 00000000..80312d8a --- /dev/null +++ b/lib/release-please/get-publish-tag.js @@ -0,0 +1,13 @@ +const semver = require('semver') + +// When the CLI is auto published, this will have to account for tagging it +// `next-MAJOR` before publishing it as `latest` +module.exports = ({ backport, version }) => { + const sVersion = semver.parse(version) + + if (backport) { + return `latest-${sVersion.major}` + } + + return sVersion.prerelease.length ? 'prerelease' : 'latest' +} diff --git a/lib/release-please/index.js b/lib/release-please/index.js index 8c8c603b..2e600e89 100644 --- a/lib/release-please/index.js +++ b/lib/release-please/index.js @@ -3,6 +3,7 @@ const { CheckpointLogger } = require('release-please/build/src/util/logger.js') const ChangelogNotes = require('./changelog.js') const Version = require('./version.js') const NodeWs = require('./node-workspace.js') +const getPublishTag = require('./get-publish-tag.js') const logger = new CheckpointLogger(true, true) RP.setLogger(logger) @@ -128,7 +129,7 @@ const touchPullRequest = async ({ octokit, owner, repo, releasePr }) => { }) } -const main = async ({ repo: fullRepo, token, dryRun, branch, forcePullRequest }) => { +const main = async ({ repo: fullRepo, token, dryRun, branch, forcePullRequest, backport }) => { if (!token) { throw new Error('Token is required') } @@ -247,6 +248,10 @@ const main = async ({ repo: fullRepo, token, dryRun, branch, forcePullRequest }) release.prNumber = releasePrNumber release.pkgName = releasePkgName + release.publishTag = getPublishTag({ backport, version: release.version }) + release.isRoot = isRoot + release.isWorkspace = !isRoot + if (isRoot) { rootRelease = release } diff --git a/lib/util/dependabot.js b/lib/util/dependabot.js index 913657f0..40a140ea 100644 --- a/lib/util/dependabot.js +++ b/lib/util/dependabot.js @@ -14,11 +14,11 @@ module.exports = (config, defaultConfig, branches) => { return branches .filter((b) => dependabot[b] !== false) .map(branch => { - const isReleaseBranch = minimatch(branch, config.releaseBranch) + const isBackport = minimatch(branch, config.releaseBranch) return { branch, - allowNames: isReleaseBranch ? [NAME] : [], - labels: isReleaseBranch ? ['Backport', branch] : [], + allowNames: isBackport ? [NAME] : [], + labels: isBackport ? ['Backport', branch] : [], ...parseDependabotConfig(defaultDependabot), ...parseDependabotConfig(dependabot), ...parseDependabotConfig(dependabot[branch]), diff --git a/tap-snapshots/test/apply/source-snapshots.js.test.cjs b/tap-snapshots/test/apply/source-snapshots.js.test.cjs index 3d851f76..a1e1b96c 100644 --- a/tap-snapshots/test/apply/source-snapshots.js.test.cjs +++ b/tap-snapshots/test/apply/source-snapshots.js.test.cjs @@ -874,7 +874,7 @@ jobs: env: GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} run: | - npx --offline template-oss-release-please "\${{ github.ref_name }}" "\${{ inputs.release-pr }}" + npx --offline template-oss-release-please --branch="\${{ github.ref_name }}" --force-pr="\${{ inputs.release-pr }}" --backport=false - name: Post Pull Request Comment if: steps.release.outputs.pr-number uses: actions/github-script@v6 @@ -988,7 +988,7 @@ jobs: RELEASE_COMMENT_ID: \${{ needs.release.outputs.comment-id }} GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} run: | - npm exec --offline -- template-oss-release-manager --lockfile=false --publish=false + npm exec --offline -- template-oss-release-manager --lockfile=false --publish=false --backport=false npm run rp-pull-request --ignore-scripts --if-present - name: Commit id: commit @@ -1159,15 +1159,17 @@ jobs: } for release in $(echo '\${{ needs.release.outputs.releases }}' | jq -r '.[] | @base64'); do - name=$(echo "$release" | base64 --decode | jq -r .pkgName) - version=$(echo "$release" | base64 --decode | jq -r .version) - spec="$name@$version" - status=$(is_published "$spec") - if [[ "$status" -eq 1 ]]; then - echo "$spec ERROR" - EXIT_CODE=$status + function decode { + echo "$release" | base64 --decode | jq -r ".$1" + } + + PKG_SPEC=$(decode "pkgName")@$(decode "version") + + if [[ "$(is_published "$PKG_SPEC")" -eq 1 ]]; then + echo "$PKG_SPEC ERROR" + EXIT_CODE=$PKG_STATUS else - echo "$spec OK" + echo "$PKG_SPEC OK" fi done @@ -2554,7 +2556,7 @@ jobs: env: GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} run: | - npx --offline template-oss-release-please "\${{ github.ref_name }}" "\${{ inputs.release-pr }}" + npx --offline template-oss-release-please --branch="\${{ github.ref_name }}" --force-pr="\${{ inputs.release-pr }}" --backport=false - name: Post Pull Request Comment if: steps.release.outputs.pr-number uses: actions/github-script@v6 @@ -2668,7 +2670,7 @@ jobs: RELEASE_COMMENT_ID: \${{ needs.release.outputs.comment-id }} GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} run: | - npm exec --offline -- template-oss-release-manager --lockfile=false --publish=false + npm exec --offline -- template-oss-release-manager --lockfile=false --publish=false --backport=false npm run rp-pull-request --ignore-scripts -ws -iwr --if-present - name: Commit id: commit @@ -2839,15 +2841,17 @@ jobs: } for release in $(echo '\${{ needs.release.outputs.releases }}' | jq -r '.[] | @base64'); do - name=$(echo "$release" | base64 --decode | jq -r .pkgName) - version=$(echo "$release" | base64 --decode | jq -r .version) - spec="$name@$version" - status=$(is_published "$spec") - if [[ "$status" -eq 1 ]]; then - echo "$spec ERROR" - EXIT_CODE=$status + function decode { + echo "$release" | base64 --decode | jq -r ".$1" + } + + PKG_SPEC=$(decode "pkgName")@$(decode "version") + + if [[ "$(is_published "$PKG_SPEC")" -eq 1 ]]; then + echo "$PKG_SPEC ERROR" + EXIT_CODE=$PKG_STATUS else - echo "$spec OK" + echo "$PKG_SPEC OK" fi done @@ -4086,7 +4090,7 @@ jobs: env: GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} run: | - npx --offline template-oss-release-please "\${{ github.ref_name }}" "\${{ inputs.release-pr }}" + npx --offline template-oss-release-please --branch="\${{ github.ref_name }}" --force-pr="\${{ inputs.release-pr }}" --backport=false - name: Post Pull Request Comment if: steps.release.outputs.pr-number uses: actions/github-script@v6 @@ -4200,7 +4204,7 @@ jobs: RELEASE_COMMENT_ID: \${{ needs.release.outputs.comment-id }} GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} run: | - npm exec --offline -- template-oss-release-manager --lockfile=false --publish=false + npm exec --offline -- template-oss-release-manager --lockfile=false --publish=false --backport=false npm run rp-pull-request --ignore-scripts -ws -iwr --if-present - name: Commit id: commit @@ -4371,15 +4375,17 @@ jobs: } for release in $(echo '\${{ needs.release.outputs.releases }}' | jq -r '.[] | @base64'); do - name=$(echo "$release" | base64 --decode | jq -r .pkgName) - version=$(echo "$release" | base64 --decode | jq -r .version) - spec="$name@$version" - status=$(is_published "$spec") - if [[ "$status" -eq 1 ]]; then - echo "$spec ERROR" - EXIT_CODE=$status + function decode { + echo "$release" | base64 --decode | jq -r ".$1" + } + + PKG_SPEC=$(decode "pkgName")@$(decode "version") + + if [[ "$(is_published "$PKG_SPEC")" -eq 1 ]]; then + echo "$PKG_SPEC ERROR" + EXIT_CODE=$PKG_STATUS else - echo "$spec OK" + echo "$PKG_SPEC OK" fi done