From a09ee556210466201eca63f9479a6d8538652dfb Mon Sep 17 00:00:00 2001 From: Cristian Duciuc Date: Mon, 9 Nov 2026 13:14:59 -0500 Subject: [PATCH 1/2] fix(release): protect publishing and preserve queued releases --- .github/workflows/release.yml | 2 ++ scripts/release.mjs | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0fb4490..4c83f3b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,10 +12,12 @@ permissions: concurrency: group: npm-release cancel-in-progress: false + queue: max jobs: publish: name: Publish to npm + environment: npm-publish runs-on: ubuntu-latest timeout-minutes: 15 diff --git a/scripts/release.mjs b/scripts/release.mjs index c252993..c40290a 100644 --- a/scripts/release.mjs +++ b/scripts/release.mjs @@ -76,17 +76,17 @@ function prepareRelease(args) { writeFileSync(packagePath, JSON.stringify(manifest, null, 2) + '\n'); runReleaseChecks(); run('git', ['add', 'package.json']); - run('git', ['commit', '-m', 'chore(release): ' + tag]); + run('git', ['commit', '-m', 'chore(release): bump version to ' + tag]); committed = true; if (push) { - run('git', ['push', '--set-upstream', remote, branch]); + run('git', ['push', '--no-follow-tags', '--set-upstream', remote, branch]); console.log( 'Open a pull request: https://github.com/worklouder/input-kit/compare/' + releaseBranch + '...' + encodeURIComponent(branch) + '?expand=1', ); } else { - console.log('Release branch created locally. Push it with: git push -u origin ' + branch); + console.log('Release branch created locally. Push it with: git push --no-follow-tags -u origin ' + branch); } } catch (error) { if (!committed) { @@ -121,10 +121,10 @@ function publishRelease(args) { run('git', ['tag', '--annotate', tag, '--message', tag]); if (push) { - run('git', ['push', remote, tag]); - console.log('Pushed ' + tag + '. The release workflow will publish it to npm.'); + run('git', ['push', '--no-follow-tags', remote, 'tag', tag]); + console.log('Pushed ' + tag + '. The release workflow requires approval before publishing to npm.'); } else { - console.log('Created local tag ' + tag + '. Push it with: git push origin ' + tag); + console.log('Created local tag ' + tag + '. Push it with: git push --no-follow-tags origin tag ' + tag); } } From 75f2797ba1d2b0d3724384368d22d0d01f286001 Mon Sep 17 00:00:00 2001 From: Cristian Duciuc Date: Mon, 9 Nov 2026 14:45:50 -0500 Subject: [PATCH 2/2] fix(release): isolate npm publishing from build --- .github/workflows/release.yml | 62 +++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4c83f3b..df83846 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,7 +7,6 @@ on: permissions: contents: read - id-token: write concurrency: group: npm-release @@ -15,9 +14,8 @@ concurrency: queue: max jobs: - publish: - name: Publish to npm - environment: npm-publish + build: + name: Verify and pack release runs-on: ubuntu-latest timeout-minutes: 15 @@ -27,29 +25,65 @@ jobs: with: fetch-depth: 0 + - name: Verify release commit is on main + run: git merge-base --is-ancestor "$GITHUB_SHA" origin/main + - name: Set up Node.js uses: actions/setup-node@v6 with: node-version: 26 - registry-url: https://registry.npmjs.org package-manager-cache: false - - name: Install trusted-publishing npm version - run: npm install --global "npm@^11.5.1" - - name: Install Yarn run: npm install --global yarn@1.22.22 + - name: Verify release tag + run: yarn release verify-tag "$GITHUB_REF_NAME" + - name: Install dependencies run: yarn install --frozen-lockfile --non-interactive - - name: Verify release tag and branch - run: | - yarn release verify-tag "$GITHUB_REF_NAME" - git merge-base --is-ancestor "$GITHUB_SHA" origin/main - - name: Build and test run: yarn test + - name: Pack package + run: | + tarball=$(npm pack --ignore-scripts --pack-destination "$RUNNER_TEMP") + mv "$RUNNER_TEMP/$tarball" "$RUNNER_TEMP/input-kit.tgz" + + - name: Upload release tarball + uses: actions/upload-artifact@v7 + with: + name: npm-package + path: ${{ runner.temp }}/input-kit.tgz + if-no-files-found: error + overwrite: true + + publish: + name: Publish to npm + needs: build + environment: npm-publish + permissions: + id-token: write + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - name: Set up Node.js + uses: actions/setup-node@v6 + with: + node-version: 26 + registry-url: https://registry.npmjs.org + package-manager-cache: false + + - name: Install trusted-publishing npm version + run: npm install --global "npm@^11.5.1" + + - name: Download release tarball + uses: actions/download-artifact@v8 + with: + name: npm-package + path: ${{ runner.temp }}/npm-package + - name: Publish package - run: npm publish --access public --provenance + run: npm publish "$RUNNER_TEMP/npm-package/input-kit.tgz" --access public --provenance --ignore-scripts