♻️ Use the automatic token and fail closed on a partial release

Drop the GITEA_TOKEN gate and pass no explicit token: gitea-release-action
defaults to the run's automatic github.token, so the release page needs only
contents: write. Keep the npm publish gated on NPM_TOKEN, but add a final
always() step that fails the job unless both the release page and npm publish
reported success, so a skipped npm half is an explicit red job instead of a
silently green one.
This commit is contained in:
tmu committed 2026-09-15 09:25:24 +00:00
1 parent 60e416b0fe
commit 79b4d8c005
2 files changed
+44 -31

No files matched your search

+31 -18
View File
@@ -141,17 +141,17 @@ jobs:
# `.npmrc` rewrite here; only the Node download is skipped.
container:
image: gitea.e1nsnull.de/tmu/act-ci:26.8.2
# Lift the optional publish secrets into job-level `env` so the steps
# below can gate on them: `secrets` is not an allowed context in a step
# `if` (see GitHub's context-availability table), `env` is. An unset
# secret arrives as the empty string, which is exactly the skip signal.
# A tag pushed without the maintainer's secrets (a fork, a manual
# dispatch) now runs the packaging checks and skips only the publish
# steps whose token is missing, instead of failing the job at an assert.
# Set both in the Gitea repo: Settings → Actions → Secrets.
# The release page is created with the run's automatic Gitea token
# (`github.token`), so it needs `contents: write`.
permissions:
contents: write
# The npm token is optional: `secrets` is not an allowed context in a
# step `if` (see GitHub's context-availability table), so it is lifted
# into job-level `env`, where an unset secret arrives as the empty
# string and skips the publish rather than attempting an unauthenticated
# one. Set NPM_TOKEN in the Gitea repo: Settings → Actions → Secrets.
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
@@ -171,25 +171,38 @@ jobs:
path: dist/
- run: npm run publish:publint
- run: npm run publish:attw
# When both tokens are present the Gitea release page is created
# *before* `npm publish` on purpose: a broken page then fails CI
# without burning an npm version. The page is cheap to retry, a
# published version is not. The body is the matching
# Keep-a-Changelog section; an unknown tag makes the extractor exit
# non-zero, so the page can never go up empty.
# The Gitea release page is created *before* `npm publish` on
# purpose: a broken page then fails CI without burning an npm
# version. The page is cheap to retry, a published version is not.
# The body is the matching Keep-a-Changelog section; an unknown tag
# makes the extractor exit non-zero, so the page can never go up
# empty.
- name: Extract release notes from CHANGELOG.md
if: env.GITEA_TOKEN != ''
env:
TAG_REF: ${{ gitea.ref }}
run: ./scripts/release-notes.sh "${TAG_REF#refs/tags/}" > release-notes.md
- name: Create the Gitea release
if: env.GITEA_TOKEN != ''
id: gitea_release
uses: https://gitea.com/actions/gitea-release-action@v1
with:
token: ${{ env.GITEA_TOKEN }}
body_path: release-notes.md
- name: Publish to npm
id: npm_publish
if: env.NPM_TOKEN != ''
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ env.NPM_TOKEN }}
# All-or-nothing: the tag is only released once *both* the release
# page and the npm package are up. A skipped npm publish (NPM_TOKEN
# unset) has no `success` outcome, so `always()` reaches this check
# even after a failure and turns the skipped half into an explicit
# red job instead of a silently green one.
- name: Require both releases
if: always()
run: |
GITEA="${{ steps.gitea_release.outcome }}"
NPM="${{ steps.npm_publish.outcome }}"
if [ "${GITEA}" != success ] || [ "${NPM}" != success ]; then
echo "::error::incomplete release — gitea=${GITEA:-skipped} npm=${NPM:-skipped}"
exit 1
fi