Skip to content

Commit df3dd27

Browse files
mikolalysenkoclaude
andcommitted
ci(release): adopt npm staged publishing via OIDC
Switches the npm-publish job to `npm stage publish` so the GitHub Actions workflow uploads tarballs to npm's staging queue. A maintainer then approves each staged version with 2FA from npmjs.com or the npm CLI before it becomes installable. The previous direct-publish flow was failing with `OIDC permission denied for this action` against npm's post-2026-05-20 trusted-publisher rules, which require the allowed-action checkbox(es) to be explicit. Each of the 15 packages needs a trusted publisher configured on npmjs.com (SocketDev/socket-patch → release.yml) with both `npm publish` and `npm stage publish` allowed; the workflow uses stage-publish for every release. Workflow changes: - Bump actions/setup-node to v6.4.0 + package-manager-cache: false (eliminates the always-auth deprecation warning emitted by v4). - Replace `npm publish --provenance --access public` with `npm stage publish --access public`. OIDC trusted publishing emits provenance automatically, so --provenance is now redundant. - Collect successfully staged package names and write a step summary with org-dashboard and per-package review links, plus a ::notice:: pointing at the staged-packages dashboard, so maintainers can click straight from the workflow run page into the approval UI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c20619b commit df3dd27

1 file changed

Lines changed: 60 additions & 14 deletions

File tree

.github/workflows/release.yml

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,13 @@ jobs:
279279
merge-multiple: true
280280

281281
- name: Setup Node.js
282-
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
282+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
283283
with:
284284
node-version: '22.22.1'
285285
registry-url: 'https://registry.npmjs.org'
286+
package-manager-cache: false
286287

287-
- name: Update npm for trusted publishing
288+
- name: Update npm for staged publishing
288289
run: npm install -g npm@11.15.0
289290

290291
- name: Stage binaries into platform packages
@@ -317,34 +318,79 @@ jobs:
317318
stage_win socket-patch-i686-pc-windows-msvc npm/socket-patch-win32-ia32
318319
stage_win socket-patch-aarch64-pc-windows-msvc npm/socket-patch-win32-arm64
319320
320-
- name: Publish platform packages
321+
- name: Stage-publish platform packages
322+
id: stage-platform
321323
run: |
324+
: > "${RUNNER_TEMP}/staged-packages.txt"
322325
for pkg_dir in npm/socket-patch-*/; do
323-
echo "Publishing ${pkg_dir}..."
324-
npm publish "./${pkg_dir}" --provenance --access public || {
325-
if npm view "@socketsecurity/$(basename "$pkg_dir")@${{ needs.version.outputs.version }}" version >/dev/null 2>&1; then
326+
pkg_name="@socketsecurity/$(basename "$pkg_dir")"
327+
echo "Staging ${pkg_name}..."
328+
if npm stage publish "./${pkg_dir}" --access public; then
329+
echo "$pkg_name" >> "${RUNNER_TEMP}/staged-packages.txt"
330+
else
331+
if npm view "${pkg_name}@${{ needs.version.outputs.version }}" version >/dev/null 2>&1; then
326332
echo "Already published, skipping."
327333
else
328334
exit 1
329335
fi
330-
}
336+
fi
331337
done
332338
333-
- name: Wait for npm registry propagation
334-
run: sleep 30
335-
336339
- name: Copy README for npm package
337340
run: cp README.md npm/socket-patch/README.md
338341

339-
- name: Publish main package
342+
- name: Stage-publish main package
340343
run: |
341-
npm publish ./npm/socket-patch --provenance --access public || {
342-
if npm view "@socketsecurity/socket-patch@${{ needs.version.outputs.version }}" version >/dev/null 2>&1; then
344+
pkg_name="@socketsecurity/socket-patch"
345+
if npm stage publish ./npm/socket-patch --access public; then
346+
echo "$pkg_name" >> "${RUNNER_TEMP}/staged-packages.txt"
347+
else
348+
if npm view "${pkg_name}@${{ needs.version.outputs.version }}" version >/dev/null 2>&1; then
343349
echo "Already published, skipping."
344350
else
345351
exit 1
346352
fi
347-
}
353+
fi
354+
355+
- name: Summarize staged versions awaiting approval
356+
if: always()
357+
run: |
358+
STAGED_FILE="${RUNNER_TEMP}/staged-packages.txt"
359+
if [ ! -s "$STAGED_FILE" ]; then
360+
echo "No packages staged this run (all versions already published or publish step failed before staging)." >> "$GITHUB_STEP_SUMMARY"
361+
exit 0
362+
fi
363+
VERSION="${{ needs.version.outputs.version }}"
364+
{
365+
echo "## npm staged versions awaiting approval"
366+
echo ""
367+
echo "Version \`${VERSION}\` is staged on npm. A maintainer must approve each package with 2FA before it becomes installable."
368+
echo ""
369+
echo "**Approve platform packages first**, then the main \`@socketsecurity/socket-patch\` package, so install-time \`optionalDependencies\` resolution sees the platform binaries already live."
370+
echo ""
371+
echo "**Approve from the web** (signs in + 2FA prompts inline):"
372+
echo ""
373+
echo "- Org dashboard: <https://www.npmjs.com/settings/socketsecurity/staged-packages>"
374+
echo ""
375+
echo "Per-package review pages:"
376+
echo ""
377+
while IFS= read -r pkg_name; do
378+
[ -z "$pkg_name" ] && continue
379+
# npmjs.com renders staged versions inline on the package page;
380+
# the access page exposes the "Staged" tab and the approve button.
381+
echo "- \`${pkg_name}@${VERSION}\` — <https://www.npmjs.com/package/${pkg_name}/access>"
382+
done < "$STAGED_FILE"
383+
echo ""
384+
echo "**Approve from the CLI** (requires \`npm@11.15.0+\` locally, signed in to the \`socketsecurity\` org with 2FA):"
385+
echo ""
386+
echo '```sh'
387+
echo "npm stage list"
388+
echo "# then, for each stage id printed above (platform packages first, main package last):"
389+
echo "npm stage approve <stage-id>"
390+
echo '```'
391+
} >> "$GITHUB_STEP_SUMMARY"
392+
# Mirror to step log so it's also visible in the raw run output.
393+
echo "::notice title=npm staged versions awaiting approval::Review and approve at https://www.npmjs.com/settings/socketsecurity/staged-packages"
348394
349395
pypi-publish:
350396
needs: [version, build, tag]

0 commit comments

Comments
 (0)