perf(ci): run CI once per change instead of twice - #1268
Conversation
`on: { push, pull_request }` with no branch filter meant every push to a PR
branch triggered the full workflow twice — once for `push` and once for
`pull_request` — duplicating the check, test, and native-build matrix on every
commit.
Restrict `push` to `main` so branch commits are validated once via the
`pull_request` event, while main keeps its post-merge run. Rust tests stay
covered: the `Run test suite` step only fired on pushes to non-default
branches (now gone), and the coverage step already runs `cargo llvm-cov` over
the workspace on both remaining triggers. Drop that dead step and the
now-always-true event guards on the Vitest and coverage steps.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughPush trigger is restricted to the ChangesCI workflow branch and test job updates
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ccusage-guide | 6d4ea65 | Commit Preview URL Branch Preview URL |
Jun 11 2026, 03:21 PM |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — CI optimization to halve runs per change by restricting push to main and relying on pull_request for branch validation.
- Restrict
pushtomain— branch pushes without a PR no longer trigger CI;pull_requestcovers pre-merge validation. Roughly halves CI minutes per PR. - Remove dead "Run test suite" step — it only fired on non-default branch pushes, which no longer happen.
- Drop always-true event guards — Vitest, coverage, and upload steps had disjuncts (
github.event_name == 'pull_request' || github.ref == ...) that are universally true under the new trigger scope. Removed with no behavioral change. - Simplify fork-guard on upload — algebraically equivalent to the original; verified by truth table for push/main, same-repo PR, and fork PR.
Big Pickle (free via Pullfrog for OSS) | 𝕏
@ccusage/ccusage-darwin-arm64
@ccusage/ccusage-linux-arm64
@ccusage/ccusage-linux-x64
@ccusage/ccusage-win32-x64
ccusage
commit: |
Code Coverage OverviewLanguages: Rust Rust / code-coverage/cargo-llvm-covThe overall coverage in the Show a code coverage summary of the most impacted files.
Code Coverage is in Public Preview. Learn more and provide us with your feedback. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
The test job spent ~73s on "Warm Nix dev shell" realizing the complete development shell — every linter, formatter, renovate, and the pre-commit hook closure — even though pnpm install itself was only ~7s. Now that coverage is a `nix build` derivation, Vitest is the sole step that needs a JS toolchain. Replace `nix develop` with `nix profile install pnpm_11 bun just`, mirroring the perf-comment and pkg-pr-new jobs, then run `just test-vitest` directly. This skips the heavy shell closure while keeping the exact tools Vitest needs.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — incremental review of commit 6d4ea65 which replaces the full Nix dev shell warmup in the CI test job with targeted JS tooling installation, following the same pattern already established in other CI jobs in this repo.
- Drop the full dev shell from the test job — replaces the
nix develop --command truewarmup withnix profile install --inputs-from . nixpkgs#pnpm_11 nixpkgs#bun nixpkgs#justfollowed bypnpm install --frozen-lockfile. This skips realizing the full dev shell closure, which included linters, formatters, and pre-commit hooks that aren't needed for running vitest. The vitest step now runsjust test-vitestdirectly since the toolchain is on PATH.
Big Pickle (free via Pullfrog for OSS) | 𝕏
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |

Summary
Every commit on a PR branch triggered the full CI workflow twice — once for
the
pushevent and once forpull_request— duplicating thecheck,test,and the entire native-build matrix.
What changed
pushto themainbranch. Branch commits are now validated oncevia the
pull_requestevent;mainkeeps its post-merge run.Run test suitestep (it only fired on pushes to non-defaultbranches, which no longer happen).
Why / safety
Rust tests stay fully covered: the coverage step runs
cargo llvm-covover thewhole workspace on both remaining triggers, so the removed
just testpath isredundant. The upload step keeps its fork guard.
Tradeoff: pushing a branch without an open PR no longer runs CI. Opening
the PR runs it. This is the intended cost saving — it roughly halves CI minutes
spent per PR.
Verify
This very PR should show a single CI run (the
pull_requestrun); thepushrun for the branch is suppressed by the new
on.push.branchesfilter on thebranch's own workflow file.
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Summary by cubic
Run CI once per change by limiting
pushtomainand relying onpull_requestfor branches; branch pushes without an open PR no longer run CI. Speed up the test job by installing onlypnpm,bun, andjustinstead of realizing the full Nix dev shell.actions/upload-code-coverage.just test-vitest; coverage stays anix buildderivation.Written for commit 6d4ea65. Summary will update on new commits.
Summary by CodeRabbit