mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
ci(rust): gate jobs with if: instead of a workflow-level paths filter (#2580)
Prerequisite for making `parity` a required status check on main. A workflow skipped by a top-level `paths:` filter never creates its check runs at all, so a required check sourced from it sits pending forever on any PR that misses those paths and the PR can never merge. A job skipped by `if:` still creates a check run, reports skipped, and GitHub counts skipped as success. Moves the seven path patterns verbatim from the `on:` block into a new `rust-changes` job (dorny/paths-filter) and gates all five existing jobs on `needs.rust-changes.outputs.rust == 'true'`. Named rust-changes, not changes, to avoid colliding with ci.yml's existing check. Job `name:` fields unchanged, so no check names move. schedule/workflow_dispatch force rust=true, preserving the nightly full-suite behaviour. CI spend unchanged: same jobs on the same PRs, plus a ~15s gate job on PRs that previously skipped the workflow outright. Verified by the PR itself — it edits rust.yml, which is in the path list, so it exercises the rust=true branch: rust-changes and parity both SUCCESS. Follow-up before adding parity to required checks: confirm a non-Rust PR reports parity as skipped rather than absent. ci.yml has the mirror-image problem (paths-ignore on docs) and is deliberately not addressed here.
This commit is contained in:
parent
85e8699451
commit
e562d007d8
1 changed files with 52 additions and 16 deletions
68
.github/workflows/rust.yml
vendored
68
.github/workflows/rust.yml
vendored
|
|
@ -1,25 +1,18 @@
|
|||
name: rust
|
||||
|
||||
# Path gating lives in the `rust-changes` job below, NOT in a workflow-level
|
||||
# `paths:` filter. The distinction matters for branch protection: a workflow
|
||||
# skipped by `paths:` never creates its check runs at all, so a required status
|
||||
# check from it sits pending forever on any PR that misses those paths, and the
|
||||
# PR can never merge. A job skipped by `if:` still creates a check run, reports
|
||||
# `skipped`, and GitHub counts skipped as success for a required check.
|
||||
#
|
||||
# Same coverage as the old filter — the path list moved verbatim into
|
||||
# `rust-changes` — but `parity` is now safe to mark required on `main`.
|
||||
on:
|
||||
push:
|
||||
branches: [ main, rust-rewrite ]
|
||||
paths:
|
||||
- 'crates/**'
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- 'rust-toolchain.toml'
|
||||
- 'tests/parity/**'
|
||||
- 'Makefile'
|
||||
- '.github/workflows/rust.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'crates/**'
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- 'rust-toolchain.toml'
|
||||
- 'tests/parity/**'
|
||||
- 'Makefile'
|
||||
- '.github/workflows/rust.yml'
|
||||
schedule:
|
||||
# Nightly parity run at 07:17 UTC (weekdays only). Redundant with the
|
||||
# per-PR gate below, but catches drift from toolchain/dependency updates
|
||||
|
|
@ -38,8 +31,43 @@ permissions:
|
|||
contents: read
|
||||
|
||||
jobs:
|
||||
# Carries the path list the workflow-level `paths:` filter used to hold. Named
|
||||
# `rust-changes` rather than `changes` so it does not collide with ci.yml's
|
||||
# `changes` check.
|
||||
rust-changes:
|
||||
name: rust-changes
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
outputs:
|
||||
rust: ${{ steps.decide.outputs.rust }}
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: dorny/paths-filter@v4
|
||||
id: filter
|
||||
if: github.event_name == 'pull_request' || github.event_name == 'push'
|
||||
with:
|
||||
filters: |
|
||||
rust:
|
||||
- 'crates/**'
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- 'rust-toolchain.toml'
|
||||
- 'tests/parity/**'
|
||||
- 'Makefile'
|
||||
- '.github/workflows/rust.yml'
|
||||
- id: decide
|
||||
# `schedule` and `workflow_dispatch` have no diff to filter against, so
|
||||
# they run the full suite — that is the point of the nightly job.
|
||||
run: |
|
||||
case "${{ github.event_name }}" in
|
||||
pull_request|push) echo "rust=${{ steps.filter.outputs.rust }}" >> "$GITHUB_OUTPUT" ;;
|
||||
*) echo "rust=true" >> "$GITHUB_OUTPUT" ;;
|
||||
esac
|
||||
|
||||
test:
|
||||
name: test (ubuntu)
|
||||
needs: rust-changes
|
||||
if: needs.rust-changes.outputs.rust == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
|
|
@ -78,6 +106,8 @@ jobs:
|
|||
|
||||
simulator-e2e:
|
||||
name: simulator e2e (${{ matrix.os }})
|
||||
needs: rust-changes
|
||||
if: needs.rust-changes.outputs.rust == 'true'
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
|
|
@ -97,6 +127,8 @@ jobs:
|
|||
|
||||
wheels:
|
||||
name: wheels (${{ matrix.target }})
|
||||
needs: rust-changes
|
||||
if: needs.rust-changes.outputs.rust == 'true'
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 45
|
||||
strategy:
|
||||
|
|
@ -137,6 +169,8 @@ jobs:
|
|||
|
||||
audit:
|
||||
name: audit
|
||||
needs: rust-changes
|
||||
if: needs.rust-changes.outputs.rust == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
|
|
@ -168,6 +202,8 @@ jobs:
|
|||
# drifting away from the fixtures; that needs re-recording, not this job.
|
||||
parity:
|
||||
name: parity
|
||||
needs: rust-changes
|
||||
if: needs.rust-changes.outputs.rust == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue