Skip to content

Add signed cross-platform updater lifecycle - #547

Merged
enaboapps merged 4 commits into
mainfrom
agent/signed-updater-532
Aug 10, 2026
Merged

Add signed cross-platform updater lifecycle#547
enaboapps merged 4 commits into
mainfrom
agent/signed-updater-532

Conversation

@enaboapps

@enaboapps enaboapps commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Addresses #532. The issue remains open until the signed Alpha-to-Beta installation is verified on both platforms.

What changed

  • adds startup, recurring, and manual checks with deduplicated update operations
  • exposes accessible available, downloading, ready, applying, current, cancelled, unconfigured, and failed states
  • adds verified progress, cancellation, retry, install cleanup, and restart controls
  • puts download/install behavior behind a fakeable Rust artifact adapter
  • consolidates macOS and Windows production publication into one pinned, tag-driven workflow
  • preserves Developer ID notarization, Windows UIAccess/Certum signing, and the public C# v0.10.0 feed
  • constrains feed inputs to the expected platform downloads and validates package structure
  • cryptographically verifies both Tauri updater signatures against the production public key before publishing update-feed/latest.json

Configuration completed

  • generated and protected the long-lived Tauri updater signing key
  • configured TAURI_UPDATER_PUBLIC_KEY
  • configured protected updater private-key secrets in the production environment
  • reused the existing Developer ID/App Store Connect production credentials

Validation

  • npm run lint
  • npm test (45 frontend tests plus 4 release-feed tests)
  • npm run build
  • cargo fmt --manifest-path src-tauri/Cargo.toml --check
  • cargo clippy --locked --manifest-path src-tauri/Cargo.toml --all-targets -- -D warnings
  • cargo test --locked --manifest-path src-tauri/Cargo.toml (135 tests plus config tests)
  • updater-signature verifier fmt, Clippy, and 2 Rust tests
  • actionlint 1.7.12 with the repository self-hosted runner label configured
  • real Tauri-generated signature verification plus malformed-signature, wrong-format payload, malformed-tag, and update-feed regression fixtures
  • local signed macOS updater archive generation with the production updater key

Remaining release validation

The A9 Max switchify-signing runner is currently offline. Once it is online with SimplySign authenticated, publish/install v1.0.0-alpha.1, merge this PR after review, publish v1.0.0-beta.1, and prove the signed in-app update on macOS and Windows before closing #532.

@enaboapps

Copy link
Copy Markdown
Contributor Author

@greptileai review current head 6a9d247. Please review the updater state machine, operation concurrency/cancellation, install cleanup, UI accessibility, and credential-gated release/feed workflow. This PR intentionally does not close #532 because real signed publication remains credential-blocked.

@greptile-apps

greptile-apps Bot commented Aug 8, 2026

Copy link
Copy Markdown

Greptile Summary

This change adds signed macOS and Windows update publication, release-tag validation, and a verified updater feed.

Two previously reported release issues are no longer present. A malicious manually dispatched release tag containing a quote and command substitution was rejected without executing its payload, and the release preparation job does not expose signing or notarization secrets. A structurally valid-looking updater artifact with a nonempty invalid signature was rejected by the compiled signature verifier before latest.json could be written.

The updater lifecycle also preserves completed downloads for installation while ensuring a cancelled download cannot be installed without downloading it again.

Confidence Score: 5/5

No blocking failure remains.

The exercised release-tag, signature-verification, and cancelled-download paths behaved as intended.

T-Rex T-Rex Logs

What T-Rex did

  • Ran the release-tag resolver with a valid dispatched tag and with a tag containing a single quote and command substitution, observing normal tag, version, and ref outputs for the valid input and a validation failure with no payload execution for the malicious input.
  • Created macOS gzip and Windows PE fixtures with nonempty invalid signatures, then ran updater-feed feed generation; verified that verification occurs before the feed write and that latest.json is absent after the failure, while the focused updater-feed tests pass.
  • Ran a focused Rust harness against the updater module to exercise completed and cancelled download flows; observed that completed downloads retain bytes for installation, cancelled downloads return Cancelled and install requires a fresh download, confirming that cancelled update data is not available for installation.
  • Compared exact malicious observed output with baseline; captured test sources and command outputs to verify the malicious path is rejected correctly and that baseline behavior emits a valid tag and ref; multiple artifacts support these observations.
  • Validated the updater-lifecycle harness results for completion and cancellation paths, including the harness source and the corresponding logs, confirming expected exit codes and install-byte behavior.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (5): Last reviewed commit: "Verify updater artifacts before publishi..." | Re-trigger Greptile

Comment thread .github/workflows/release-tauri.yml Outdated
@enaboapps

Copy link
Copy Markdown
Contributor Author

@greptileai review current head. The dispatch input is now passed only through VERSION_INPUT and validated as data. The prepare job has no secrets; production credentials are scoped only to explicit validation/signing steps in their platform jobs. README also distinguishes ephemeral CI validation keys from production material.

@enaboapps

Copy link
Copy Markdown
Contributor Author

Latest head 81fd8b0 is fully green:

  • Greptile 5/5, including executable shell-injection validation
  • frontend CI passed
  • macOS app/DMG CI passed
  • Windows NSIS/UIAccess CI passed
  • local lint, 43 frontend tests, build, fmt, Clippy, 128 Rust tests, unsigned app bundle, and release-overlay updater archive validation passed

Keeping this PR draft and #532 open until the documented production signing credentials, release runner, and real signed install test are available.

@enaboapps
enaboapps force-pushed the agent/signed-updater-532 branch from 81fd8b0 to 22cb5aa Compare August 9, 2026 21:07
@enaboapps

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread scripts/create-update-feed.mjs Outdated
@enaboapps

Copy link
Copy Markdown
Contributor Author

@greptileai please run a full review of the current head, including the updater artifact verification and release workflow changes.

@enaboapps

Copy link
Copy Markdown
Contributor Author

Current head 41eedc7 is green:

  • Greptile 5/5 with executable Tauri signature/tamper validation
  • frontend CI passed
  • macOS app/DMG CI passed
  • Windows NSIS/UIAccess CI passed
  • all review threads are resolved/outdated

The PR remains draft and #532 remains open. The only outstanding milestone item is the real signed Alpha-to-Beta install/update test, which requires the currently offline a9-max-switchify-signing runner with SimplySign authenticated.

@enaboapps
enaboapps marked this pull request as ready for review August 10, 2026 08:20
@enaboapps
enaboapps merged commit 22459de into main Aug 10, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant