ci(release): per-platform idempotent npm publish + spam-filter retry

The previous 'napi prepublish -t npm' step was atomic — one failure killed
the whole step, and on retry it tried to republish already-uploaded
versions which 403'd. v0.1.2 left 3 of 4 platform packages and the wasm
package on npm but the main 'wickra' package and 'wickra-win32-x64-msvc'
never got out.

Replace it with a small bash loop that:

- Walks every npm/<platform>/ directory.
- Skips the publish if 'npm view <pkg>@<version>' confirms the version
  is already on the registry (idempotent re-runs).
- Tolerates per-package failures (sets rc but always returns 0 from the
  helper) so spam-filter blocks on one platform don't take down the
  others. A 30-second retry handles transient rate-limit spam blocks.
- Publishes the main 'wickra' meta-package as a separate step with the
  same skip-existing guard.

Same publishing semantics, just deconstructed into individually
recoverable steps.
This commit is contained in:
kingchenc
2026-05-21 21:34:33 +02:00
parent 1aa7df1c97
commit ccf2b46482
+45 -5
View File
@@ -188,18 +188,58 @@ jobs:
working-directory: bindings/node
run: npx napi artifacts --dir artifacts
- name: Prepublish platform packages to npm
# Publish each platform package individually so one failure doesn't kill
# the others. Skip versions that are already on npm. Tolerate spam-filter
# 403s with a one-time retry after a short delay (spam detection is
# often rate-limit-based and clears on the next request).
- name: Publish platform packages (idempotent)
working-directory: bindings/node
run: npx napi prepublish -t npm --skip-gh-release
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
set +e
version=$(node -p "require('./package.json').version")
publish_dir() {
local dir=$1
local pkg=$(basename "$dir")
local pkgname="wickra-$pkg"
local existing
existing=$(npm view "$pkgname@$version" version 2>/dev/null)
if [ "$existing" = "$version" ]; then
echo "::notice::skip $pkgname@$version (already on npm)"
return 0
fi
echo "::group::publish $pkgname@$version"
(cd "$dir" && npm publish --access public)
local rc=$?
echo "::endgroup::"
if [ "$rc" -ne 0 ]; then
echo "::warning::first attempt of $pkgname failed (rc=$rc); retrying after 30s"
sleep 30
(cd "$dir" && npm publish --access public)
rc=$?
fi
if [ "$rc" -ne 0 ]; then
echo "::warning::$pkgname could not be published; the main package will skip the missing optional dep"
fi
return 0
}
for dir in npm/*/; do
publish_dir "$dir"
done
- name: Publish main package to npm
- name: Publish main package to npm (idempotent)
working-directory: bindings/node
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
version=$(node -p "require('./package.json').version")
existing=$(npm view "wickra@$version" version 2>/dev/null)
if [ "$existing" = "$version" ]; then
echo "::notice::skip wickra@$version (already on npm)"
else
npm publish --access public
fi
# --------------------------------------------------------------------------
# WASM: wasm-pack build + npm publish (as `wickra-wasm`)