Repository navigation
Gate releases on a verified asset manifest; source download claims from the release feed - #259
Merged
Merged
Conversation
…laims from the feed Refs #253 `auto-release.yml` published the GitHub release before any build ran and exited without waiting, so all eight recent runs reported success — including the six that produced asset-less releases (v1.12.0..v1.13.2). `scripts/verify-release-manifest.mjs` was wired to nothing. Release gate: - the release is now created as a draft on an explicitly created tag, so a failed build leaves nothing on /releases/latest or the download page; - `verify-release-manifest.mjs` is rewritten as the required gate: it fails when a contract asset is missing, empty, still uploading, or attached under an off-contract name, and it runs in `release.yml` before the draft is published and again in `auto-release.yml` after the watched run; - `auto-release.yml` waits on the dispatched `release.yml` run, so a green run means a downloadable release exists; - signing, notarization, secrets, and both workflows' triggers are unchanged. Download page: - /download and /download.md now read the tag, installer filename, update archive, and appcast presence from the GitHub release feed at build time instead of hardcoding them, and fall back to claiming nothing when the feed is unreachable; - the Sparkle auto-update claim is now conditional on a published appcast.xml. No release carries one, so both surfaces say updates are manual, matching `NativeUpdaterConfiguration.ready`. Tests: `scripts/verify-release-manifest.test.mjs` (complete manifest, draft, missing asset, no assets, Tauri-shaped names, wrong version, empty/pending upload, bad tag), wired into CI as `pnpm test:release-manifest`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The runner's preinstalled Node runs verify-release-manifest.mjs, which uses only stable built-ins, so setup-node's dependency cache added a cache-poisoning surface to a workflow that can publish releases for no gain. Refs #253 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A draft is not reliably resolvable by `gh release view <tag>`, and GitHub will create a second draft under a tag that already has one. Matching the full release list keeps a re-run after a failed build a true no-op. Refs #253 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
sarthakagrawal927
added a commit
that referenced
this pull request
Sep 6, 2026
Refs #252, #253. No product change. This bump exists to run the release gate landed in #259 end to end, which no run has ever done: the last six releases (v1.12.0..v1.13.2) went public with zero assets while every auto-release run reported success. What this release exercises: - auto-release.yml creates the tag and a DRAFT release, dispatches release.yml, waits on that run, and re-verifies the published asset manifest, so a green run means a downloadable release exists; - release.yml verifies the manifest with verify-release-manifest.mjs before flipping the draft to published, and checks that the public appcast URL resolves; - the installed-upgrade proof's incumbent is pinned to v1.11.1, whose bundled CLI has the `rubrics` command the proof seeds data with (#252/#258); - /download and /download.md read the tag, installer filename, update archive, and appcast presence from the release feed at build time, so the page follows whatever this release actually publishes; - src/data/privacy.ts stays the single source for /privacy, /privacy.md, and the page JSON-LD. The three crates and their exact path pins move with the app version, as 1.13.1 established; core:qualify-cli reports 1.13.3. Local gates: lint, knip:strict, change-size, complexity, cycles, duplication, check-docs, test:release-manifest, core:qualify-cli. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #253.
auto-release.ymlcreated the GitHub release before any build ran and exited without waiting, so all eight recent runs reportedsuccess— including the six that produced asset-less releases (v1.12.0..v1.13.2).scripts/verify-release-manifest.mjsexisted but was referenced by no workflow and no package script.Release gate
auto-release.ymlnow creates thev<version>tag explicitly (a draft release does not create its own tag, and bothrelease.ymland the qualification workflow check out the exact tag) and then a draft release. A draft is absent from/releases/latest, from the release feed the download page reads, and from Sparkle's feed — so a failed build leaves nothing user-visible behind.verify-release-manifest.mjsis the required gate. Rewritten from a network-only appcast probe into a manifest verifier with a pure, testable core. It fails when a contract asset is missing, empty, still uploading, or attached under a name that is not on the contract, and emits acodevetter.release-manifest-verification/v1receipt.release.ymlafter upload and before the draft is flipped to published, and again inauto-release.ymlafter the watched run finishes.auto-release.ymlnow waits. It resolves the dispatchedrelease.ymlrun andgh run watch --exit-statuses it, so a green auto-release run means a downloadable release exists.inspect-native-appcast.mjs, offline, inside qualification); this gate only asserts the published manifest, so nothing is duplicated.pushonShared.xcconfig+workflow_dispatch;release: created+workflow_dispatch).The old ad-hoc
grep -Fxcontract check and thecurlof the public feed are replaced by the script plus a post-publish feed check with retries.Download page (#253 items 2 and 3)
/downloadand/download.mdno longer hardcode a version, a filename, or an update promise.src/data/release.tsreads the release feed at build time and picks the newest published release that actually carries an installer, so the page can only state what is downloadable. If the feed is unreachable or rate-limited the build fails soft: it links the releases index and claims no filename, rather than claiming something stale.The Sparkle claim is now conditional on a published
appcast.xml. No release carries one, so both surfaces currently say updates are manual — which matchesNativeUpdaterConfiguration.readyandevidence/verification/native-release-readiness-2026-09-02.md. The claim turns itself back on the first time a release publishes an appcast. The appcast is real and is generated, EdDSA-signed and inspected innative-production-qualification.yml; its feed URL ishttps://github.com/Codevetter/codevetter/releases/latest/download/appcast.xml, notcodevetter.com/appcast.xml— nothing was invented here.Built output today:
Evidence
Dry-run of the gate against real releases:
So the gate blocks both failure modes #253 reported — Tauri-shaped filenames and zero assets — and passes a complete manifest.
Local gates:
pnpm lint,pnpm knip:strict,quality:change-size,quality:complexity,quality:cycles,quality:duplication,pnpm test:release-manifest(10 tests),pnpm test:automation,node scripts/check-docs.mjs, landingpnpm build+verify-agent-surfaces.mjs(6/6 PASS) — all green. Workflow shell fragments shellcheck clean locally;actionlintruns inrepository-security.ymlon this PR.Not done here
No tag, no release, nothing published. The pipeline is still unproven end to end — see the comment on #253 for the single maintainer action that proves it.
🤖 Generated with Claude Code