Repository navigation
CI was burning ~2,340 min/month — now fixed, here's the breakdown #261
Description
Summary
The ci/release-only change (#260, merged today) reduced CI from running on every PR and push to only running on release-please PRs and tag pushes. This issue documents the before/after numbers.
Before (March 1–20 actuals from Actions Usage Metrics)
| Workflow | Runs | Linux min | Windows min | Total billed min |
|---|---|---|---|---|
| ci.yml | 364 | 1,354 | 985 | 2,339 |
| release-please.yml | 83 | 83 | — | 83 |
| release.yml | ~19 | 31 | 3 | 51* |
| dependabot-updates | 7 | 7 | — | 7 |
| Total | ~2,493 |
*Release also runs macOS builds (10x multiplier) — the 17 min macOS shown in the screenshot accounts for most of release.yml's cost.
Where 2,339 CI minutes came from
| Trigger | Runs | Est. min | Notes |
|---|---|---|---|
| PR (pull_request) | 213 | ~1,363 | Every PR to main |
| Push to main | 151 | ~966 | Redundant — CI already passed on the PR |
| Total CI | 364 | ~2,339 |
The push-to-main trigger alone was responsible for ~966 min — 39% of all CI — re-validating code that was already validated on the PR.
Each CI run spins up 7 jobs (test + build on both ubuntu and windows, plus lint and two gate jobs), billing ~6.4 min on average. Windows jobs are billed at 2x, which is why 985 billed minutes come from Windows despite each Windows job only running ~2 min.
Top branches by CI runs
| Branch | Runs |
|---|---|
| main (push) | 50 |
| release-please--branches--main | 18 |
| All feature/fix branches combined | ~296 |
After (projected with ci/release-only)
| Workflow | Est. runs/month | Est. billed min |
|---|---|---|
| ci.yml (release-please PRs + tags only) | ~24 | ~154 |
| release-please.yml | ~83 | ~83 |
| release.yml | ~19 | ~51 |
| Total | ~288 |
Estimated savings: ~2,200 min/month (88%)
What changed
PR #260 modified ci.yml to:
- Remove
push: branches: [main]trigger — no more redundant CI on merge - Add a
should-rungate job that checks if the PR is from arelease-please--*branch - All other jobs depend on
should-runand skip if it outputsfalse - Keep
push: tags: ["v*"]so CI runs as a final check alongside release builds - Keep
workflow_dispatchas an escape hatch
Regular PRs now rely on local pre-commit hooks (go fmt, go vet, golangci-lint) for quality.
Remaining optimization opportunities
- Drop Windows from CI matrix: Windows jobs account for ~40% of CI minutes due to the 2x multiplier. The release workflow already builds and tests on Windows. Removing Windows from CI and relying on release builds would save another ~40% of remaining CI minutes (~60 min/month). Low risk for a pure-Go project with no Windows-specific code paths in CI.
- Release builds macOS 10x multiplier: Each macOS build minute costs 10 Linux minutes. The current macOS build is fast (~0.7 min raw = ~7 billed), but worth noting if release frequency increases.
Data source
- Screenshot: Actions Usage Metrics page, March 1–20, 2026
- Run counts:
gh api repos/AppSprout-dev/mnemonic/actions/runs(deduplicated, 494 total runs) - Job timings:
gh run viewon representative runs
Activity
CalebisGross commentedon Mar 29, 2026
This was a post-mortem documenting the fix, not an open task. The CI change (#260) has been live since March 20 — CI only runs on release-please PRs and tag pushes now. Closing as resolved.