Repository navigation
ci: run repository gate checks in one Bazel analysis - #4638
Conversation
Repository gates paid a separate Bazel analysis for each of its Bazel steps, and Feature gates paid a whole runner for one more. In run 41016935321 the policy-test step spent 65 s of 71 s loading and analyzing (critical path 6 s), `bazel build //:rustfmt_check` 35 s of 37 s (critical path 2 s), and Feature gates 52 s of Bazel setup plus 83 s of analysis for a 1 s `gen_builds_test` (151 s job). One `bazel test` invocation now builds `//:rustfmt_check` and runs every policy test, including `gen_builds_test` and `release_pr_refresh_test`, so the actions run side by side under one analysis. Locally the merged invocation analyzes and passes cold in 125 s (8 tests, critical path 22 s). Expected: Repository gates about 40 s shorter; Feature gates becomes a pass-through that keeps the protected check name and frees a hosted runner slot and a 2.3 GB cache restore per run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
A Renovate bump under mockups/ (PR #4633) reran Clippy for 53 minutes and six Linux shards for 45 to 80 minutes on run 41101852182, although mockups/ is in .bazelignore and no Bazel action could change. Two causes: Renovate's actor (29139614) has no fleet identity, so its runs take the hosted path, and the hosted path has no compiled-action cache at all: `gh cache list` shows zero setup-bazel disk entries, because a fleet-enabled master run skips the restore step, which leaves the save key empty, so master never saved one. Fixes: - `vars.TS_BAZEL_RENOVATE_CLIENT_ID` enrolls Renovate's pull requests in the fleet alongside the owner and the Devin bot, in every copy of the identity expression, so its unchanged actions become remote cache hits. - A `Change scope` job lists a pull request's files once and decides, through scripts/ci-change-scope.py, whether any path reaches a Bazel input. Only mockups/, docs/, and repository-root Markdown qualify as skippable; plugin/** Markdown is globbed by Bazel. Clippy, Test Linux, Test Windows, and Dashboard skip when nothing qualifies as Bazel input; the Test Linux result job accepts a skipped matrix only in that case. Empty, truncated, or unlisted file sets fail closed and run everything, and pushes and dispatches never skip. - Dashboard, the one Bazel job without a fleet identity, saves its disk cache on master so hosted runs stop rebuilding the frontend toolchain every time. Validation: actionlint, the hosted-runner policy check, 16 change-scope unit tests, and the decision script against PR #4633's real file list (bazel=false) and an empty list (bazel=true). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Devin Review found 1 new potential issue.
1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)
| if len(parts) > 1: | ||
| return parts[0] in SKIPPABLE_DIRECTORIES |
There was a problem hiding this comment.
🔴 New documentation targets bypass CI
When a PR adds docs/BUILD.bazel, path_is_skippable skips the Bazel jobs despite the new package entering //.... Failing targets in that package receive no Linux or Windows validation.
Learn more
The change-scope job decides whether to run Bazel-backed checks from changed filenames. Bazel does not currently have a package under docs/, but adding a BUILD or BUILD.bazel file creates one. The directory-wide allowlist treats that new file as documentation, so the ready-PR Linux and Windows checks skip even though their //... patterns would include the package. The Linux result job also treats its skipped matrix as successful when the scope output is false.
Example: A PR adds docs/BUILD.bazel with a failing sh_test. The classifier reports bazel=false, so the Linux test result succeeds without running the new test.
Recommended fix: Reject docs/BUILD, docs/BUILD.bazel, and other Bazel package/configuration files before applying the docs/ allowlist; add a regression test for new packages under skippable directories.
Was this helpful? React with 👍 or 👎 to provide feedback.
#4637 moved the Linux test job's setup-bazel step above the disk cleanup. Keep that position and carry this branch's Renovate fleet identity into it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(kimi): reject probes of a port kimi web never announced A port TraceDecay asks `kimi web` for, but that `kimi web` never bound, can belong to any local process. The new `foreign` fake mode has another server take that port while Kimi never announces, and asserts Kimi's bearer token never reaches it. Fails on master with "GET /api/v1/plugins returned HTTP 404", the CI message from #4638. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(kimi): only probe the endpoint kimi web announces TraceDecay picked a loopback port by binding port 0 and dropping the listener, passed it to `kimi web --port`, and polled it with Kimi's bearer token as soon as `server.token` existed. Until Kimi bound that port, any local process could hold it, and Kimi itself moves to the next free port when the requested one is busy. Either way Kimi's token went to a server that was not Kimi; in CI a parallel test's server answered 404. Start `kimi web --port 0` so only Kimi holds its port, and probe only the port and token from a complete `Local:` line of that child's ready banner, which Kimi prints after it binds. The `server.token` read goes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Why
Repository gates paid a separate Bazel analysis for each Bazel step, and Feature gates paid a whole hosted runner for one more. Baseline run 41016935321 (PR #4626):
bazel build //:rustfmt_check)bazel test //scripts:gen_builds_testWhat
//:rustfmt_check, every//scripts:*_testpolicy test,gen_builds_test, andrelease_pr_refresh_testin onebazel testinvocation, so one analysis serves actions that now run side by side.Locally the merged invocation analyzes and passes cold in 125 s (1 target, 8 tests, critical path 22 s).
Before/after (this PR's CI run)
Per-step after-timings will be added when the run finishes.
Validation
actionlintpasses.scripts/check-github-hosted-runners.pyand its 11 tests pass.//:rustfmt_checkbuilt).🤖 Generated with Claude Code
Measured (run 41122200755 vs baseline run 41016935321)
That saves about 160 s of runner time per run, and one fewer runner doing Bazel setup. Those jobs already ran in parallel with the longer Linux and Windows jobs, so a run's total time barely changes. The saving shows up in the hosted-runner queue: in this run,
Change scopewaited 26 min for a runner and Repository gates started 53 min in.