Skip to content

Commit a2b1ccf

Browse files
committed
Publish prereleases through trusted publish workflow
The separate rc workflow validated correctly but npm rejected its publish because trusted publishing is scoped to the existing publish workflow. Folding rc routing into publish.yml keeps the special rc path while reusing the workflow identity npm already trusts. Constraint: RC must publish with dist-tag rc and must not advance latest Rejected: Keep separate rc-release workflow | npm trusted publishing is workflow-scoped and the new workflow path was not authorized Rejected: Require local or repo NPM_TOKEN | existing release setup already uses trusted publishing without a token Confidence: high Scope-risk: narrow Tested: npm run check; npm pack --dry-run with package-content verification; YAML parse for CI/publish workflows; prettier --check .github/workflows/*.yml Not-tested: Successful publish after retag; requires GitHub Actions rerun
1 parent 9bfdf6c commit a2b1ccf

2 files changed

Lines changed: 87 additions & 141 deletions

File tree

.github/workflows/publish.yml

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,104 @@ on:
44
push:
55
tags: ["v*"]
66

7+
concurrency:
8+
group: publish-${{ github.ref_name }}
9+
cancel-in-progress: false
10+
711
jobs:
812
publish:
9-
if: ${{ !contains(github.ref_name, '-') }}
13+
name: Validate and publish
1014
runs-on: ubuntu-latest
1115
permissions:
1216
contents: read
1317
id-token: write
18+
env:
19+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
1420
steps:
1521
- uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
1624
- uses: actions/setup-node@v4
1725
with:
1826
node-version: 22
1927
cache: npm
2028
registry-url: https://registry.npmjs.org
2129
- run: npm ci
22-
- run: npm run build
23-
- run: npx vitest run
24-
- run: npm publish --provenance --access public
30+
- name: Verify tag and select npm dist-tag
31+
run: |
32+
set -euo pipefail
33+
NAME=$(node -p "require('./package.json').name")
34+
VERSION=$(node -p "require('./package.json').version")
35+
36+
if [[ "$GITHUB_REF_TYPE" != "tag" ]]; then
37+
echo "Publish must run from a git tag, got ref type: $GITHUB_REF_TYPE" >&2
38+
exit 1
39+
fi
40+
41+
if [[ "$GITHUB_REF_NAME" != "v$VERSION" ]]; then
42+
echo "Tag/version mismatch: tag=$GITHUB_REF_NAME package=v$VERSION" >&2
43+
exit 1
44+
fi
45+
46+
if [[ "$VERSION" == *"-rc."* ]]; then
47+
DIST_TAG=rc
48+
elif [[ "$VERSION" == *"-"* ]]; then
49+
DIST_TAG=next
50+
else
51+
DIST_TAG=latest
52+
fi
53+
54+
echo "PACKAGE_NAME=$NAME" >> "$GITHUB_ENV"
55+
echo "PACKAGE_VERSION=$VERSION" >> "$GITHUB_ENV"
56+
echo "NPM_DIST_TAG=$DIST_TAG" >> "$GITHUB_ENV"
57+
echo "Publishing $NAME@$VERSION with npm dist-tag '$DIST_TAG'"
58+
- name: Verify project
59+
run: |
60+
set -euo pipefail
61+
npm run check
62+
npm test
63+
npm run build
64+
npm audit --omit=dev
65+
npm audit
66+
- name: Verify npm package contents
67+
run: |
68+
set -euo pipefail
69+
PACK_JSON="$RUNNER_TEMP/npm-pack.json"
70+
npm pack --dry-run --json > "$PACK_JSON"
71+
node - "$PACK_JSON" <<'NODE'
72+
const fs = require('node:fs')
73+
const [pack] = JSON.parse(fs.readFileSync(process.argv[2], 'utf8'))
74+
const paths = pack.files.map((file) => file.path)
75+
const required = [
76+
'README.md',
77+
'LICENSE',
78+
'dist/packages/cli/index.js',
79+
'docs/migrations/2.0.0.md',
80+
]
81+
const forbidden = paths.filter(
82+
(path) => /(^|\/)__tests__(\/|$)/.test(path) || /\.test\.(js|d\.ts)$/.test(path),
83+
)
84+
const missing = required.filter((path) => !paths.includes(path))
85+
if (missing.length > 0 || forbidden.length > 0) {
86+
if (missing.length > 0) console.error(`Missing package files: ${missing.join(', ')}`)
87+
if (forbidden.length > 0) console.error(`Forbidden test files in package: ${forbidden.join(', ')}`)
88+
process.exit(1)
89+
}
90+
console.log(`Pack OK: ${pack.name}@${pack.version}, ${pack.entryCount} files, ${pack.size} bytes`)
91+
NODE
92+
- name: Publish to npm
93+
run: |
94+
set -euo pipefail
95+
if [[ -n "${NPM_TOKEN:-}" ]]; then
96+
export NODE_AUTH_TOKEN="$NPM_TOKEN"
97+
else
98+
unset NODE_AUTH_TOKEN
99+
echo "NPM_TOKEN secret is not set; relying on npm trusted publishing/OIDC." >&2
100+
fi
101+
102+
npm publish --provenance --access public --tag "$NPM_DIST_TAG"
103+
- name: Verify published package
104+
run: |
105+
set -euo pipefail
106+
npm view "$PACKAGE_NAME@$PACKAGE_VERSION" version --json
107+
npm view "$PACKAGE_NAME" dist-tags --json

.github/workflows/rc-release.yml

Lines changed: 0 additions & 137 deletions
This file was deleted.

0 commit comments

Comments
 (0)