Skip to content

fix(ci): gate required schema-parity & verify-non-root via changes job (#1222)#1223

Merged
vybe merged 1 commit into
devfrom
feature/1222-ci-required-check-shim
Jun 16, 2026
Merged

fix(ci): gate required schema-parity & verify-non-root via changes job (#1222)#1223
vybe merged 1 commit into
devfrom
feature/1222-ci-required-check-shim

Conversation

@vybe

@vybe vybe commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Problem

Every PR to dev is frozen BLOCKED — even with approval + admin:

GraphQL: 2 of 4 required status checks are expected. (mergePullRequest)

dev requires schema-parity and verify-non-root, but both come from path-filtered workflows (on.pull_request.paths = DB paths / docker/**). On a PR that doesn't touch those paths the workflow never runs, so the required context never posts a status → GitHub holds it "expected" forever → merge blocked. enforce_admins: true blocks the override too. schema-parity.yml even carried a maintainer note warning not to make it required for this exact reason.

Fix

Move the path filtering from the workflow trigger to a cheap changes detector job (dorny/paths-filter) + a job-level if: on the heavy job:

  • A job skipped via if: still posts a check run (conclusion: skipped), which branch protection counts as passing → the required context is always present.
  • The heavy job runs only when the relevant surface changes → intent preserved:
    • schema-parity still runs (and can block) on src/backend/db/**, database.py, utils/helpers.py, …
    • verify-non-root still boots the stack (and can block) on docker/**, docker-compose*.yml, scripts/deploy/start.sh, src/mcp-server/Dockerfile.

Behavior after merge

PR touches… schema-parity verify-non-root
nothing relevant (deps, docs) skip → ✅ pass skip → ✅ pass
src/backend/db/** runs, can block skip → ✅ pass
docker/** skip → ✅ pass runs, can block

Self-merging — no branch-protection change needed

This PR edits both workflow files, and each filter includes its own path, so both real jobs run here and post all four required contexts. It merges with one approval; enforce_admins, the required-checks list, and strict are untouched.

Test plan

  • YAML parses; jobs = [changes, schema-parity] / [changes, verify-non-root]
  • On this PR: schema-parity + verify-non-root run for real (both workflow files changed) and pass
  • After merge: a previously-frozen dependency PR (e.g. chore(deps): bump tailscale/github-action from 2 to 4 #1173) becomes mergeable
  • After merge: confirm a deps PR shows schema-parity/verify-non-root as skipped → passing

Fixes #1222

🤖 Generated with Claude Code

#1222)

Both checks were required on `dev` but path-filtered via
`on.pull_request.paths`, so they never posted a status on PRs that don't
touch DB/docker paths — leaving the required context "expected" forever and
freezing the entire dev merge queue (admin override blocked too via
enforce_admins).

Move the path filter from the workflow trigger to a cheap `changes` detector
(dorny/paths-filter) + job-level `if:`. A job skipped via `if:` still posts a
check run (conclusion: skipped), which branch protection counts as passing —
so the required context is always present, while the heavy job runs only when
the relevant surface changes. Intent preserved: schema-parity still blocks real
schema drift on `src/backend/db/**`; verify-non-root still blocks root/socket
regressions on `docker/**`.

Self-merging: this PR edits both workflow files (each filter includes its own
path), so both real jobs run here and post all four required contexts — no
branch-protection change or admin override needed.

Fixes #1222

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vybe vybe requested a review from AndriiPasternak31 as a code owner June 15, 2026 17:12
@vybe vybe requested review from oleksandr-korin and removed request for AndriiPasternak31 June 15, 2026 17:36
@github-actions

Copy link
Copy Markdown

⚠️ Nightly unit-suite check skipped — merge conflict against dev.

Resolve by running git merge dev locally and pushing the result. The next nightly run will re-test once the conflict is gone.

@dolho

dolho commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review — LGTM ✅

Correct fix and the canonical GitHub pattern for "required + path-filtered" checks. Verified the diff, YAML validity, job graph, and the live check run.

Why it's right

  • Root cause + mechanism are correct: on.pull_request.paths filters at the workflow level → no run → the required context never posts → GitHub holds it "expected" forever. Moving the filter to an always-running changes job (dorny/paths-filter) + a job-level if: on the heavy job is the documented solution — a job skipped via if: posts a skipped check run, which branch protection counts as passing.
  • Empirically proven on this PR: the rollup shows changes ✅, schema-parity ✅, and verify-non-root ✅ all ran for real — because each filter self-includes its own workflow path and this PR edits both files. The self-merge claim holds; no branch-protection change needed.
  • Intent preserved — filter path lists unchanged, both gates still run and can block on db/** / docker/**.
  • verify-prod-frontend-uid is a step inside verify-non-root, so it's covered (no new always-on heavy job).
  • Least-privilege is right: changes adds pull-requests: read (paths-filter API mode), heavy job keeps contents: read.

Non-blocking suggestions

  1. Supply chain (low): dorny/paths-filter@v3 is tag-pinned, not SHA-pinned — a floating tag can be repointed, and this runs with pull-requests: read. A commit-SHA pin would harden it. (Consistent with the repo's existing actions/checkout@v6 tag-pinning, so optional.)
  2. Fail-open (low): if the changes job itself fails (dorny/API hiccup), the dependent gate is skipped-due-to-failed-need → counts as passing → a db/docker-changing PR could merge without the gate actually running. Low probability and awkward to close fully; worth a comment acknowledging it.
  3. The unchecked test-plan box ("after merge: deps PR shows skipped → passing") is the one behavior only confirmable post-merge — recommend validating on a no-op PR (e.g. fix(agents): validate template cpu/memory before container create (#1197) #1227 / fix(agent): salvage execution telemetry on agent-side timeout 504 (#1201) #1229, which don't touch db/**) right after this lands.

Merge-context heads-up (not this PR's fault): currently BLOCKED on lint (sys.modules pollution check) — the pre-existing #1199 dev-red lint that #1213 fixes — plus REVIEW_REQUIRED. With enforce_admins: true there's a near-deadlock: this PR is blocked by the lint, and #1213 (the lint fix) was blocked by the phantom-check freeze this PR removes. Breaking it likely needs a one-time admin action (temporarily relax enforce_admins, merge one, restore).

Also: #1228 is a duplicate of #1222 — worth closing in its favor.

@vybe vybe merged commit 5027b19 into dev Jun 16, 2026
16 of 17 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.

2 participants