ci: skip downstream jobs when their area is unchanged#89
Merged
Conversation
Add a 'changed' job using dorny/paths-filter@v3 that emits per-area booleans (rust/web/tray/openapi/tauri). Each downstream job gates itself via 'if: needs.changed.outputs.<area> == true' on top of the existing should-run commit-message gate. Docs-only commits, single-area changes (e.g. web-only docs sweep), and tree-touching commits that miss a particular workload (e.g. a crates/starstats-server change skips tray-ui + tauri-client) now avoid spinning up the unaffected jobs. Stacks with the existing concurrency cancel-chain so small bursts of commits to next/main don't burn Rust/Tauri matrix minutes on no-op work. Job names still report in every run (skipped, not absent), so this is forward-safe for required-status-check branch protection.
9 tasks
ntatschner
pushed a commit
that referenced
this pull request
May 23, 2026
Decouples the Tauri tray installer cadence from the server + web
container image cadence. Each track now has its own version number,
its own tag schema, its own auto-alpha trigger, and ships through its
own workflow:
- tray: tag tray-vX.Y.Z[-channel.N] -> release.yml
version in crates/starstats-client/Cargo.toml + tauri.conf.json
updater manifest at release-manifests/tray-{channel}.json
- platform: tag vX.Y.Z[-channel.N] -> release-images.yml (unchanged)
version in workspace [workspace.package], inherited by
starstats-core + starstats-server
no auto-update manifest (homelab pulls floats via Komodo)
Glob non-overlap: GitHub's 'v*' anchors at start, so 'tray-v*' never
fires release-images.yml. No tags-ignore needed.
Web-only changes no longer churn the tray's signed MSI / channel
manifest. Tray bug fixes no longer force a server redeploy.
Key changes:
- scripts/release-promote.mjs: every prerelease/live subcommand now
takes a <tray|platform> track argument. New pure helpers tagPrefix,
parseTrackTag, bumpClientCargo. latestSemverFromTags accepts an
optional track filter. 49 new unit tests cover the track plumbing
(67 total, all green).
- crates/starstats-client/Cargo.toml: switched from
'version.workspace = true' to literal 'version = "1.8.4"' so the
client floats independently. starstats-client -> starstats-core dep
is a path dep so version skew is irrelevant.
- release.yml: trigger 'tray-v*', validate-tag strips the prefix,
manifest path is release-manifests/tray-<channel>.json. New step
generates a per-component changelog (git log filtered to tray paths
since the previous tray-v* tag) and injects into the GH Release body
via body_path instead of GH's auto-generated notes (which would
otherwise pick the literal previous tag — possibly a platform vX.Y.Z
— and leak platform-only commits into the tray release body).
- promote.yml: new detect-tracks setup job. workflow_dispatch takes a
track input (tray|platform|both). Push-to-next auto-alpha uses
dorny/paths-filter@v3 to bump only the tracks whose files changed;
docs-only pushes tag nothing. starstats-core triggers both tracks.
Self-bump commits are skipped to break the loop (mirrors ci.yml).
- ci.yml: should-run skip list adds 'chore: bump tray to ' and
'chore: bump platform to ' for the new bot-commit message format.
- release-manifests/{alpha,beta,rc,live}.json renamed to
release-manifests/tray-{alpha,beta,rc,live}.json (git mv, history
preserved). Tray client manifest_url() + tauri.conf.json updater
endpoint updated to match.
- apps/web: platform version surfaced in a sub-footer chip on both
signed-in + marketing layouts. Build-time inlined via next.config.mjs
env block, sourced from workspace Cargo.toml.
- CLAUDE.md branch model section + docs/RELEASING.md quick-reference
table updated. Full design spec at
docs/superpowers/specs/2026-05-23-release-tracks-split.md.
Migration: one-time. Old in-the-wild tray installers point at
release-manifests/<channel>.json which now 404s; users re-download
+ re-pair from the latest GH release. Acceptable per internal/dogfood
deployment posture.
Out of scope (future PRs): platform GH releases with their own
changelog; release-notes/<track>/<version>.md narrative summaries;
roadmap-emit track-aware slugs.
Depends on PR #89 (ci.yml path filters) for the ci.yml conflict — if
this lands first, #89 rebases trivially on top.
See docs/superpowers/specs/2026-05-23-release-tracks-split.md.
ntatschner
added a commit
that referenced
this pull request
May 24, 2026
) Decouples the Tauri tray installer cadence from the server + web container image cadence. Each track now has its own version number, its own tag schema, its own auto-alpha trigger, and ships through its own workflow: - tray: tag tray-vX.Y.Z[-channel.N] -> release.yml version in crates/starstats-client/Cargo.toml + tauri.conf.json updater manifest at release-manifests/tray-{channel}.json - platform: tag vX.Y.Z[-channel.N] -> release-images.yml (unchanged) version in workspace [workspace.package], inherited by starstats-core + starstats-server no auto-update manifest (homelab pulls floats via Komodo) Glob non-overlap: GitHub's 'v*' anchors at start, so 'tray-v*' never fires release-images.yml. No tags-ignore needed. Web-only changes no longer churn the tray's signed MSI / channel manifest. Tray bug fixes no longer force a server redeploy. Key changes: - scripts/release-promote.mjs: every prerelease/live subcommand now takes a <tray|platform> track argument. New pure helpers tagPrefix, parseTrackTag, bumpClientCargo. latestSemverFromTags accepts an optional track filter. 49 new unit tests cover the track plumbing (67 total, all green). - crates/starstats-client/Cargo.toml: switched from 'version.workspace = true' to literal 'version = "1.8.4"' so the client floats independently. starstats-client -> starstats-core dep is a path dep so version skew is irrelevant. - release.yml: trigger 'tray-v*', validate-tag strips the prefix, manifest path is release-manifests/tray-<channel>.json. New step generates a per-component changelog (git log filtered to tray paths since the previous tray-v* tag) and injects into the GH Release body via body_path instead of GH's auto-generated notes (which would otherwise pick the literal previous tag — possibly a platform vX.Y.Z — and leak platform-only commits into the tray release body). - promote.yml: new detect-tracks setup job. workflow_dispatch takes a track input (tray|platform|both). Push-to-next auto-alpha uses dorny/paths-filter@v3 to bump only the tracks whose files changed; docs-only pushes tag nothing. starstats-core triggers both tracks. Self-bump commits are skipped to break the loop (mirrors ci.yml). - ci.yml: should-run skip list adds 'chore: bump tray to ' and 'chore: bump platform to ' for the new bot-commit message format. - release-manifests/{alpha,beta,rc,live}.json renamed to release-manifests/tray-{alpha,beta,rc,live}.json (git mv, history preserved). Tray client manifest_url() + tauri.conf.json updater endpoint updated to match. - apps/web: platform version surfaced in a sub-footer chip on both signed-in + marketing layouts. Build-time inlined via next.config.mjs env block, sourced from workspace Cargo.toml. - CLAUDE.md branch model section + docs/RELEASING.md quick-reference table updated. Full design spec at docs/superpowers/specs/2026-05-23-release-tracks-split.md. Migration: one-time. Old in-the-wild tray installers point at release-manifests/<channel>.json which now 404s; users re-download + re-pair from the latest GH release. Acceptable per internal/dogfood deployment posture. Out of scope (future PRs): platform GH releases with their own changelog; release-notes/<track>/<version>.md narrative summaries; roadmap-emit track-aware slugs. Depends on PR #89 (ci.yml path filters) for the ci.yml conflict — if this lands first, #89 rebases trivially on top. See docs/superpowers/specs/2026-05-23-release-tracks-split.md. Co-authored-by: Nigel Tatschner <n Tatschner@gmail.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.
Summary
changedjob usesdorny/paths-filter@v3to emit per-area booleans (rust/web/tray/openapi/tauri).if:now ANDs the existingshould-rungate withneeds.changed.outputs.<area> == 'true', so unchanged areas skip entirely..github/workflows/ci.ymlitself, so a workflow tweak never silently skips its own validation.crates/starstats-coreis shared by bothopenapiandtaurifilters;apps/tray-uiis in bothtrayandtauri(the latter becausetauri::generate_context!validatesfrontendDistexists at compile time, per the project CLAUDE.md note);packages/api-client-tsis inweb+openapionly (tray-ui talks to Rust via Tauriinvoke, not the generated TS schema);packages/**is included broadly forweb/trayso future shared packages don't need a CI rev.Why
Stacks with the existing concurrency cancel-chain (per the CLAUDE.md "Build & Test cancel-chain on
main" note) — small bursts of bookkeeping commits tomain/next(release-manifest auto-commits, docs catch-ups, fmt-fixes) no longer burn Rust/Tauri matrix minutes on no-op work. The currentshould-rungate already drops bot-bookkeeping commits; this generalises the cost-saving to any human commit that's scoped to a single subsystem.Why per-job filter (not workflow-level
on: paths:)Workflow-level path filters skip the entire run, which leaves required status checks missing rather than green — breaks merges once you wire up the branch-protection snippet in
docs/RELEASING.md. The per-job pattern keeps every job name reporting (skipped counts as concluded for required-check purposes), so this change is forward-safe.Test plan
changedjob in CI; verify all 6 downstream jobs run (the workflow file itself changed, which matches every filter group).README.mdordocs/**); verifyrust/web/tray/openapi/tauriall skip whileshould-run+changedstill run.crates/starstats-server/**change; verifyrust+openapi-drift+tauri-clientrun,web/web-e2e/tray-uiskip.apps/web/**change; verifyweb+web-e2erun,rust/tray-ui/tauri-client/openapi-driftskip.apps/tray-ui/**change; verifytray-ui+tauri-clientrun,rust/web/web-e2e/openapi-driftskip.