Repository navigation
Description
Context
While debugging the v0.3.2 publish pipeline today, I discovered that every intermediate publish step in .github/workflows/publish.yml uses || true to tolerate failures:
- name: Publish @aictrl/util
run: bun pm pack && npm publish *.tgz --access public --provenance || trueThe intent is to tolerate "version already published" errors on re-runs (e.g. a workflow restart after a partial success). But || true is a big hammer — it also swallows authentication failures, network errors, and every other reason npm publish might fail.
Why it matters
During #48's corepack experiment, npm --version reported 10.9.7 (the runner's bundled npm, not the corepack-"activated" 11.5.2), which pre-dates OIDC trusted publishing support. Every npm publish in the workflow failed with ENEEDAUTH, but:
@aictrl/utilpublish: ENEEDAUTH →|| truemasks → step shows ✓@aictrl/pluginpublish: ENEEDAUTH →|| truemasks → step shows ✓@aictrl/sdkpublish: ENEEDAUTH →|| truemasks → step shows ✓- platform binary loop (11 packages): ENEEDAUTH each →
|| truemasks → step shows ✓ @aictrl/clipublish (no|| true): ENEEDAUTH → step finally fails
Net effect: 14 publishes failed to auth, the workflow ran for 2m53s doing nothing useful, and only the final step surfaced the problem. I wasted a release cycle thinking my fix was 90% right with a small auth hiccup at the end, when really nothing was getting published. Verified post-run with npm view @aictrl/cli versions — nothing from that run ever reached npm.
This same masking happened on v0.3.1 back on 2026-04-03 and nobody noticed; @aictrl/[email protected] never actually existed on npm even though the GitHub release tag still does.
What "good" looks like
Tolerate only the "version already published" case (E409/EPUBLISHCONFLICT), fail loud on everything else.
Sketch:
- name: Publish @aictrl/util
working-directory: packages/util
run: |
bun pm pack
set +e
output=$(npm publish *.tgz --access public --provenance 2>&1)
code=$?
echo "$output"
set -e
if [ $code -ne 0 ] && ! echo "$output" | grep -qE 'EPUBLISHCONFLICT|cannot publish over|already published'; then
exit $code
fiOr extract it into a reusable composite action / shell function since the pattern repeats across 4 named steps + the platform binary loop.
Acceptance criteria
|| trueremoved from allnpm publishsteps inpublish.yml- Workflow still tolerates reruns where a specific version already exists on npm (common during partial-failure recovery)
- Workflow fails loud on auth errors, network errors, and any other non-"already-published" failure
- Ideally also fails loud if
bun pm packproduces zero.tgzfiles (current glob-based invocation would silently succeed on an empty match)
Related
- Discovered during fix: activate pinned npm via corepack in publish workflow #48 / fix: pin publish workflow npm to 11.10.1 (pre promise-retry removal) #49 / the v0.3.2 release saga on 2026-04-11
- Same pattern would have caught the v0.3.1 silent failure weeks earlier
Activity
ci: fail loud on npm publish errors that aren't EPUBLISHCONFLICT (#51)
ci: fail loud on npm publish errors that aren't EPUBLISHCONFLICT (#51)
ci: clean stale .tgz before bun pm pack per review feedback
ci: extract publish wrapper to shared script, fix pipefail bug