ci(prek): scope PR runs to the diff on ubuntu-slim, keep main whole-tree - #1317
Merged
Merged
Conversation
The prek job now runs in two shapes. On a pull request the hooks see only the PR's own diff (`--from-ref` / `--to-ref`) on `ubuntu-slim`; on a push to `main` they run `--all-files` on `ubuntu-latest`. The cores only pay off on the whole-tree sweep — at a handful of files there is nothing for prek to split across them. The link check is exempt from that scoping and runs whole-repo on both events, in a step of its own. lychee is a whole-repo hook wearing a file filter: `pass_filenames: false` means prek's file list only decides *whether it fires*, so under `--from-ref` a PR that breaks a link by renaming a non-doc file matches no `.md`, the hook never runs, and the break lands on `main`. It is nearly free to run unconditionally — measured at 29 MiB peak RSS in 0.24s over 10,251 links, since `offline = true` fetches no URL and `language: rust` needs no Docker. Docs updated where they described CI as always whole-tree. A green PR check is no longer a whole-repo result, which makes the existing "run `prek run --all-files` before you push" pre-flight load-bearing rather than redundant. Generated-by: Claude Opus 5
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
prekjob now runs in two shapes. On a pull request the hooks see only the PR's own diff (--from-ref/--to-ref) onubuntu-slim; on a push tomainthey run--all-filesonubuntu-latest. ci(runners): move every job to the 1-vCPU ubuntu-slim runner #1190's reasoning for slim holds for the PR shape — at a handful of files there is nothing for prek to split across the extra cores, so they buy nothing. The cores only pay on the whole-tree sweep, which is also the run that has to be exhaustive, somainkeeps them.lycheeis a whole-repo hook wearing a file filter:pass_filenames: false+ a trailing.means it always walked the tree itself, and prek's file list only decides whether it fires (files: \.(md|rst|j2)$). Under--from-refthat gate is a hole — a PR that breaks a link by renaming or deleting a non-doc file matches no.md, the hook never runs, and the break lands onmain..lychee.tomlsetsoffline = true(no URL is fetched) and the hook islanguage: rust(no Docker daemon, so slim is fine) off the existing hook-env cache.AGENTS.md,CONTRIBUTING.md). A green PR check is no longer a whole-repo result, which makes the existing "runprek run --all-filesbefore you push" pre-flight load-bearing rather than redundant.Type of change
.claude/skills/<name>/) — eval fixtures updated belowtools/<system>/*.md)tools/*/withpyproject.toml)docs/,README.md,CONTRIBUTING.md) — the CI-shape descriptions onlyprek, workflows, validators)Test plan
prek run --all-filespasses (exit 0, whole tree)uv run zizmor --config .zizmor.yml .github/workflows/pre-commit.yml— no findingsruns-on: ${{ github.event_name == 'pull_request' && 'ubuntu-slim' || 'ubuntu-latest' }}prek run … $PREK_SCOPE --skip workspace-pytest --skip identity --skip skill-token-count --skip lycheeprek run lychee --color=always --all-files,if: ${{ !cancelled() }}prek run lychee --all-filespasses locally (the exact command the new step runs)getrusage(RUSAGE_CHILDREN)rather than assumed: 29.3 MiB peak, 0.24s,🔍 10251 Total 🔗 4338 Unique ✅ 8929 OK 🚫 0 Errorsprek run --helpconfirms--from-ref/--to-refexist and default--to-reftoHEADRFC-AI-0004 compliance
CI-only change — no skill or tool behaviour, no new mutation, no new host access. No row applies.
Linked issues
Refs #1190 (the PR that moved every job to
ubuntu-slim; this splitsprekso the PR shape joins them).Notes for reviewers (optional)
fetch-depthternary is quoted on purpose.${{ cond && 0 || 1 }}evaluates to1on a pull request, because0is falsy in GitHub expressions and the idiom falls through to the right operand. That would have left PRs on a shallow clone and broken--from-refsilently.'0'/'1'are strings, and only the empty string is falsy.PREK_SCOPEis built inenv:, not interpolated intorun:, so no expression is expanded into the step's shell source.!cancelled()rather thanalways()on the lychee step: a link break and a hook failure in the step above are independent, and a contributor should see both in one run instead of fixing one to discover the other.typoscomment does not apply to lychee, and this PR does not expose it to one.typoshit it because prek hands it the file list and chunks that list across ~cpu_countinvocations, so 1 vCPU collapsed ~4.9k paths into one ~5.7 GB process.lycheehaspass_filenames: false, so it receives no list and has always been a single whole-repo process regardless of core count. I corrected thetyposcomment, which said "the 4-vCPU runner the prek workflow now uses" — now true only of themainjob, and that hook walks the tree precisely so slim is safe.lycheeis not the onlypass_filenames: falsewhole-repo hook gated by afiles:pattern —typos,check-placeholders,symlink-lint,check-doc-syncandskill-and-tool-validateshare the shape, so under--from-refeach fires only when a PR happens to touch a matching path.mainstill catches them. I scoped this PR tolycheebecause it is the one whose gate is routinely missed by a legitimate PR (a rename); say the word if you would rather have one "whole-repo hooks" step covering the set.offlineis ever turned back off, the 29 MiB figure stops holding —max_concurrency = 14in-flight responses get buffered and memory becomes a function of response size. That is already coupled to reinstating the.lycheecachestep; worth remembering the memory dimension travels with it..last-syncis 2 commits behindmain, but this ships no skill, tool or mode change, so it is exempt perAGENTS.md.🤖 Generated with Claude Code