Smoke-test the assembled release before it is published - #391
Merged
Merged
Conversation
Each build job checks its own installers and publish checksums whatever it downloaded, but nothing checked the set as a whole. The publish job now runs scripts/release-smoke.mjs after SHA256SUMS and before creating the release: all six installers present once and non-empty, SHA256SUMS covering every asset and matching its bytes, the tag and the three version sources agreeing, the product name and identifier unchanged, and no updater asset unless createUpdaterArtifacts is on. The job summary states the updater and signing state, including an allow_unsigned rehearsal. Chat #356, plan Task 5. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Moderate issues remain in workflow reporting, updater validation, checksum parsing, and signing-state reporting.
Review effort: Lite
Findings: 2
Open (2)
What changed in this PR
Adds an assembled-release smoke test before publication, validating artifacts, checksums, versions, identity, updater state, and signing status.
Changes:
- Added validation logic, type declarations, and comprehensive tests.
- Integrated the smoke test into the release workflow.
- Documented the release validation process.
| File | Description |
|---|---|
src/release-workflow.test.ts |
Verifies workflow ordering and flags. |
src/release-smoke.test.ts |
Tests release validation scenarios. |
scripts/release-smoke.mjs |
Implements assembled-release validation. |
scripts/release-smoke.d.mts |
Declares validator types. |
docs/releasing.md |
Documents release validation. |
.github/workflows/release.yml |
Runs validation before publication. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…platforms Under set -euo pipefail a failing smoke run exited the step before its report reached the job summary; capture the status, write the summary, then exit with it. The manifest step refuses two updater archives for one platform, so the smoke check now does too, and the enabled-updater fixture carries one archive per platform as a real release would. Co-Authored-By: Claude Opus 5.5 (1M context) <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 #356 (plan Task 5). This adds the release smoke test the issue lists as absent. It follows the release owner's decisions recorded on #356: the updater stays off, and the unsigned state is reported rather than hidden.
Gap
Each
buildjob smoke-tests its own installers, andpublishchecksums whatever it downloaded. Nothing checked the assembled set as a whole. A missing platform, a stale file from another version, or a checksum that no longer matches would reachgh release create.scripts/release-smoke.mjsThis runs in
publish, after Generate and verify SHA256SUMS and before Publish GitHub release, on dry runs and real runs alike. It fails if any of the following does not hold.v0.0.1rehearsal (run 35174981698) actually produced:_aarch64.dmgand_x64.dmg_x64_en-US.msiand_x64-setup.exe_amd64.AppImageand_amd64.debSHA256SUMS. It covers every other asset exactly once, lists nothing that is absent, has no malformed or duplicate lines, and every digest matches the bytes.package.json,tauri.conf.jsonand theCargo.toml[package]version all agree.productNameisOpenCoven Chatandidentifierisai.opencoven.chat.createUpdaterArtifacts..sigorlatest.jsonis a failure.latest.jsonmust carry the version and exactly the platforms of the present archives.It prints a JSON report, which goes to the job summary. The report states
updater: disabledand asigningstate. The signing state isunsignedon anallow_unsignedrehearsal, so the summary cannot read as signed when it was not. Code signatures themselves are still verified in the build jobs.Tests
src/release-smoke.test.ts, 24 tests. A clean unsigned release with the updater off passes against the real configuration. Each rule above has a failing case: each missing installer, an empty installer, a stray asset, a digest mismatch, missing and extra coverage, malformed and duplicate lines, a missingSHA256SUMS, tag and config version drift, a changed identifier, and updater assets while off. There are also enabled-updater cases: pass, missing signature, missing platform, nothing produced. Finally, the CLI exits 0 or 1 accordingly.src/release-workflow.test.tspins the step between SHA256SUMS and publication, including theallow_unsignedflag.Notes
tests/release-smoke.spec.tsunder Playwright. This follows the repository's convention instead:scripts/*.mjsplus.d.mts, with vitest insrc/.release-context.mjsstays inline inrelease.yml, wheresrc/release-workflow.test.tsalready covers it.release.ymlis not a governed Phase 1 file, so no harness repin is needed.Validation
phase1-schema-v2-evidenceandwindows-supervisor-source, timed out at load average 41 and pass when run alone..github/workflows.🤖 Generated with Claude Code