Fail the npm already-published check closed

Merged
JE
2mo ago
+14-2

Ports the seed template fix from basecamp/sdk#12 into this repo's own copy of release-typescript.yml.

The publish job decided whether to publish with if npm view "${PKG_NAME}@${VERSION}" version 2>/dev/null. npm view exits non-zero for an absent version (E404), but also for a DNS failure, an auth error, a registry 5xx or a timeout, so every one of those read as "not published" and the job went on to npm publish. The publish step's own "cannot publish over the previously published versions" idempotency guard bounded the realistic damage to a confusing failure at the wrong step rather than a duplicate publish, but the shape is wrong.

Now: publish only when npm positively answers E404; a 0 exit with a version string is "already published" (skip); anything else prints npm's output, fails the job, and leaves a re-run of the same tag run as the recovery. An empty --cache keeps npm from answering from a stale packument when the fetch fails. Only the check step changes; it still reads the package name from package.json as before, and the publish step's idempotency handling is untouched.

Verified

  • The step body, extracted from this file and run against the live registry on npm 11.19: 0.2.4 → already_published=true; 99.99.99 → E404, already_published=false; registry unreachable (ECONNREFUSED) → ::error, exit 1, no output written.
  • actionlint 1.7.12 and zizmor 1.30.0 (--persona regular, whole tree): clean.

Summary by cubic

Fails the npm already-published check in the release workflow so the job no longer publishes blindly when the registry check errors. Previously any npm view failure — DNS, auth, registry outage, timeout — counted as "not published" and the job went on to npm publish. Now it publishes only when npm positively returns E404; a successful response skips, and anything else prints npm's output and fails the job.

  • A re-run of the same tag run is the recovery path.
  • An empty --cache keeps npm from answering from a stale packument when the fetch fails.
  • Only the check step changes; the publish step's idempotency guard is untouched.