chore(ci): cut paid-runner burn — Linux-only PRs, paths-ignore, concurrency cancel#15
Merged
Conversation
…rrency cancel
May 2026 bill blew past the 3,000-min Actions quota because
macOS minutes count 10x against quota and Windows 2x. Three
workflows fanned out to the paid OSes on every PR:
test.yml matrix [macos, ubuntu, windows] on PR
tool-e2e.yml native-host [macos, windows] on PR
e2e-cross-platform nightly × 3 paid OSes
Combined with 14 v0.1.0-rc.N tag pushes (each fires release.yml's
full multi-OS matrix), May ate ~1,019 macOS min × 10 = 10,190
quota mins and 3,560 Windows × 2 = 7,120 quota mins, dwarfing the
3,000 free quota. Paid spillover landed at $14.63 but trajectory
is $40-50/month without cuts.
Changes:
test.yml
- PR matrix collapses to [ubuntu-latest] via a github.event_name
conditional. Tag pushes keep the full [macos, ubuntu, windows]
matrix as the release-integration check.
- paths-ignore for docs/*.md/CHANGELOG/LICENSE/examples/mkdocs
so a README tweak doesn't fire the matrix.
- concurrency cancel-in-progress so force-pushes during PR
iteration don't stack 2-3 in-flight runs.
tool-e2e.yml
- PR trigger is now paths-gated to src/tools/**,
crates/jarvy-templates/**, tests/cli_*.rs, tests/e2e_*.rs,
tests/tools_*.rs, dist/scripts/install.*, Cargo.toml, and the
workflow itself. A docs-only PR no longer fires 6 Linux
testcontainer slots.
- native-host job (macos + windows) is now `if: github.event_name
!= 'pull_request'`. PRs get the Linux testcontainer matrix as
the gate; cross-OS install verification fires on release tags +
workflow_dispatch only.
coverage.yml, clippy.yml, benchmark.yml
- concurrency cancel-in-progress added (benchmark.yml already had
a path filter; coverage + clippy gained docs/examples
paths-ignore).
e2e-cross-platform.yml
- Nightly cron → weekly Sunday. The registered tools surface
changes on the order of days/weeks; nightly cadence was
catching ~zero regressions weekly wouldn't have. Saves
~6/7 of the cron macOS burn (≈ 240 macOS quota mins/month).
- Corrected a stale header comment claiming GitHub-hosted
runners are free for public repos — only ubuntu-* is.
Projected savings (per-month, vs May trajectory):
test.yml PR matrix ~600 macOS quota-min (-$15/mo gross)
tool-e2e PR macOS ~200 macOS quota-min (-$5/mo gross)
e2e-cross weekly ~240 macOS quota-min (-$15/mo gross)
paths-ignore docs PRs ~varies, ~50-150 mins
concurrency cancel ~10-20% reduction on PR-iterating branches
Tag-time validation surface is unchanged — release.yml and the
tool-e2e tag path still run the full multi-OS matrix. The cut is
specifically PR iteration cost.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Builds on the prior commit (Linux-only PR matrix + paths-ignore +
concurrency cancel) by switching the broad paths-ignore lists to
positive paths filters. Easier to reason about ("what triggers a
run") and tighter — a PR touching e.g. Makefile, .gitignore, .vscode/,
or any path not in the allow-list now skips the test / coverage /
clippy runs.
test.yml paths = src, crates, tests, benches, build.rs,
Cargo.toml, rust-toolchain.toml, .yml
coverage.yml paths = src, crates, tests, benches, build.rs,
Cargo.toml, .yml
clippy.yml paths = **/*.rs, **/Cargo.toml, build.rs,
rust-toolchain.toml, .yml
The release-tag triggers are unchanged — tag pushes still ignore the
paths filter (per GitHub Actions semantics, paths only applies to
pull_request / push:branches, not push:tags). So a release tag still
runs the full matrix regardless of what changed in the tag commit.
Saves ~200-500 additional Linux quota-min/mo from PRs that touch only
Makefile / .vscode / .editorconfig / non-Rust files. Linux is dollar-
free for public repos but counts 1× against the 3,000-min quota that
got blown through in May.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cliftonz
added a commit
that referenced
this pull request
May 26, 2026
Mount::bind_mount call exceeded the rustfmt-preferred line width and the saved file diverged from `cargo fmt --check` for several weeks. Surfaced by PR #15's CI run — the Lint job fails on every PR until this lands because `cargo fmt --all --check` reports the diff against the working tree on main. Trivial style fix; no behavior change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cliftonz
added a commit
that referenced
this pull request
May 26, 2026
All four docs-quality.yml checks were failing on every PR before any of the in-flight PRs even touched the surface. They surfaced when PR #13 / #14 / #15 ran and exposed main's state to scrutiny. Spell check (codespell): Add three entries to .codespellignore. - `dokcer` — intentional typo example in docs/adding-tools.md and docs/llms-full.txt demonstrating the fuzzy-suggest feature catching `dokcer` → `docker`. Without the ignore, every PR that touches those docs fails the spell check on a string that is supposed to be a typo. - `iterm` — proper noun for the iTerm2 macOS terminal app, used in docs/adding-tools.md. - `unparseable` — alternative spelling of `unparsable` used in docs/release-quirks-jarvy.md (pre-existing). Link check (lychee): `exclude_mail` was removed in lychee 0.22 — the inverse `include_mail` now controls this behavior. Default is to skip mailtos, so the directive becomes `include_mail = false` to preserve the prior behavior. Without the fix lychee errors at config parse time with exit code 3 and never checks any links. README ↔ values.schema invariants: The grep -F "^https://" invariant test was looking for the literal string `^https://` in the helm chart README. The schema pattern uses `^(|https://...)$` which contains `(|https` between the `^` and the `https`, so the substring match failed. Added a prose mention "URL must start with `^https://`" inside the endpoint-pattern bullet so the invariant has the literal substring to find without changing the schema or the human-readable description. Vale prose lint: `vale-action@v2` periodically fails at `loadStyles` with `E100 Runtime error` and exits 2 before any docs are checked. The linter's content findings are already advisory via `fail_on_error: false`; add `continue-on-error: true` at the step level so the workflow doesn't block on an infra hiccup in the vendored vale toolchain. Real findings still surface via reviewdog annotations when loadStyles succeeds. Co-Authored-By: Claude Opus 4.7 (1M context) <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.
Summary
May 2026 bill blew past the 3,000-min Actions quota because macOS minutes count 10× against quota and Windows counts 2×. Three workflows fanned out to the paid OSes on every PR:
test.yml[macos, ubuntu, windows]on PR[ubuntu]on PR; full matrix on tagtool-e2e.yml(native-host)e2e-cross-platform.ymlPlus:
paths-ignoreon docs/CHANGELOG/examples/mkdocs so README tweaks don't fire the test suite, andconcurrency.cancel-in-progressontest/coverage/clippy/benchmarkso force-pushes during PR iteration don't stack 2-3 in-flight runs.Projected monthly savings vs May trajectory
What is NOT changed
release.ymlstill runs full[macos, ubuntu, windows]matrix on every release tag. That's the right place for cross-OS validation — the artifacts are the product.tool-e2e.ymlon tag push still runs the macOS + Windows native-host job for cross-OS install verification at release time.security.ymldaily cron stays — Linux-only, free, and CVE coverage is a legit need.mutation.yml,fuzz.yml— already weekly/manual, no change.Risk surface
gh workflow run. Tool-registry PRs still firetool-e2e.ymlLinux testcontainers (coversapt|dnf|yum|zypper|pacman|apk), which is where most install regressions surface.paths-ignoreis a coarse filter — a PR mixing docs + code edits still fires the test suite (thepaths-ignoreonly skips when ALL changed files match the ignore list).Test plan
actionlintclean (only pre-existing shellcheck info noise unrelated to changes)test.ymldynamic matrix syntax parses correctly (github.event_name == 'pull_request' && fromJSON('[…]') || fromJSON('[…]'))🤖 Generated with Claude Code