From b9759b3538544739a1881fdc0a73d37a1d2f2304 Mon Sep 17 00:00:00 2001 From: Florent Klein Date: Thu, 30 Jul 2026 04:25:21 +0200 Subject: [PATCH] Skip already-published versions in the npm publish job The v0.2.1 publish failed on @natui/dev after @natui/core was already on the registry, and the job could not be re-run: the core step died on a republish conflict before reaching the missing packages, leaving manual publishing as the only recovery. Each publish step now asks the registry whether its exact version already exists and skips with a log line when it does, comparing npm view output rather than its exit code, which varies across npm releases for missing versions. Re-running a partially failed job now resumes with the missing packages. RELEASING.md replaces the new-patch-version guidance with fix the cause and re-run. Co-Authored-By: Claude Fable 5 --- .github/workflows/publish.yml | 30 ++++++++++++++++++++++++++---- RELEASING.md | 5 +++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b4f1d92..21ea3d5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -111,17 +111,39 @@ jobs: # Confirms the workspace versions match the pushed tag and re-validates # all three tarballs before anything reaches the registry. - run: pnpm release:check "$GITHUB_REF_NAME" + # Each publish step skips a version the registry already has, so + # re-running this job after a partial publish resumes with the missing + # packages instead of failing on a republish conflict. npm view's exit + # code for a missing version varies across npm releases; compare its + # output instead. - name: Publish @natui/core working-directory: packages/natui - run: npm publish + run: | + version="$(node -p "require('./package.json').version")" + if [ "$(npm view "@natui/core@${version}" version 2>/dev/null || true)" = "${version}" ]; then + echo "@natui/core@${version} is already on the registry; skipping." + else + npm publish + fi # @natui/dev declares its @natui/core peer with the workspace protocol, # which only pnpm rewrites to a real version range. Pack with pnpm, then # let npm publish the tarball so OIDC trusted publishing still applies. - name: Publish @natui/dev working-directory: packages/natui-dev run: | - pnpm pack - npm publish "natui-dev-$(node -p "require('./package.json').version").tgz" + version="$(node -p "require('./package.json').version")" + if [ "$(npm view "@natui/dev@${version}" version 2>/dev/null || true)" = "${version}" ]; then + echo "@natui/dev@${version} is already on the registry; skipping." + else + pnpm pack + npm publish "natui-dev-${version}.tgz" + fi - name: Publish create-natui-app working-directory: packages/create-natui-app - run: npm publish + run: | + version="$(node -p "require('./package.json').version")" + if [ "$(npm view "create-natui-app@${version}" version 2>/dev/null || true)" = "${version}" ]; then + echo "create-natui-app@${version} is already on the registry; skipping." + else + npm publish + fi diff --git a/RELEASING.md b/RELEASING.md index cf98cc3..2872f72 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -127,5 +127,6 @@ attestations automatically. All three packages must name `publish.yml` in this repository as their trusted publisher: on npmjs.com, open each package's Settings, then Trusted Publisher, and select GitHub Actions with this repository and that workflow filename. A version already on the registry -cannot be republished; a failed run after a partial publish needs a new -patch version. +cannot be republished, but each publish step skips versions the registry +already has. After a partial publish, fix the cause and re-run the failed +job; it resumes with the missing packages.