From 8915eb8faa83fd57989890c29ac29209d9e96c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 15 Sep 2026 09:06:35 +0000 Subject: [PATCH] :construction_worker: Gate the publish steps on their tokens The publish job aborted at the top-of-job NPM_TOKEN assert, so every tag run since 0.1.1 failed before checkout and nothing was ever published. Lift both optional secrets into job-level env (the secrets context is not allowed in a step if) and gate each publish step: the Gitea release on GITEA_TOKEN, npm publish on NPM_TOKEN. An absent secret now skips only its step, so a tag without the maintainer's secrets stays green after the packaging checks. --- .gitea/workflows/ci.yml | 52 ++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index abc878c..d05426e 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -65,8 +65,8 @@ jobs: - uses: actions/checkout@v4 # Fail fast when the job container is not the baked image: a stale # tag on the runner (`forcePull=false` in its pull log) silently - # reintroduces the per-job download. Mirrors the publish job's - # NPM_TOKEN assert — cheap, and it names the invariant. + # reintroduces the per-job download. Cheap, and it names the + # invariant. - name: Assert the baked tool cache is present run: | test -f "/opt/hostedtoolcache/node/$(tr -d '[:space:]' < .node-version)/x64.complete" @@ -141,20 +141,18 @@ jobs: # `.npmrc` rewrite here; only the Node download is skipped. container: image: gitea.e1nsnull.de/tmu/act-ci:26.8.2 - # The release page is created with the run's automatic Gitea token - # (`github.token`), not `NPM_TOKEN`, so it needs `contents: write`. - permissions: - contents: write + # 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. + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} steps: - # Double-gate: publish only runs on a tag *and* aborts here if NPM_TOKEN - # is unset, so a tag push never silently no-ops (or half-publishes). Set - # NPM_TOKEN in the Gitea repo: Settings → Actions → Secrets. - - name: Assert NPM_TOKEN is configured - run: | - if [ -z "${{ secrets.NPM_TOKEN }}" ]; then - echo "::error::NPM_TOKEN secret is not set — refusing to publish." - exit 1 - fi - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: @@ -173,19 +171,25 @@ jobs: path: dist/ - run: npm run publish:publint - run: npm run publish:attw - # 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. + # 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. - 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 - - uses: https://gitea.com/actions/gitea-release-action@v1 + - name: Create the Gitea release + if: env.GITEA_TOKEN != '' + uses: https://gitea.com/actions/gitea-release-action@v1 with: + token: ${{ env.GITEA_TOKEN }} body_path: release-notes.md - - run: npm publish --access public + - name: Publish to npm + if: env.NPM_TOKEN != '' + run: npm publish --access public env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + NODE_AUTH_TOKEN: ${{ env.NPM_TOKEN }}