From 5f6037edfaf2921bd4d6b64916c6bac1e7a97a3e Mon Sep 17 00:00:00 2001 From: Qwynn Marcelle Date: Wed, 19 Aug 2026 06:28:35 -0400 Subject: [PATCH] fix(release): enter the npm-publish environment so the scoped token is in scope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `@workspacejson/cli@0.6.1` was tagged but never published. Its run cleared every gate — guards, build, typecheck, tests, and the tarball verification that stopped 0.6.0 — then failed the credential check with both variables empty: NODE_AUTH_TOKEN: NPM_TOKEN: NPM_TOKEN is an ENVIRONMENT secret on `npm-publish`, and this repository holds no repository-level NPM_TOKEN at all. GitHub exposes an environment secret only to a job that declares `environment:`. This job never did, so `${{ secrets.NPM_TOKEN }}` resolved to the empty string and the guard reported a missing credential on a repository whose credential was correct all along. `publish` is the job id. `npm-publish` is the environment. Nothing in the run output distinguished them, which is most of why this read as a token problem. The job now declares `environment: npm-publish`, and takes `name: npm-publish` so a reader of a failed run sees the same word in the job label and in the scope it needs. The header said "Required repository secret"; it now names the environment secret actually required, and records why the token is scoped that way — the environment is the reviewer-gateable boundary the standard's own releases publish behind, so widening the token to the repository would have been the wrong repair. Not re-run, re-tagged: a re-run replays the workflow as it existed at the tagged commit, and cli-v0.6.1 points at a commit with no `environment:` line, so it would fail identically. The failed tags stay. 0.6.0 and 0.6.1 each record a real defect stopped before anything reached the registry, which is better evidence than a history in which the gates never fired. Version bumped to 0.6.2. No package, mining, retrieval, provenance or artifact behavior changes; the 0.5.0 authority migration and the 0.6.1 packaging-boundary repair both ship here unchanged. --- .github/workflows/publish-cli.yml | 22 ++++++++++++++- README.md | 8 +++--- packages/cli/CHANGELOG.md | 46 +++++++++++++++++++++++++++++++ packages/cli/package.json | 2 +- 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-cli.yml b/.github/workflows/publish-cli.yml index 4cf74aa..1cf634e 100644 --- a/.github/workflows/publish-cli.yml +++ b/.github/workflows/publish-cli.yml @@ -21,8 +21,22 @@ name: Publish @workspacejson/cli # reaches the registry. A tag that disagrees with the manifest fails the run # instead of publishing a version nobody named. # -# Required repository secret: +# Required ENVIRONMENT secret, on the `npm-publish` environment: # NPM_TOKEN npm automation token with publish rights on @workspacejson/cli +# +# Environment, not repository. This distinction is load-bearing and it is what +# failed the 0.6.1 release: GitHub exposes an environment secret only to a job +# that explicitly declares `environment:`. The job did not, so +# `${{ secrets.NPM_TOKEN }}` resolved to the empty string and the credential +# guard below reported a missing token on a repository whose token was +# correctly configured all along. The secret was never the problem; the job was +# simply never in the scope where it exists. +# +# Scoping it to an environment rather than the repository is deliberate: it is +# the same reviewer-gateable boundary the standard's `standard-v*` releases +# publish behind. Moving NPM_TOKEN to a repository secret would "fix" this by +# widening the blast radius of every workflow in the repository, which is the +# opposite of what the environment is for. # --------------------------------------------------------------------------- on: @@ -40,6 +54,12 @@ concurrency: jobs: publish: + # `name` is cosmetic — it labels the job in the Actions UI. `environment` is + # the line that actually admits the job to the scope where NPM_TOKEN exists. + # They are named alike on purpose, so a reader of a failed run sees the same + # word in the job label and the environment it needs. + name: npm-publish + environment: npm-publish runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index 8f755ea..a061043 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ consumed here as released packages. > > **Registry snapshot, verified 2026-08-19:** the published versions are > `@workspacejson/cli@0.5.2` and `agents-audit@0.4.4`. The manifest table below -> declares `0.6.1`. `0.6.0` was tagged but never published — its publish run -> stopped at the tarball gate on a packaging defect (see the CLI changelog) — -> so the registry skips from `0.5.2` to `0.6.1`. +> declares `0.6.2`. `0.6.0` and `0.6.1` were both tagged but never published — +> each publish run stopped at a different gate before reaching the registry (see +> the CLI changelog) — so the registry skips from `0.5.2` to `0.6.2`. > > The versions shown in the table below are the versions declared by this > repository's package manifests. `pnpm run check:package-docs` keeps those @@ -33,7 +33,7 @@ consumed here as released packages. | Directory | Package | Version | Role | | -- | -- | -- | -- | -| [`packages/cli/`](./packages/cli/) | `@workspacejson/cli` | `0.6.1` | the neutral producer and its `workspacejson` binary | +| [`packages/cli/`](./packages/cli/) | `@workspacejson/cli` | `0.6.2` | the neutral producer and its `workspacejson` binary | | [`packages/agents-audit-compat/`](./packages/agents-audit-compat/) | `agents-audit` | `0.4.4` | frozen compatibility bridge; preserves the historical command and API | | [`packages/mining-core/`](./packages/mining-core/) | `@workspacejson/mining-core` | `0.0.0`, private | L0 commit-graph mining core — extraction, path identity, completeness semantics (META-297 Phases 1–2) | diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index c586ebe..6952c5a 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,51 @@ # Changelog — `@workspacejson/cli` +## 0.6.2 + +### Patch Changes + +- Enter the `npm-publish` environment in the publish job, so the scoped + `NPM_TOKEN` is actually in scope. **`0.6.1` was tagged but never published**; + this is the same release with that workflow defect corrected. + + No package, mining, retrieval, provenance or artifact behavior changes. The + `0.5.0` standard authority migration and the `0.6.1` packaging-boundary repair + both ship here unchanged. + + **What stopped `0.6.1`.** The publish run cleared every gate — guards, build, + typecheck, tests, and the tarball verification that stopped `0.6.0` — then + failed on the credential check with both variables empty: + + ``` + NODE_AUTH_TOKEN: + NPM_TOKEN: + ``` + + `NPM_TOKEN` is stored as an **environment** secret on the `npm-publish` + environment, and this repository holds no repository-level `NPM_TOKEN` at all. + GitHub exposes an environment secret only to a job that explicitly declares + `environment:`. The `publish` job never did, so `${{ secrets.NPM_TOKEN }}` + resolved to the empty string and the guard reported a missing credential on a + repository whose credential was correctly configured the whole time. + + `publish` is the job id; `npm-publish` is the environment. Nothing in the run + output made that distinction visible, which is most of why it read as a token + problem. + + **The fix is one line of behavior.** The job now declares + `environment: npm-publish`, and takes `name: npm-publish` so the Actions UI + labels it with the same word as the scope it needs. The workflow header, which + said "Required repository secret", now names the environment secret it actually + requires and records why the token is scoped that way — an environment is the + reviewer-gateable boundary the standard's own releases publish behind, so + widening the token to the repository would have been the wrong repair. + + **Why the tag moved rather than the run being re-run.** A re-run replays the + workflow as it existed at the tagged commit, and `cli-v0.6.1` points at a commit + whose workflow has no `environment:` line. Re-running it would fail identically. + The failed tag is left in place: `0.6.0` and `0.6.1` each record a real defect + that a gate caught before anything reached the registry. + ## 0.6.1 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index b95f01d..a42efa9 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@workspacejson/cli", - "version": "0.6.1", + "version": "0.6.2", "description": "The workspace.json producer — scans a repository and generates .agents/workspace.json deterministically, preserving human-authored manual evidence.", "license": "Apache-2.0", "author": "workspace.json contributors",