Skip to content

ci(release): require complete, verified desktop assets before publishing - #1202

Merged
qnbs merged 14 commits into
mainfrom
release/tauri-assets-guard-20261108
Nov 8, 2026
Merged

qnbs merged 14 commits into
mainfrom
release/tauri-assets-guard-20261108

Conversation

@qnbs

@qnbs qnbs commented Nov 8, 2026 •

Copy link
Copy Markdown
Owner

User description

Summary

  • Require the complete Linux, Windows, and Apple Silicon release asset matrix, including all required installer signatures, per-target SBOMs, and third-party notices.
  • Validate latest.json against exactly the supported updater platforms, expected release URLs, and matching signature sidecars.
  • Cryptographically verify every signed target package against the updater public key embedded in tauri.conf.json before bundle upload. Add a protected-main workflow-dispatch preflight that signs a throwaway payload and proves valid, tampered, and wrong-key outcomes without publishing artifacts.
  • Stage releases as drafts, read the complete uploaded inventory back with sizes and SHA-256 digests, and publish only after exact verification. Existing published tags cannot be overwritten; failures leave an unpublished draft.

Validation

  • Focused Biome checks: PASS.
  • releaseAssetsGuard, releaseSecurityGate, and workflowPolicy: 85 tests PASS.
  • PR_BUDGET_BASE=origin/main pnpm run ci:prepush: PASS, including workflow policy and TypeScript.
  • Four outgoing commits are SSH-signed and verified.
  • Full three-OS bundle execution and the actual stored-key workflow-dispatch probe remain hosted qualification steps after this PR is merged; they are not represented as locally completed.

Security and scope

This change preserves exact-tag signature verification and the exact-ref OSV gate. It does not change release versions, the updater public key, branch protection, security waivers, or native OS code-signing claims. A partially uploaded draft is never marked public; only the same tag's unpublished draft can be resumed after the full local asset gate passes.

Related: #1201, #574, #575.

Summary by Sourcery

Harden desktop release publishing so only complete, cryptographically verified, and exactly matched assets can become public.

New Features:

  • Add a protected-main signing preflight that validates the configured updater key with valid, tampered, and wrong-key signatures.
  • Require and validate the complete Linux, Windows, and Apple Silicon release asset matrix, including installer signatures, SBOMs, notices, and updater metadata.

Bug Fixes:

  • Prevent incomplete, malformed, mismatched, or cryptographically invalid desktop assets from being published.
  • Prevent overwriting an already published release for an existing tag.

Enhancements:

  • Stage releases as drafts and verify the uploaded and published inventories, sizes, and SHA-256 digests before and after publication.

CI:

  • Harden the Tauri release workflow with fail-closed asset collection, pre-upload signature verification, exact updater manifest validation, and protected release publication checks.

Documentation:

  • Document the signed desktop release flow, draft publication safeguards, and current platform matrix.

Tests:

  • Add coverage for release asset completeness, updater manifest validation, remote inventory verification, and workflow security policy.

Chores:

  • Update documented test-count metrics and the unreleased changelog.

Summary by cubic

Tightens desktop release publishing so only a complete, cryptographically verified asset set becomes public. Releases are staged as drafts, compared against the validated local inventory and SHA-256 digests, and published only on exact match; existing published tags are never overwritten.

  • Requires the full installer matrix (Linux deb/rpm/AppImage, Windows setup/MSI, macOS dmg and updater archive), per-target SBOMs, and third-party notices before a draft can be created.
  • Verifies every signed updater payload against the public key in tauri.conf.json in each bundle job and validates all three latest.json entries against expected URLs and signature sidecars.
  • Adds a workflow_dispatch preflight on protected main that signs a throwaway payload and proves valid, tampered, and wrong-key outcomes without publishing artifacts.
  • Stages the release as a draft, reads back uploaded asset sizes and digests via release-assets-guard.mjs remote, and fails closed on missing, extra, empty, mismatched, or malformed files; revalidates the staged tag and inventory immediately before publication, and again after the draft becomes public.
  • Matches both space and dot spellings of Tauri bundle basenames while rejecting ambiguous duplicates, and dispatches CLI modes only through own properties so inherited Object entries cannot bypass validation.

Written for commit 1f748f1. Summary will update on new commits.

View guided diff Turn on auto-fix

Summary by CodeRabbit

  • Release Reliability
    • Releases are published only after required platform installers, signatures, and supporting files pass validation.
    • Uploaded assets are checked against the expected inventory and file digests before publication.
    • Existing published releases are not overwritten, and releases are staged as drafts before publication.
    • Manual signing checks are available for runs on the protected main branch.
  • Documentation
    • Updated desktop release guidance and reported test totals.
  • Tests
    • Added coverage for release files, updater manifests, uploaded assets, and workflow policies.

CodeAnt-AI Description

Require complete, verified desktop assets before publishing releases

What Changed

  • Tag releases now require the full Linux, Windows, and Apple Silicon installer, signature, software inventory, and notices set, with updater entries for exactly those supported platforms.
  • Updater packages are verified before upload. Releases stay unpublished until the uploaded files match the validated inventory, and published releases for the same tag cannot be overwritten.
  • A protected-main preflight checks that the configured updater key accepts valid signatures and rejects tampered or wrong-key signatures, without publishing assets.

Impact

✅ Fewer incomplete desktop releases
✅ Verified updater downloads for Linux, Windows, and Apple Silicon
✅ Published release tags protected from overwrite

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

qnbs added 4 commits November 8, 2026 13:28
Require the full installer, updater, SBOM, and notices matrix; validate every latest.json platform binding and sidecar before publication. Upload as a draft, verify the remote asset inventory and SHA-256 digests, then publish only the verified draft. Add a protected-main probe that signs a throwaway payload and checks the stored updater key against the embedded public key.
Refresh the generated test and file counts after adding the release asset guard regression suite.
Declare the release helper contract for TypeScript and make manifest and upload fixtures safe under unchecked-index access.
Verify each tagged Linux, Windows, and macOS updater payload against the embedded minisign public key before uploading bundle artifacts. Document and guard the per-target signature checks.
@vercel

vercel Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
worldscript-studio Ready Ready Preview Nov 8, 2026 2:30pm UTC

@codeant-ai

codeant-ai Bot commented Nov 8, 2026

Copy link
Copy Markdown

Skipping CodeAnt AI review — this PR is a back-merge between long-lived branches (release/tauri-assets-guard-20261108 → main). The diff here has already been reviewed when the underlying commits landed on the source branch, so re-running analysis would produce duplicate findings on already-reviewed code.

If you want to analyze this anyway (e.g. you resolved conflicts with new logic), comment @codeant-ai : review and CodeAnt will start a review.

@sourcery-ai

sourcery-ai Bot commented Nov 8, 2026

Copy link
Copy Markdown

Sorry @qnbs, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 3 hours and 55 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-08T14:31:13.633126Z 1f748f1 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Explain Change →

Warning

Review limit reached

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Next included review available in 27 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 79 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Learn how review limits work.

Review configuration:

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 7674f4f and 1f748f1.

Files selected for processing: 4

  • .github/workflows/tauri-build.yml
  • scripts/release-assets-guard.mjs
  • tests/unit/tooling/releaseAssetsGuard.test.ts
  • tests/unit/workflowPolicy.test.ts
Walkthrough

The Tauri release workflow adds signing preflight and bundle verification. A release guard validates asset names, updater manifests, and uploaded asset records. Tagged releases are staged as drafts and published after remote inventory and digest checks pass.

Changes: Tauri release integrity

Layer / File(s) Summary
Signing and bundle checks
.github/workflows/tauri-build.yml, tests/unit/workflowPolicy.test.ts
Manual dispatch on main tests updater signing and rejection cases. Tagged builds verify expected signed bundles before upload, and missing upload files fail the workflow.
Asset and manifest validation
scripts/release-assets-guard.*, tests/unit/tooling/releaseAssetsGuard.test.ts, README.md
The guard validates release asset names, updater manifests, and local and remote asset records. Unit tests cover validation failures and matching records. README test totals are updated.
Draft release and publication
.github/workflows/tauri-build.yml, tests/unit/workflowPolicy.test.ts, CHANGELOG.md, docs/TAURI-CI.md
The workflow collects and validates release assets, stages a draft, checks its uploaded inventory and digests, then publishes it. The changelog and CI documentation describe the release checks.
Merge Risk: Low · previous review 7674f

The release guard accepts an invalid CLI mode name and exits successfully. The workflow only uses valid modes, so the practical risk is small. Fix the lookup before merge as a quick hardening step.

@sourcery-ai

sourcery-ai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

Data structures

Declare the release-asset guard’s typed validation results and function contracts used by its TypeScript tests.

  • scripts/release-assets-guard.d.mts L1-52

Implementation

Implement the release-asset guard that validates the required asset matrix and updater manifest, generates latest.json, and compares local assets with the uploaded inventory and digests.

  • scripts/release-assets-guard.mjs L1-466

Configuration

Add the protected-main signing preflight and verify each tagged platform’s signed updater artifacts before uploading bundle assets.

  • .github/workflows/tauri-build.yml L130-179, L287-335, L343

Require the complete release asset set, validate updater manifests, stage releases as drafts, verify uploaded and pre-publication inventories, and confirm the final published state.

  • .github/workflows/tauri-build.yml L372, L394-447, L453-507

Documentation

Document the signing preflight, tagged-artifact verification, complete asset matrix, and draft-based publication checks in the Tauri CI guide.

  • docs/TAURI-CI.md L14-18, L102-120 (+4 small edits)

Record the desktop publishing requirements in the Unreleased changelog and synchronize the README’s generated test-count references.

  • CHANGELOG.md L10-11
  • README.md L23-1032 (4 small edits)

Tests

Test asset-matrix completeness, updater-manifest bindings, remote inventory and digest verification, and CLI mode validation.

  • tests/unit/tooling/releaseAssetsGuard.test.ts L1-254

Guard workflow policy for the signing preflight, per-platform artifact verification, and correctly ordered draft publication checks.

  • tests/unit/workflowPolicy.test.ts L35, L44-47, L422-537

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codeant-ai

codeant-ai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

View results CodeAnt  CodeAnt Quality Gate Results

Commit 1f748f1f · Scanned Nov 08, 2026 at 14:34 UTC

✅  Overall Status: PASSED

Quality Gate Status Details
New code coverage ⚪  Not applicable Not applicable — no applicable code changes
Secrets ✅  Passed 0 secrets found
Duplicate code ✅  Passed 0.0% duplicated
SAST ✅  Passed No security issues
Bugs ✅  Passed Rating S · No bugs
IaC ✅  Passed Rating S · No issues

@codeant-ai

codeant-ai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

View results CodeAnt  CodeAnt Coverage Report

Commit 1f748f1f · Scanned Nov 08, 2026 at 14:30 UTC

⚪  Overall Status: Not applicable

Coverage Status Details
New Code Coverage ⚪  Not applicable Not applicable — no applicable code changes

New-code coverage threshold not configured; coverage is reported but not enforced.

Record the complete desktop asset and updater-signature publishing contract in Unreleased notes.
@github-actions

github-actions Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

[check-pr-size] PR size is over the hard tier (normal profile): 8 files, 1252 meaningful lines, 14 commits — limit ≤20 files / ≤1200 lines / ≤10 commits. Consider splitting into smaller, independently reviewable PRs.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d8c4e7c85f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/tauri-build.yml Resolved
Comment thread .github/workflows/tauri-build.yml Resolved

qnbs commented Nov 8, 2026

Copy link
Copy Markdown
Owner Author

Independent PR #1202 exact-head admission checkpoint — 2026-11-08

Pinned current PR: head 6e24f667d3fc9c8c663937428051ce7bc2f29616, base protected main 5b04abff1fdc5bf6e88e7c18ed669803f2ae6026; 5 signed GitHub-Verified commits, 8 files, +816/-133 (949 meaningful lines; currently beyond the normal target 400 lines while still within the repository's separate absolute constraints). PR is OPEN / BLOCKED. Latest public release remains v1.29.2 (20 assets). Do not create v1.29.3 tag or merge on incomplete exact-head checks.

Validated improvement: tauri-build.yml now has per-target signed bundle checks, full 3-OS artifact inventory, exact three-platform latest.json, staged draft, GitHub uploaded-asset SHA-256 + size read-back, and only then draft publication. Previous v1.29.2 asset names and required 20-file classes were independently enumerated and align with the new patterns. Updater signing preflight is intentionally runnable only on protected main; actual stored-secret compatibility and 3-OS tag-time signing have not yet been proven by this PR's local fixtures.

Live red gates requiring source-level correction, no suppression: CodeScene Code Health Review (main) FAIL; scripts/release-assets-guard.mjs health=7.17, including complex validateLatestManifest (CC=26), main (CC=20), validateReleaseAssetNames (CC=10), nested conditionals and critical Bumpy Road Ahead. CodeFactor FAIL (1 new Minor finding). CodeAnt SAST/quality is green, verified-signature check SUCCESS, CodeQL SUCCESS; Node22 and Node24 quality in progress. There are 11 unresolved CodeScene inline findings. Break up conditional-heavy validation and mode dispatch without changing semantics or suppressing rules; preserve negative tests, explicit fail-closed logic and the no-publish-on-invalid-input boundary. Confirm the actual CodeFactor issue before deciding its disposition. Given file and commit targets, prefer a single reviewed cohesive correction on the current PR; split only when absolute admission limits force it, without weakening proof.

Hosted proof still required: current-head CI/CD full matrix and reviewer epochs, exact-main protected merge; then a safe, nonpublishing workflow_dispatch on resulting main that proves TAURI_SIGNING_PRIVATE_KEY matches tauri.conf.json embedded public key with valid / tampered / wrong-key cases. A manual dispatch produces unsigned updater artifacts and cannot stand in for actual tagged signed builds. Before the release tag: 3-OS packaged candidate, OSV on all three lockfiles, changelog/version truth, prior v1.29.2 updater compatibility, and full RELEASE_READY=YES checklist in #1201. Only then tag/publish/read back. Never rotate the updater key because a GitHub RELEASE_PAT was renewed.

Current Vercel authenticated read-only inventory: 47 (19 Production, 18 CANCELED previews, 10 READY previews), reflecting PR-preview churn; all three production aliases remain correctly bound to exact current-main READY deployment dpl_2uARW4n8XroLoJ3aeqRyR1jzaGri. Provider counts are not a new destructive retention authorization.

This is review/issue coordination only; no code, release, branch, deployment or signing-secret mutation performed.

Split manifest, asset inventory, and CLI handling into focused validators; stream SHA-256 calculation for large installers. Preserve artifact paths, verify published state after the final visibility update, and keep incomplete uploads unpublished.
@qnbs

qnbs commented Nov 8, 2026

Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

@codeant-ai

codeant-ai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

CodeAnt  CodeAnt Review Status

✅  Review completed

Status Commit Started (UTC) Finished (UTC)
✅  #91324 Reviewed your PR 1f748f1 Nov 08, 2026 · 14:29 14:34
✅  #c933c Reviewed your PR 954e3b5 Nov 08, 2026 · 14:26 14:31
✅  #d85e8 Reviewed your PR 27842df Nov 08, 2026 · 14:10 14:14
✅  #7e9c7 Reviewed your PR a500922 Nov 08, 2026 · 13:38 13:44
✅  #8d6c1 Reviewed your PR fd188ab Nov 08, 2026 · 13:06 13:12

@codeant-ai

codeant-ai Bot commented Nov 8, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added the size:XL This PR changes 500-999 lines, ignoring generated files label Nov 8, 2026
codescene-access[bot]

This comment was marked as outdated.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Nitpick comments: 1

scripts/release-assets-guard.mjs: 1

199-300: Trivial · Maintainability & Code Quality · Quick win

Add a test for the CLI main dispatch, or refactor it into per-mode handlers.

main has CC=20 according to the PR notes. It combines directory reading, sidecar loading, and four mode branches in one function. The CLI modes (generate, validate, remote) are the fail-closed publish path, and no test covers them. A parsing error in the remote TSV path, for example, would only surface at tag time.

Split main into runAssets, runGenerate, runValidate, and runRemote handlers. Share the latest.json read and validation between validate and remote. This also addresses the CodeScene gate failure without suppressions.

Source: Pipeline failures

Review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 5b04abf and 6e24f66.

Files selected for processing: 8

  • .github/workflows/tauri-build.yml
  • CHANGELOG.md
  • README.md
  • docs/TAURI-CI.md
  • scripts/release-assets-guard.d.mts
  • scripts/release-assets-guard.mjs
  • tests/unit/tooling/releaseAssetsGuard.test.ts
  • tests/unit/workflowPolicy.test.ts

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Comment thread .github/workflows/tauri-build.yml Resolved
Comment thread scripts/release-assets-guard.mjs Resolved
Comment thread tests/unit/workflowPolicy.test.ts Resolved
Replace mapfile with a Bash 3 compatible null-delimited loop and use the pinned release action's returned ID for draft verification, publication, and final readback. Further flatten remote inventory validation without weakening checks.
Comment thread docs/TAURI-CI.md Resolved
@codeant-ai

codeant-ai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

CodeAnt  CodeAnt Nitpicks

1 code suggestion

1. A writer can change the draft after this inventory passes but before the PATCH, briefly publishing unverified assets; the later check detects this only afterward.

Race condition · .github/workflows/tauri-build.yml:487-491

Update the generated test-count badges and references to the current Vitest source set.
@qnbs

qnbs commented Nov 8, 2026

Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

@codeant-ai

codeant-ai Bot commented Nov 8, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

codescene-access[bot]

This comment was marked as outdated.

@codeant-ai codeant-ai Bot added size:XXL This PR changes 1000+ lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels Nov 8, 2026
Comment thread .github/workflows/tauri-build.yml Resolved
qnbs added 2 commits November 8, 2026 14:52
Exercise remote verification against the complete desktop asset matrix and require the published-tag refusal step to remain ordered before draft staging.
Refresh the source-derived README test metric after adding the complete release inventory regression.
codescene-access[bot]

This comment was marked as outdated.

qnbs commented Nov 8, 2026

Copy link
Copy Markdown
Owner Author

Follow-up on the CodeAnt suggestions from the previous head. Commit 32bf3362 adds a remote-inventory regression using the full release asset matrix (including latest.json) and proves that omitting a required installer fails. The workflow-policy test now requires the published-tag refusal step and checks that it runs before draft staging.

For the race finding, the publish step already re-fetches the staged tag, draft state, and complete paginated asset inventory, then validates every size and SHA-256 immediately before the draft=false PATCH. The workflow also serializes runs by ref; the published-state and asset readback is an additional postcondition. The release PATCH has no inventory-digest precondition to make that multi-request sequence atomic, so a privileged out-of-band writer in the narrow interval remains governed by the single-writer release lease.

@CodeAnt-AI review

@codeant-ai

codeant-ai Bot commented Nov 8, 2026

Copy link
Copy Markdown

Question: follow-up on the codeant suggestions from the previous head. commit 32bf3362 adds a remote-inventory regression using the full release asset matrix (including latest.json) and proves that omitting a required installer fails. the workflow-policy test now requires the published-tag refusal step and checks that it runs before draft staging.

for the race finding, the publish step already re-fetches the staged tag, draft state, and complete paginated asset inventory, then validates every size and sha-256 immediately before the draft=false patch. the workflow also serializes runs by ref; the published-state and asset readback is an additional postcondition. the release patch has no inventory-digest precondition to make that multi-request sequence atomic, so a privileged out-of-band writer in the narrow interval remains governed by the single-writer release lease.

review

Answer:

[P2] Make the single-writer assumption explicit or enforce it — .github/workflows/tauri-build.yml:485–489

The final inventory is fetched and validated before draft=false, but that validation is not atomic with the PATCH. A privileged writer could add, remove, or replace an asset after the inventory check and before publication. The post-publication check would detect the mismatch only after the release was already public; it does not return the release to draft. The workflow’s concurrency group coordinates this workflow’s runs, not UI edits or writes from other workflows.

So the claimed “only publish the verified inventory” guarantee depends on the stated single-writer lease actually excluding those out-of-band writers. If that is an accepted trust assumption, document it as such; otherwise, this race remains unresolved. The added regression and step-ordering checks do cover the missing-asset and published-tag cases.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Nitpick comments: 1

tests/unit/workflowPolicy.test.ts: 1

477-513: Trivial · Functional Correctness · Low value

The ordering assertions compare indexOf values in the whole release block, so a stray earlier match can satisfy them.

release.indexOf('Publish the verified complete draft') and similar calls match the first occurrence of the text. The text can also appear in comments or in needs or if expressions. The sorted-order check can then pass although the real step order is wrong. The prepublishIndexes check has the same weakness: publish.indexOf('gh api --paginate --jq') matches the first occurrence only.

Anchor each lookup on the step header form - name: <name>. This also matches the helper contract in extractStepBlock.

Proposed fix

-      release.indexOf('Refuse to overwrite a published release'),
-      release.indexOf('Stage GitHub Release as a draft'),
+      release.indexOf('      - name: Refuse to overwrite a published release'),
+      release.indexOf('      - name: Stage GitHub Release as a draft'),

Apply the same - name: prefix to the other step names in releaseStepIndexes.

Review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 6e24f66 and 7674f4f.

Files selected for processing: 8

  • .github/workflows/tauri-build.yml
  • CHANGELOG.md
  • README.md
  • docs/TAURI-CI.md
  • scripts/release-assets-guard.d.mts
  • scripts/release-assets-guard.mjs
  • tests/unit/tooling/releaseAssetsGuard.test.ts
  • tests/unit/workflowPolicy.test.ts
Files skipped from review as they are similar to previous changes: 3

  • CHANGELOG.md
  • README.md
  • docs/TAURI-CI.md

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Comment thread scripts/release-assets-guard.mjs Resolved
Match both exact space and dot spellings of Tauri bundle basenames while rejecting ambiguous matches. Require an own CLI mode handler so inherited Object properties cannot bypass validation, with regression coverage for both cases.

qnbs commented Nov 8, 2026

Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

@codeant-ai

codeant-ai Bot commented Nov 8, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

codescene-access[bot]

This comment was marked as outdated.

Bind workflow sequencing assertions to actual YAML step headers and shell commands so comments or unrelated expressions cannot satisfy the gate.

Split CLI argument parsing from dispatch to keep release-guard complexity below the CodeScene threshold without changing validation behavior.
@qnbs

qnbs commented Nov 8, 2026

Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

@codeant-ai

codeant-ai Bot commented Nov 8, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

codescene-access[bot]

This comment was marked as outdated.

Separate required argument checks from own-property mode resolution so the release guard stays below the CodeScene complexity threshold without relaxing invalid-mode handling.
@qnbs

qnbs commented Nov 8, 2026

Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

@codeant-ai

codeant-ai Bot commented Nov 8, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codescene-access codescene-access Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gates Passed
3 Quality Gates Passed

See analysis details in CodeScene

Quality Gate Profile: The Bare Minimum
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

@qnbs

qnbs commented Nov 8, 2026 •

Copy link
Copy Markdown
Owner Author

The ordering-test finding is addressed in commit 954e3b56: publication steps now resolve from exact YAML step headers, and the pre-publication sequence is anchored to executable shell-command lines plus the fetched release-assets endpoint and output. The release-guard dispatch is split into required-argument validation and own-property handler resolution in 1f748f1f, preserving inherited-mode rejection. The focused release/workflow suites pass (89 tests); CodeScene reports all three gates passed on the current head.

qnbs commented Nov 8, 2026

Copy link
Copy Markdown
Owner Author

2026-11-08 ~15:40 CET — exact-head 14/15 commit budget: STOP/merge-first owner instruction

Live authoritative state: PR #1202 OPEN, head=1f748f1f10a1f0d58bf74015d8626654f9bb7667, base=5b04abff1fdc5bf6e88e7c18ed669803f2ae6026, 14 of 15 permitted commits, 14/14 GitHub Verified, 8 changed files, +1118/-134, size:XXL label while PR Size Governance check SUCCESS. Every 10/10 inline review thread RESOLVED (not a waiver of exact-head CI). Current exact-head checks: 26 PASS, 0 FAIL, two required Node gates still IN_PROGRESS: CI #42490059304, Node24 on Codecov upload, Node22 on Vitest; exact-head CodeQL #42490059291 SUCCESS. CodeScene latest 3/3 gates APPROVED; CodeFactor, Semgrep, Security Audit, verified signatures, workflow policy and reviewer governance SUCCESS. mergeable_state=blocked as of this observation. Do not mark admitted or merge until the last exact-head checks and branch-protection state go green.

Immediate instructions to sole authorized local VS Code Codex CLI operator

  1. Freeze current head; no speculative commits, CI retriggers, repetitive pushes, or unrelated polishing. The two Node jobs are progressing without a failure. Avoid new push just to churn bot reviews. Retain the explicit 15-commit budget; do not rewrite signed history, squash/rebase/force-push to cosmetically reset the count, suppress CodeScene, or bypass protected-gate constraints. Keep all security provenance and no-personal-identity rules.
  2. If both Node22/Node24 and every required exact-head CI/CodeQL/Semgrep/security/reviewer gate succeed, reconfirm 10/10 review threads resolved, mergeable_state and protected requirements against head 1f748f1f. Merge this PR via the repository's approved signed protected route, without spending commit chore(deps): bump ossf/scorecard-action from 2.4.0 to 2.4.3 #15 for administrative changes. If review epoch is still pending, allow it to complete but don't block on optional rate-limited Sourcery/CodeRabbit when governed required gates already pass; do not confuse optional check with mandatory.
  3. If a reproducible P0/P1 defect genuinely requires a code change, make at most one remaining focused signed commit on ci(release): require complete, verified desktop assets before publishing #1202, using authenticated CodeScene CLI preflight, focused 89-test release/workflow suite, full ci:prepush, diff/check/policy and single batched push. Count actual commits after pushing. If chore(deps): bump ossf/scorecard-action from 2.4.0 to 2.4.3 #15 is reached and another correction is needed, STOP modifying this PR; document failing exact-head evidence and a bounded successor branch/PR for outstanding changes; retain ci(release): require complete, verified desktop assets before publishing #1202 unmerged if it still contains a release-integrity blocker. Never treat a successor as permission to merge a known-unsafe base. Avoid an XXL cascading chain: identify minimal must-fix, decide whether a cohesive verified ci(release): require complete, verified desktop assets before publishing #1202 is mergeable, otherwise hand off narrowly with dependencies.
  4. Postmerge verify new main SHA, push CI/CD+CodeQL, Pages public freshness, exact-SHA Vercel Production READY and all three canonical aliases, then canonical Node22 SAFE-only ci(vercel): prune stale Preview deployments after PR closure #627 retention with fully paginated classification, UNKNOWN=0, protected postproof. Recent read-only Vercel inventory is 54 deployment records (19 Production, 24 CANCELED + 11 READY Previews), due PR churn; not an authorization to delete active/unknown Preview or any Production/rollback.
  5. Critical next hosted proof before v1.29.3: tauri-build.yml nonpublishing workflow_dispatch on verified protected resulting main must sign an isolated probe using the stored TAURI_SIGNING_PRIVATE_KEY, validate against the unchanged shipped tauri.conf.json updater public key, reject tampered/wrong-key cases. Record run ID, SHA and gate outcomes. The toolchain probe + safe 3-OS workflow_dispatch are not substitutes for the later tagged signed installer matrix. Git RELEASE_PAT renewal is unrelated to this updater signing secret.
  6. Only then separate reviewed v1.29.3 release-prep PR per #1201: version/Cargo/lock/AGENTS sync, curated Unreleased changelog/release notes, exact-SHA three-OS candidate & SBOM/notices/packaged-state qualification, fresh OSV (document time-bound security(deps): retire conditional temporary OSV exceptions by 2026-11-30 #1163/security(osv): requalify 10 existing Rust waivers before 2026-11-30 expiry #1164 accepted risks expiring Nov 30), protected signed annotated release tag, tag-time Tauri+GHCR publishing and full 20-asset/signature/latest.json SHA256 read-back. Never tag before RELEASE_READY=YES. Keep build(deps): bump @reduxjs/toolkit from 2.12.0 to 2.13.0 in the npm-minor-patch group across 1 directory #1195 RTK 2.13 on HOLD due prototype-ID regression deps(redux): verify RTK 2.12.0 pin and Recharts reachability #1183.

No new GitHub issue or successor PR is necessary if the current green-gate merge succeeds at 14 commits. This is coordination only; no code/tag/branch/merge/provider write was performed.

@qnbs
qnbs merged commit 5295b16 into main Nov 8, 2026
49 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant