From bb97c67f258419f429c4aac7a5f4fb77c7f136db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Sandstr=C3=B6m?= Date: Mon, 19 Oct 2026 12:24:42 +0200 Subject: [PATCH 1/2] fix(ci): skip the publish dry run when the version is already on npm A rerun after a partial release died in the dry-run step, because npm rejects a dry run over an existing version. The recovery steps (GitHub release, SBOM, attestation) were never reached. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01RSop9MyLof8XxLTkFnF4KG --- .github/workflows/publish.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f377e8a3..30137667 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -254,7 +254,21 @@ jobs: - name: Show what will be published # `npm publish --dry-run` lists the exact files going into the tarball # and prints the tarball SHA — gives auditors a verifiable trail. - run: npm publish --dry-run --tag ${{ steps.disttag.outputs.tag }} + # + # IDEMPOTENT like the publish step below: npm refuses even a dry run for a version + # already on the registry, which made a rerun after a partial release die here + # before reaching the GitHub-release recovery steps. + env: + DIST_TAG: ${{ steps.disttag.outputs.tag }} + run: | + set -euo pipefail + name="$(node -p "require('./package.json').name")" + version="$(node -p "require('./package.json').version")" + if npm view "$name@$version" version >/dev/null 2>&1; then + echo "· $name@$version already on npm, skipping dry run" + exit 0 + fi + npm publish --dry-run --tag "$DIST_TAG" - name: Publish to npm with provenance # No NODE_AUTH_TOKEN: the credential comes from this job's OIDC identity, exchanged From cbc80f97b6149bd2739a64e637d0e16c2a5a7757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Sandstr=C3=B6m?= Date: Mon, 19 Oct 2026 14:14:09 +0200 Subject: [PATCH 2/2] test: retry temp cleanup in the dotenvx secrets test on Windows Windows still holds dotenvx.exe for a moment after the child exits, so rm failed with EBUSY and failed windows-native on #595. Same fix as #590. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01RSop9MyLof8XxLTkFnF4KG --- src/check-secrets.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/check-secrets.test.ts b/src/check-secrets.test.ts index 3e1147bb..4dec6519 100644 --- a/src/check-secrets.test.ts +++ b/src/check-secrets.test.ts @@ -233,7 +233,7 @@ describe("checkSecrets - dotenvx source", () => { } finally { if (previousPath === undefined) delete process.env.PATH; else process.env.PATH = previousPath; - await rm(project, { recursive: true, force: true }); + await rm(project, { recursive: true, force: true, maxRetries: 10, retryDelay: 200 }); } }); });