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:
@@ -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`)
|
||||
|
||||
Reference in New Issue
Block a user