Skip to content

ci: path-gate single-surface jobs on changed files - #1560

Closed
RohanK6 wants to merge 1 commit into
kirodotdev:mainfrom
RohanK6:feat/path-gated-ci
Closed

ci: path-gate single-surface jobs on changed files#1560
RohanK6 wants to merge 1 commit into
kirodotdev:mainfrom
RohanK6:feat/path-gated-ci

Conversation

@RohanK6

@RohanK6 RohanK6 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

What

A first-stage changes job computes one decision output per surfacerun_backend / run_frontend — and the clearly single-surface jobs gate on that single flag. Path policy lives in exactly one place (the decide step); no other job re-derives it.

Gated job Runs when
Backend Lint & Type Check (3.10/3.12) run_backend
Backend Tests (Linux 3.10/3.12 shards, Windows shards, namespace sandbox) run_backend
Coverage Combine run_backend
Frontend Lint & Type Check, Frontend Tests run_frontend
Electron Shell Tests, E2E (stub ACP backend, offline) run_frontend

A surface runs when its own paths changed, when meta paths changed (.github/**, scripts/** — when in doubt, run everything), or when the PR carries the ci-full-run label (escape hatch to force the complete matrix).

Always-on (cross-cutting or too cheap to gate): De-Amazon Scrub Lint, Brand Name Gate, Docs Lint, CloudFormation Lint, Inclusive Language, Gateway Tests (macOS), Coverage Gate.

Coverage Gate safety

The gate keeps its fail-closed contract as a symmetric invariant:

  • surface required ⟹ upstream must be success
  • surface not required ⟹ upstream must be exactly skipped (anything else — failure, cancellation, dependency-skip, or a job that ran when it shouldn't have — fails)
  • empty flags (the path-filter job never reported) ⟹ fail closed

Prior art

This is the pattern home-assistant/core's ci.yaml uses at much larger scale: an info job runs dorny/paths-filter, derives decision outputs, downstream jobs gate on single flags, and a ci-full-run label forces the full suite. Same action version pinned here (v4.0.2, full SHA per this repo's convention). GitHub's own docs confirm workflow-level paths: filtering can't work with required checks (skipped workflows leave required checks pending and block merge) — hence job-level filtering with an always-running verdict.

Why

From #1556: a recent 5-line website/src/pages/ChatSidebar.tsx fix ran 8 backend test shards, Electron tests, CloudFormation lint, and Docker smoke — none reachable by the diff. Roughly half of every single-surface PR's CI is unaffectable by its changes, and on fork PRs each push costs a maintainer "Approve and run" click that buys one mostly-irrelevant matrix run.

Testing

  • actionlint v1.7.12: clean on this workflow (only note is a pre-existing style nit in an untouched script)
  • YAML validated; dorny/paths-filter SHA matches the upstream v4.0.2 tag
  • This PR touches .github/**, so it sets meta ⟹ runs the full matrix on itself — the gating logic exercises its most conservative branch on this very run

Closes #1556

@RohanK6
RohanK6 requested a review from a team as a code owner August 5, 2026 03:32
@github-actions github-actions Bot added fork Pull request from a fork (external contributor) readiness: checking Automated validation is still running labels Aug 5, 2026
@RohanK6
RohanK6 force-pushed the feat/path-gated-ci branch 2 times, most recently from 15d21d5 to 4b0ea47 Compare August 5, 2026 11:47
Every PR currently runs the full ~20-job matrix regardless of what it
touches -- a frontend-only diff runs 8 backend test shards, and a
backend-only diff runs the frontend suite, Electron tests, and the
Playwright E2E. Each fork-PR push also costs a maintainer approval
click that buys one mostly-irrelevant run.

Add a cheap first-stage 'changes' job (dorny/paths-filter, SHA-pinned
per repo convention) computing backend/frontend/meta flags, and gate
only the clearly single-surface jobs on them: backend lint + all
backend test shards (Linux/Windows/sandbox) run when backend or meta
paths changed; frontend lint/tests, Electron shell tests, and the
stub-ACP E2E run when frontend or meta paths changed. Workflow,
script, and dependency-manifest changes set 'meta' and run everything.
Cross-cutting gates (SAST-adjacent lints, brand/scrub/docs/cfn, macOS
gateway tests) stay unconditional.

Coverage Gate keeps its fail-closed spirit: path-skipped upstreams
pass only when the corresponding flag is false AND the changes job
itself succeeded; dependency-failure skips, cancellations, and a
failed path-filter job all still fail the gate.

Closes kirodotdev#1556
@RohanK6
RohanK6 force-pushed the feat/path-gated-ci branch from 4b0ea47 to 5f27d2f Compare August 5, 2026 12:07
@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Aug 5, 2026
@iamwhatever

Copy link
Copy Markdown
Collaborator

Thanks for this, @RohanK6 — the path-gating design is clean (single decision point, meta-forces-full, symmetric fail-closed Coverage Gate) and we want it. Fork PRs can't reach readiness: passed (the secret-backed AI reviews and managed CodeQL don't run on fork heads), so I've re-raised your commit from an in-repo branch — authorship preserved via cherry-pick — as #1757 so the full readiness pipeline can validate and land it. Closing this in favor of that. Credit is all yours.

@iamwhatever iamwhatever closed this Aug 6, 2026
@github-actions github-actions Bot removed the readiness: action required A blocking check or review needs attention label Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fork Pull request from a fork (external contributor)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CI runs the full matrix on every PR — path-gate surface-specific jobs to cut compute, noise, and fork-approval toil

2 participants