From a4d5fe70d5f97090c32c7e2e042f046c28a8191a Mon Sep 17 00:00:00 2001 From: Tauan BF <11513929+tauanbinato@users.noreply.github.com> Date: Mon, 28 Sep 2026 20:22:18 -0300 Subject: [PATCH] Publish the npm launcher from the release workflow 0.30.0's package was published by hand, with the maintainer's security key in the browser, which an automated run cannot do. A job after the GitHub release now publishes it through npm's trusted publishing: the environment npm (v* tags only, like crates-io) and the job's OIDC token stand in for a token, and npm adds the package's provenance itself. It checks that npm is 11.5.1 or later, which trusted publishing needs, and that npm/package.json has the tag's version; it skips a version npm already has, so a rerun is safe; and it ships the release's SHA256SUMS in the package as the hand publish did. --- .github/workflows/release.yml | 41 ++++++++++++++++++++++++++++++++++- CHANGELOG.md | 2 ++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b98d22b..fcf7bb4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,7 +3,9 @@ name: Release # checks run and the binaries build first, then the crate goes to crates.io and # the tag's message body becomes the notes of a GitHub release that carries the # binaries, their checksums and build provenance; then the Homebrew formula in -# Tech-Byte-Frontier/homebrew-tap installs it. Every step can be rerun safely. +# Tech-Byte-Frontier/homebrew-tap installs it, and the npm launcher +# @tech-byte-frontier/jevgate of the same version runs it. Every step can be +# rerun safely. on: push: tags: ["v*"] @@ -126,3 +128,40 @@ jobs: git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git commit -qam "jevgate ${TAG#v}" git push + npm: + needs: publish + runs-on: ubuntu-latest + # npm trusts only this workflow in this environment (trusted publishing), and + # adds the package's provenance itself. + environment: npm + permissions: + contents: read + id-token: write + env: + TAG: ${{ github.ref_name }} + GH_TOKEN: ${{ github.token }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + # Trusted publishing needs npm 11.5.1 or later, which Node 24 releases + # bring. No package cache: nothing restored runs next to the publish token. + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + package-manager-cache: false + - name: Publish the npm launcher + run: | + npm_version=$(npm --version) + [ "$(printf '%s\n' 11.5.1 "$npm_version" | sort -V | head -n 1)" = 11.5.1 ] || { echo "::error::npm $npm_version is older than 11.5.1, which trusted publishing needs"; exit 1; } + name=$(jq -r .name npm/package.json) + version=$(jq -r .version npm/package.json) + [ "$TAG" = "v$version" ] || { echo "::error::Tag $TAG does not match npm/package.json version $version"; exit 1; } + if [ -n "$(npm view "$name@$version" version 2>/dev/null)" ]; then + echo "npm already has $name $version" + exit 0 + fi + # The package ships the release's checksums, which tie it to these binaries. + gh release download "$TAG" --pattern SHA256SUMS --dir npm + npm publish ./npm --access public diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dd7755..af20d1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ Notable changes to JevGate. Versions follow [Semantic Versioning](https://semver ## [Unreleased] +- Releases publish the npm package, `@tech-byte-frontier/jevgate`, from the release workflow through npm's trusted publishing: no token, and npm shows the package's provenance. 0.30.0's was published by hand. + ## [0.30.0] - 2026-09-28 0.30.0 carries the five versions of the roadmap, 0.26 to 0.30, in one release. A pull request check judges only what the change touches and fails only on rules measured right at least 80% of the time on projects JevGate was never tuned on; `jevgate hook` puts that gate in a coding agent's loop; each question's answer is cached apart and each finding says how often findings like it were right; a team's own conventions become questions that gate its code; and nine more languages are read, in preview. Each part below says what changed and how it was measured.