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-run gate job that checks if the PR is from a release-please--* branch
- All other jobs depend on
should-run and skip if it outputs false
- Keep
push: tags: ["v*"] so CI runs as a final check alongside release builds
- Keep
workflow_dispatch as 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 view on representative runs
Summary
The
ci/release-onlychange (#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)
*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
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
After (projected with ci/release-only)
Estimated savings: ~2,200 min/month (88%)
What changed
PR #260 modified ci.yml to:
push: branches: [main]trigger — no more redundant CI on mergeshould-rungate job that checks if the PR is from arelease-please--*branchshould-runand skip if it outputsfalsepush: tags: ["v*"]so CI runs as a final check alongside release buildsworkflow_dispatchas an escape hatchRegular PRs now rely on local pre-commit hooks (go fmt, go vet, golangci-lint) for quality.
Remaining optimization opportunities
Data source
gh api repos/AppSprout-dev/mnemonic/actions/runs(deduplicated, 494 total runs)gh run viewon representative runs