chore(ci): cut PR wall-clock ~9.5min → ~5-6min — dedupe dogfood, shard it, cache lint's build#3622
Merged
Merged
Conversation
…d it, cache lint's build Three data-driven fixes from job-level timing of recent PR runs: 1. Test Core re-ran the whole ~7.5-minute dogfood suite that the dedicated Dogfood job was already running in parallel (both gate on the same `core` filter). Exclude @objectstack/dogfood from both the PR --affected run and the push run; the Dogfood job remains the sole (and unconditional) runner of the suite. Verified locally: turbo unions inclusive filters and then subtracts `!` negations, so `--affected --filter=!@objectstack/dogfood` is exactly "affected minus dogfood" (140 → 137 tasks, nothing else lost). 2. The Dogfood job itself was the workflow's longest pole (7m34s for the ~60-file suite on one 4-vCPU runner). Shard it 2-way with vitest's deterministic file-level --shard, passed through turbo (pass-through args are part of the turbo task hash, so each shard caches independently — verified: distinct hashes per shard). The `objectstack verify` CLI step is shard-independent and runs on shard 1 only. NOTE: if branch protection requires "Dogfood Regression Gate", the required check must be renamed to the two sharded names. 3. lint.yml's "TypeScript Type Check" job runs a full workspace build but was the only build-running job with NO turbo cache step — it rebuilt everything from scratch every run (4m38s observed, vs 51s for the same build in ci.yml's cached Build Core). Add the same .turbo/cache step. Also: lint.yml and codeql.yml had no concurrency group, so superseded runs of both (they trigger on every PR sync) kept burning runners and delaying the queue. Add the same cancel-in-progress policy ci.yml already documents. Full-chain smoke: `turbo run test --filter=@objectstack/dogfood -- --shard=1/30` runs green end-to-end (turbo → pnpm → vitest, 61 tasks OK). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECTCrcCdZpCHw5zFSgcmGt
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECTCrcCdZpCHw5zFSgcmGt
os-zhuang
marked this pull request as ready for review
July 27, 2026 10:31
os-zhuang
added a commit
that referenced
this pull request
Jul 27, 2026
…name (#3622 follow-up) (#3644) INCIDENT: every open PR in the repo is BLOCKED — mergeable, all checks green, merge button dead. Root cause: #3622 sharded the dogfood job 2-way, so its checks now publish as "Dogfood Regression Gate (1/2)" / "(2/2)". Branch protection still requires the bare context "Dogfood Regression Gate", which no job emits anymore — the requirement can never be satisfied. #3622's own comment called for updating branch protection; that step never happened. Fix keeps the contract in CODE rather than in protection settings: a tiny aggregator job carrying the stable name, gated on the matrix's aggregate result. A future shard-count change therefore cannot deadlock the repo again. `if: always()` + result inspection so a legitimately skipped matrix (filter says no core paths changed) still satisfies the gate. Verified: workflow YAML parses; job graph has dogfood-gate needs: dogfood with name "Dogfood Regression Gate". Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.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.
Why
Job-level timing of recent PR runs shows where the time actually goes:
turbo run test --affected— 8m35sturbo run build— 4m38s (no cache)Two structural problems dominate: the dogfood suite ran twice per core PR (once in its dedicated job, once again inside Test Core's affected set, in parallel on two runners), and lint's typecheck job is the only build-running job with no turbo cache, so it rebuilt the entire workspace from scratch on every run — the identical build takes 51s in ci.yml's cached Build Core job.
What
Exclude
@objectstack/dogfoodfrom Test Core (both the PR--affectedrun and the push run). The dedicated Dogfood job — gated on the samecorefilter — remains the sole, unconditional runner of the suite. Verified locally: turbo unions inclusive filters and then subtracts!negations, so--affected --filter=!@objectstack/dogfoodis exactly "affected minus dogfood" (140 → 137 tasks, nothing else dropped).Shard the Dogfood job 2-way (
vitest run --shard=N/2, ~60 independent test files, deterministic file-level partition). The shard arg passes through turbo and is part of the turbo task hash, so each shard caches independently (verified: distinct hashes). Theobjectstack verifyCLI step is shard-independent and runs on shard 1 only. Turbo cache keys are shard-scoped so the two matrix jobs don't race on one cache entry.Add the missing turbo cache step to lint's typecheck job — same key scheme as ci.yml, so the fallback prefix also hits caches saved by main pushes.
Add
concurrencycancel-in-progress to lint.yml and codeql.yml (ci.yml already has it). Both trigger on every PR sync; superseded runs were burning runners and delaying the queue.Expected effect
Verification
turbo run test --affected --filter=!@objectstack/dogfood --dry=jsonwith a spec change: dogfood excluded, all other affected tasks intact.vitest run --shard=1/30inpackages/qa/dogfood: 3 files / 13 tests, green — sharding partitions and runs correctly.turbo run test --filter=@objectstack/dogfood -- --shard=1/30→ 61 tasks successful, exit 0.--dry=jsontask-hash comparison between--shard=1/2and--shard=2/2: hashes differ, so per-shard turbo caching is safe.If branch protection lists "Dogfood Regression Gate" as a required status check, it must be updated to the two sharded check names (
Dogfood Regression Gate (1/2)/Dogfood Regression Gate (2/2)).🤖 Generated with Claude Code
https://claude.ai/code/session_01ECTCrcCdZpCHw5zFSgcmGt
Generated by Claude Code