ci(release): publish Tauri updater latest.json on tag releases - #1372
ci(release): publish Tauri updater latest.json on tag releases#13720xbrayo wants to merge 1 commit into
Conversation
Sign aw-tauri bundles with TAURI_SIGNING_PRIVATE_KEY, collect per-platform updater artifacts, and generate latest.json for the Tauri updater endpoint when publishing draft releases. URLs use github.repository so they resolve to ActivityWatch/activitywatch on upstream runs.
Greptile SummaryAdds generation and publication of signed Tauri updater metadata during tag releases.
Confidence Score: 3/5This PR should not merge until tag metadata is moved out of executable shell source; the checkout action should also be pinned for release-path hardening. Any repository writer can push a matching tag, and the release job substitutes that tag directly into shell commands running in a contents-write workflow, making command execution reachable before draft release publication. Files Needing Attention: .github/workflows/release.yml
|
| Filename | Overview |
|---|---|
| .github/workflows/release.yml | Adds updater signing, artifact collection, manifest generation, and release upload, but directly embeds tag-controlled text into a privileged shell step and adds a mutable checkout dependency. |
| scripts/package/generate_latest_json.py | Builds a Tauri updater manifest from staged signature files and rejects empty manifests; no independently publishable defect was established in the configured release path. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
T["Push v* tag"] --> B["Build Tauri matrix"]
B --> S["Sign updater bundles"]
S --> P["Normalize updater artifacts"]
P --> D["Download build artifacts"]
T --> M["Interpolate tag metadata"]
M --> G["Generate latest.json"]
D --> G
G --> R["Create draft GitHub release"]
Reviews (1): Last reviewed commit: "ci(release): publish Tauri updater lates..." | Re-trigger Greptile
| --notes "ActivityWatch ${{ github.ref_name }}" \ | ||
| --repo "${{ github.repository }}" \ | ||
| --tag "${{ github.ref_name }}" \ |
There was a problem hiding this comment.
Tag name enables shell injection
When a repository writer pushes a v* tag containing shell syntax, github.ref_name is substituted directly into this script before shell parsing, causing embedded commands to execute in a release job with contents-write access. Pass the values through environment variables rather than embedding expressions in shell source.
How this was verified: The tag trigger accepts any v* name, the release condition only checks that prefix, and this step directly interpolates the resulting name into shell commands.
Knowledge Base Used: Packaging and release pipeline
| needs: [build-qt, build-tauri, release-notes] | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v7 |
There was a problem hiding this comment.
The new checkout step executes a mutable v7 action reference in a contents-write release job. Pinning it to a reviewed commit SHA prevents a subsequently moved tag from changing executable release automation.
How this was verified: This action runs before release generation and inherits the workflow's contents-write permission.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
|
This is a prerequisite for ActivityWatch/aw-tauri#68. |
Summary
Adds support for publishing a Tauri updater
latest.jsonmanifest (and signed updater artifacts) on tag releases from the unifiedrelease.ymlworkflow.TAURI_SIGNING_PRIVATE_KEYinto the Tauri build so bundles emit.sigfiles whencreateUpdaterArtifactsis enabled in aw-tauriactivitywatch-tauri-<version>-<platform>.<ext>[.sig]latest.jsonviascripts/package/generate_latest_json.pyduring the draft release joblatest.jsonand updater assets alongside existing release filesDownload URLs are built from
${{ github.repository }}/${{ github.ref_name }}, so on upstream they point at:https://github.com/ActivityWatch/activitywatch/releases/latest/download/latest.jsonPrerequisites (org secrets / aw-tauri)
This CI path is ready, but end-to-end updates also need:
TAURI_SIGNING_PRIVATE_KEY(and optionalTAURI_SIGNING_PRIVATE_KEY_PASSWORD)createUpdaterArtifacts: true, the matching public key, and endpoint:https://github.com/ActivityWatch/activitywatch/releases/latest/download/latest.jsonWithout signing / updater artifacts, the generate step fails intentionally (no empty manifest).
Test plan
.sigfiles), verifylatest.jsonplatform keys and asset URLslatest.json+.sigassets appear on the draft release