Repository navigation
docs-only PRs run verify-precommit-config and smoke-test to completion: 84% of runner time on a markdown edit #15299
Description
Problem
A docs-only pull request runs two heavy required jobs to completion. PR #15250 changed one markdown file (5 insertions, 5 deletions) and consumed ~34.5 minutes of self-hosted runner time across the first 30 of its 73 workflow runs.
The self-skip design works for almost everything. Measured job durations on docs/visual-arch-align:
| Job | n | total s | max s |
|---|---|---|---|
| verify-precommit-config (Enforce Pre-commit Hooks) | 2 | 1142 | 645 |
| smoke-test (Docker Smoke Test) | 1 | 590 | 590 |
| Detect changed paths | 10 | 123 | 14 |
| Unit & Integration Tests | 2 | 8 | 5 |
| migration-matrix | 2 | 7 | 4 |
| python-suite | 2 | 7 | 4 |
| verify-generated-types | 2 | 5 | 3 |
| api-wiring | 1 | 3 | 3 |
Unit & Integration Tests, python-suite, migration-matrix, verify-generated-types and api-wiring all report in 3-5 seconds — they gate their work on changes and self-skip exactly as ci.yml:36-37 describes. That design is correct and is not what this issue proposes changing.
verify-precommit-config and smoke-test do not self-skip. Together they are 1732s of the 2068s measured — 84% of all runner time spent on a markdown edit.
Why a paths: filter is the wrong fix
Both jobs publish required status contexts (verify-precommit-config, smoke-test). Adding pull_request.paths would recreate the deadlock that #14353 removed and that ci.yml:24-31 documents inline: when a filter and the workflow trigger disagree, neither workflow reports the required context and the PR waits forever on a check nobody can produce. enforce-precommit.yml:10 already says its missing filter is deliberate for this reason.
The workflow must keep starting. Only the work should be skipped.
Proposed fix
Apply the pattern the other required contexts already use — a changes detection job, with the expensive steps gated on it, and the context still reported when nothing relevant changed:
.github/workflows/enforce-precommit.yml— gate the config-verification steps on a paths check; reportverify-precommit-configas passing when the PR touches no.pre-commit-config.yaml, hook, or workflow path.github/workflows/docker-smoke-test.yml— gatesmoke-teston changes to Dockerfiles, compose files, and the application source it exercises; a markdown-only PR should report the context without building an image
Acceptance criteria
- A docs-only PR reports
verify-precommit-configandsmoke-testas passing in seconds, not minutes - Both contexts are still reported on every PR, so branch protection can never deadlock
- A PR touching
.pre-commit-config.yaml,.github/workflows/**, or hook scripts still runs the full pre-commit verification - A PR touching Dockerfiles, compose files, or application source still runs the full smoke test
- Measured: a docs-only PR's total runner time drops by roughly the 1732s identified above
Why this matters on a self-hosted runner
Runner slots are finite. Docs PRs holding them for ~20 minutes per push delays unrelated PRs behind them in the queue. The cost here is contention and latency, not billing.
Evidence
PR #15250: 1 file, +5/-5, docs only
73 workflow runs; first 30 sampled -> 59 jobs, 40 executed, 19 skipped
runner time in successful jobs: 2068s (34.5 min)
verify-precommit-config + smoke-test: 1732s (84%)
Repo-wide context: only 2 of the last 200 workflow runs failed, so this is not a flakiness or retry problem — it is unconditional work on irrelevant changes.
Activity
ci(security): declare least-privilege permissions on the docker smoke…
fix(ci): keep Set up Python ungated so the workflow-filter guard keep…
ci(perf): stop docs-only PRs running the pre-commit sweep and image b…
github-actions commentedon Aug 29, 2026
PR #15300 (merged to
Dev_new_gui) references this issue with a close keyword.If this issue is fully resolved, close it manually. If work remains, no action is needed.
mrveiss commentedon Aug 29, 2026
Closed by PR #15300, merged as
36a1e7d25fintoDev_new_gui.Acceptance criteria — verified against the merged base, not the branch
steps.filter.outputs.code;smoke-testgated onneeds.changes.outputs.docker.git show origin/Dev_new_gui:.github/workflows/enforce-precommit.ymlshows 3 gated stepsverify-precommit-config's job is never gated — it always runs and reports.smoke-testmoves todocker-smoke-required-context.yml:60,68on the exact complement (docker != 'true')docs-only-paths.ymlcodekey =**minus prose, so any.pre-commit-config.yaml,.github/**or hook script edit yieldscode == 'true'.github/filters/docker-paths.yml, present in base, covers everyCOPY/ADDin the backend, slm and frontend Dockerfiles and every default compose bind-mountSet up Python(18s) stayed ungated for the reason below, so the realised saving is ~1598s rather than the full 1732sLive behaviour, observed on PR #15300 itself
The
smoke-testcontext appeared twice —passfrom the real job andskippingfrom the shim — which is the intended complement for a PR that touches Docker-relevant paths. This PR touches.github/**, so both gates evaluatedtrueand both jobs ran in full; a docs-only PR is what takes the fast path.Review found one blocking bug, fixed before merge
Gating
Set up Pythonwould have broken the required check on exactly the docs-only PRs this issue targets. Two ungated steps run afterwards and callpython3 pipeline-scripts/check_workflow_path_filters.py, which doesimport yaml(:52); PyYAML reaches the runner only as pre-commit's dependency, asenforce-precommit.ymlstates inline. Skipping the setup step would have producedModuleNotFoundError: No module named 'yaml'.CI could not have caught this — a PR touching
.github/**hascode == 'true', so the skip path is never exercised by this PR's own run. Fixed in28361d5a65by keepingSet up Pythonungated; at 18s against the sweep's 1008s it forfeits almost none of the saving.Also corrected in review:
config/**andautobot-slm-agent/**matched nothing (untracked local directories, not repo paths) and were removed; all 19 remaining directory patterns confirmed tracked.Additional fix carried in the same PR
CodeQL raised 2 medium alerts:
docker-smoke-test.ymlcarried nopermissions:block at all — pre-existing, surfaced because the file was touched. Fixed inbb05dd2e6bwithcontents: read, matchinghardened-smoke-test.ymlandco-located-smoke.yml.CI
33 success, 16 skipped, 0 failures, verified against the review-fix commit
28361d5a65rather than an earlier push.CodeQL,verify-precommit-configandsmoke-testall green.ci(perf): scope enforce-precommit to the PR diff and cache its hook e…