From 0da63cad1545dd0301145efca57a223276f9e40a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=9C=E5=86=A0=E9=AD=81?= Date: Fri, 4 Sep 2026 23:47:47 +0900 Subject: [PATCH] fix(release): pass an explicit npm dist-tag, stop tee masking a failure Two defects in the GitHub Packages publish step, neither yet surfaced because release.yml has not been tagged since. npm/cli refuses to publish a prerelease version whose dist-tag is left at its default ("You must specify a tag using --tag when publishing a prerelease version"); the check is on whether --tag was passed at all, not on its value. Every version this step publishes is a pre-release, so the next tagged run would have stopped here with the NuGet packages already pushed - which is exactly how v0.5.0-preview.3 failed in vault-extract and had to be re-cut. --tag latest is passed explicitly rather than reusing steps.channel.outputs.npm-tag ("next" here): this registry only ever receives pre-releases - stable goes to npmjs under the public @dignite/* name - so latest tracking the newest preview is what a consumer of this channel wants, it keeps an unpinned install resolving, and it stops the latest tag earlier untagged publishes already set from freezing on a stale preview. The second defect is why the first would have been hard to read: the publish ran as `if ! npm publish ... | tee`, and the step shell is `bash -e` with no pipefail, so the pipeline status was always tee's. The failure branch could never fire, the "already published" soft skip was unreachable, and an E401 - or this --tag error - would have been reported as a green step. Redirect to the log and test npm's own exit status instead, which is also what turns `exit 1` into `exit $status`. Same bug and same fix as vault-extract's release workflow. --- .github/workflows/release.yml | 24 ++++++++++++++++++++++-- CHANGELOG.md | 25 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5928eb7..df31063 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -326,11 +326,31 @@ jobs: # npm publish has no --skip-duplicate equivalent (unlike the dotnet nuget push calls # above); re-dispatching at an unchanged pre-release version is expected and shouldn't # fail the run, so treat "already published" as a soft skip and let anything else fail. - if ! npm publish "$workdir/package" --registry https://npm.pkg.github.com 2>&1 | tee /tmp/npm-publish.log; then + # + # Redirect rather than `| tee`: the step shell is `bash -e` with no pipefail, so a + # pipeline's status is tee's (always 0). `if ! npm publish ... | tee` therefore never + # sees a failure, and this step reported success over an E401. The same bug + # dignite-projects/vault-extract's release workflow shipped before it fixed this. + # + # --tag is not optional: npm errors out on a prerelease version whose dist-tag is left + # at its default ("You must specify a tag using --tag when publishing a prerelease + # version" - npm/cli checks whether the tag was set at all, not what it was set to). + # "latest" is the right value here even though the version is a prerelease, and is why + # this does not reuse steps.channel.outputs.npm-tag ("next" on this branch): GitHub + # Packages only ever receives pre-releases - stable goes to npmjs under the public + # @dignite/* name - so latest tracking the newest preview is what a consumer of this + # channel wants, it keeps an unpinned install resolving, and it stops the latest tag + # earlier untagged publishes already set from freezing on a stale preview. + set +e + npm publish "$workdir/package" --registry https://npm.pkg.github.com --tag latest > /tmp/npm-publish.log 2>&1 + status=$? + set -e + cat /tmp/npm-publish.log + if [ $status -ne 0 ]; then if grep -q 'Cannot publish over existing version' /tmp/npm-publish.log; then echo "::notice::@dignite-projects/ng.site@${{ steps.channel.outputs.version }} is already published; skipping." else - exit 1 + exit $status fi fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f4c607..1e2ac6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -126,6 +126,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- **The pre-release npm publish would have failed on its dist-tag, and a failure would have been + reported as success either way.** Two defects in the same step, neither of which any run has + surfaced yet because `release.yml` has not been tagged since. + + npm/cli now refuses to publish a version carrying a SemVer pre-release suffix when its dist-tag + is left at the default — *"You must specify a tag using --tag when publishing a prerelease + version"* — and the check is on whether `--tag` was passed at all, not on what it was set to. + Every version this step publishes is a pre-release, so the next tagged run would have stopped + here, after the NuGet packages had already been pushed. That is not hypothetical: it is exactly + how `v0.5.0-preview.3` failed in dignite-projects/vault-extract, leaving that version published + on one channel only. `--tag latest` is now passed explicitly, rather than reusing + `steps.channel.outputs.npm-tag` (`next` on this branch): GitHub Packages only ever receives + pre-releases here — stable goes to npmjs under the public `@dignite/*` name — so `latest` + tracking the newest preview is what a consumer of this channel wants, it keeps an unpinned + install resolving, and it stops the `latest` tag earlier untagged publishes already set from + freezing on a stale preview. + + The second defect is why the first would have been confusing to diagnose: the publish ran as + `if ! npm publish … | tee /tmp/npm-publish.log`, and the step shell is `bash -e` with no + `pipefail`, so the pipeline's status was always `tee`'s — zero. The `if !` branch could never + fire, the "already published" soft-skip was unreachable, and a real failure (an `E401`, or this + `--tag` error) would have been reported as a green step. The publish now redirects to the log + and tests `npm`'s own exit status, which is also what makes `exit 1` an `exit $status`. The same + bug, and the same fix, as dignite-projects/vault-extract's release workflow. + - **`dotnet restore Dignite.Site.slnx` failed with `NU1605`**, so the new CI workflow and the next tagged release alike would have stopped at their first .NET step. `Microsoft.Extensions.FileProviders.Embedded` was pinned at `10.0.9` by `Dignite.Site.Host`,