Skip to content

Publish workflow: fail loud on npm auth errors instead of silently tolerating them #51

@byapparov

Description

@byapparov

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 || true

The 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/util publish: ENEEDAUTH → || true masks → step shows ✓
  • @aictrl/plugin publish: ENEEDAUTH → || true masks → step shows ✓
  • @aictrl/sdk publish: ENEEDAUTH → || true masks → step shows ✓
  • platform binary loop (11 packages): ENEEDAUTH each → || true masks → step shows ✓
  • @aictrl/cli publish (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/cli@0.3.1 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
    fi

Or extract it into a reusable composite action / shell function since the pattern repeats across 4 named steps + the platform binary loop.

Acceptance criteria

  • || true removed from all npm publish steps in publish.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 pack produces zero .tgz files (current glob-based invocation would silently succeed on an empty match)

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions