Skip to content

perf(ci): replace coverage report with a plain Rust test run - #1273

Merged
ryoppippi merged 1 commit into
mainfrom
ci/replace-coverage-with-tests
Jun 11, 2026
Merged

ryoppippi merged 1 commit into
mainfrom
ci/replace-coverage-with-tests

Conversation

@ryoppippi

@ryoppippi ryoppippi commented Jun 11, 2026 •

Copy link
Copy Markdown
Member

Summary

The nixified cargo llvm-cov coverage build recompiled the whole workspace with
instrumentation (~230s on the arm runner) and produced a cobertura report that
nothing consumes (no badge, no docs reference). Drop coverage entirely and run
the workspace tests instead via crane's cargoTest, which reuses the shared,
non-instrumented cargoArtifacts and only compiles the test binaries.

What changed

  • nix/coverage.nix → nix/tests.nix: ccusage-tests package built with
    cargoTest (doCheck enabled). Source scoped to the Rust tree plus the few
    out-of-tree files the build/tests include_str! (flake.lock,
    ccusage.example.json, apps/ccusage/package.json) so unrelated edits don't bust
    the cache.
  • CI test job: replace the coverage generate + upload steps with
    nix build .#ccusage-tests; drop the now-unused code-quality permission and
    the upload-code-coverage action.

Notes

  • No coverage badge / docs reference exists, so nothing is orphaned.
  • Verified locally: the derivation runs the suite (253 + 10 + 51 + 16 + 2 tests
    pass) rather than skipping it.
  • Cache warmth still depends on the sticky disk retaining cargoArtifacts; a
    follow-up will add a GC root so the deps persist across runs (the same reason
    the native build currently recompiles deps every run).

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Replace the Rust coverage step with a plain test run in CI to speed up builds and remove an unused Cobertura report. Tests now run via nix build .#ccusage-tests using crane’s cargoTest, reusing cargoArtifacts.

  • Refactors
    • Replace ccusage-coverage with ccusage-tests in nix/tests.nix, built with cargoTest (doCheck enabled); workspace tests must pass.
    • CI: drop coverage generation/upload and the code-quality permission; run nix build .#ccusage-tests.
    • Limit the test source to rust plus flake.lock, ccusage.example.json, and apps/ccusage/package.json to avoid cache busts from unrelated edits.

Written for commit fccf571. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Chores
    • Updated CI/CD workflow to run tests via dedicated build steps
    • Removed coverage reporting infrastructure
    • Refactored test build configuration to use optimized test-focused dependencies
    • Reduced repository permissions in CI pipeline for improved security

The nixified `cargo llvm-cov` coverage build recompiled the whole workspace
with instrumentation (~230s) and produced a cobertura report nothing consumed
(no badge, no docs reference). Drop coverage entirely and run the workspace
tests instead via crane's `cargoTest`, which reuses the shared, non-instrumented
`cargoArtifacts` and only compiles the test binaries.

- nix/coverage.nix -> nix/tests.nix: `ccusage-tests` package built with
  `cargoTest` (doCheck enabled), source scoped to the Rust tree plus the few
  out-of-tree files the build/tests `include_str!`, so unrelated edits don't
  invalidate it.
- CI test job: replace the coverage generate + upload steps with
  `nix build .#ccusage-tests`; drop the now-unused `code-quality` permission and
  the upload-code-coverage action.

Verified locally: the derivation runs the suite (253 + 10 + 51 + 16 + 2 tests
pass) rather than skipping it.
@coderabbitai

coderabbitai Bot commented Jun 11, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR transitions the Rust test and CI infrastructure from a coverage-focused build (cargoLlvmCov + Cobertura reports) to a workspace test build (cargoTest). The Nix test module replaces the coverage module, CI steps are rewired to invoke nix build .#ccusage-tests, and the workflow is tightened by removing coverage uploads and code-quality permissions.

Changes

Rust Test Build Transition

Layer / File(s) Summary
Nix test derivation refactoring
nix/tests.nix
The module transitions from cargoLlvmCov to cargoTest, updates documentation to describe .#ccusage-tests as the workspace test target, scopes sources to Rust and select build-included files, enables doCheck = true, passes cargoExtraArgs = "--workspace", and removes coverage-specific attributes and arguments.
Flake module import update
flake.nix
The flake-parts imports list switches from ./nix/coverage.nix to ./nix/tests.nix, wiring the new test derivation into the flake configuration.
CI test job refactoring
.github/workflows/ci.yaml
The test job permissions are tightened (removing code-quality: write), comments are updated to clarify JS-only tooling for Vitest while Rust tests run via nix build, and prior Rust coverage generation/upload steps are replaced with nix build .#ccusage-tests --print-build-logs.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • ccusage/ccusage#1266: Adds nix/coverage.nix and wires CI to build and upload Cobertura reports, while this PR removes the coverage module and replaces it with a tests-focused derivation.
  • ccusage/ccusage#1268: Modifies the CI test job's Rust flow to handle ccusage-tests and coverage artifacts, overlapping with the CI rewiring in this PR.
  • ccusage/ccusage#1258: Adds a "warm Nix dev shell" step and other CI job orchestration tweaks in the same test job, potentially interacting with the test step changes here.

Suggested reviewers

  • pullfrog

Poem

🐰 From coverage to tests, we leap and we bound,
The Nix derivation spins all around,
cargoTest now builds what cargoLlvmCov knew,
CI workflows refactored, fresh build and review! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: replacing a coverage report build with a plain Rust test run, which is the core objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/replace-coverage-with-tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Pullfrog  | View workflow run | Using Big Pickle (free via Pullfrog for OSS) | 𝕏

@ryoppippi
ryoppippi merged commit b80d71b into main Jun 11, 2026
16 of 17 checks passed
@ryoppippi
ryoppippi deleted the ci/replace-coverage-with-tests branch June 11, 2026 15:55
@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: fccf571d96b6
Base SHA: 42e5b168cf0b

This compares the PR package against the configured base package on the same CI runner.

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new 42e5b168cf0b 735.7ms 872.7ms 77.4ms 3
PR pkg.pr.new fccf571 935.3ms 890.9ms 72.7ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: 42e5b168cf0b; PR package: fccf571. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 916.4ms 1.025s 0.89x 733.50 MiB 735.25 MiB 1.00x 1.10 GiB/s 1005.99 MiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 219.9ms 223.1ms 0.99x 92.50 MiB 92.75 MiB 1.00x 4.58 GiB/s 4.51 GiB/s

Package runtime diagnostics

Compares 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 /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 1.047s 984.52 MiB/s 1
claude --offline --json Installed native binary 1.01 GiB 991.0ms 1.02 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 190.4ms 5.29 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 136.3ms 7.39 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 51.1ms 51.7ms 0.99x 43.00 MiB 43.00 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
claude session --offline --json 0.00 MiB 50.9ms 49.8ms 1.02x 43.25 MiB 43.00 MiB 0.99x 0.03 MiB/s 0.03 MiB/s
codex daily --offline --json 0.00 MiB 49.0ms 48.0ms 1.02x 43.00 MiB 43.25 MiB 1.01x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 53.2ms 50.5ms 1.05x 43.25 MiB 42.75 MiB 0.99x 0.02 MiB/s 0.02 MiB/s

Large real-world-shaped fixture performance

Generated 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 /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 963.9ms 941.0ms 1.02x 733.50 MiB 731.75 MiB 1.00x 1.04 GiB/s 1.07 GiB/s
codex --offline --json 1.01 GiB 180.4ms 181.2ms 1.00x 91.25 MiB 91.50 MiB 1.00x 5.58 GiB/s 5.56 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB +0.00 KiB 1.00x
installed native package binary 3324.84 KiB 3324.84 KiB +0.00 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: fccf571d96b6
Base SHA: 42e5b168cf0b

This compares the Rust PR release binary against the configured base package on the same CI runner.

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new 42e5b168cf0b 850.5ms 962.3ms 90.1ms 3
PR pkg.pr.new fccf571 816.3ms 1.122s 75.8ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: 42e5b168cf0b; PR package: fccf571. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 1.018s 1.055s 0.96x 738.50 MiB 726.25 MiB 0.98x 1012.99 MiB/s 977.28 MiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 268.3ms 267.8ms 1.00x 92.00 MiB 95.00 MiB 1.03x 3.75 GiB/s 3.76 GiB/s

Package runtime diagnostics

Compares 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 /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 893.5ms 1.13 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 883.8ms 1.14 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 237.0ms 4.25 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 162.9ms 6.18 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 63.2ms 10.0ms 6.29x 43.00 MiB 3.00 MiB 0.07x 0.02 MiB/s 0.15 MiB/s
claude session --offline --json 0.00 MiB 61.5ms 9.6ms 6.41x 43.00 MiB 2.75 MiB 0.06x 0.03 MiB/s 0.16 MiB/s
codex daily --offline --json 0.00 MiB 60.7ms 11.1ms 5.46x 43.00 MiB 2.75 MiB 0.06x 0.01 MiB/s 0.08 MiB/s
codex session --offline --json 0.00 MiB 75.0ms 14.9ms 5.05x 43.00 MiB 2.75 MiB 0.06x 0.01 MiB/s 0.06 MiB/s

Large real-world-shaped fixture performance

Generated 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 /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 979.6ms 744.1ms 1.32x 726.75 MiB 739.25 MiB 1.02x 1.03 GiB/s 1.35 GiB/s
codex --offline --json 1.01 GiB 223.9ms 179.7ms 1.25x 94.00 MiB 95.00 MiB 1.01x 4.50 GiB/s 5.60 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB +0.00 KiB 1.00x
installed native package binary 3324.84 KiB 3324.84 KiB +0.00 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant