Repository navigation
ci(cache): scope macOS Nix cache key by target arch - #1294
Conversation
The arm64 and x64 macOS native packages both build on the same arm64 Blacksmith runner (x64 cross-compiles via the multi-arch Apple SDK), so runner.os and runner.arch are identical for both jobs. They therefore shared a single cache-nix-action key (`nix-macOS-ARM64-<hash>`) and clobbered each other's restored store on every run, leaving the Intel build effectively uncached. Thread a `cache-key-suffix` input through setup-nix into setup-macos-nix-cache and pass the target arch from build-macos-nix-native-package, so build-mac-arm64 and build-mac-x64 get independent cache entries.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ccusage-guide | c9be5a0 | Commit Preview URL Branch Preview URL |
Jun 11 2026, 11:58 PM |
|
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)
📝 WalkthroughWalkthroughThree composite GitHub Actions are updated to thread an architecture-scoped cache-key suffix: ChangesmacOS Nix Cache Scoping
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 |
There was a problem hiding this comment.
Caution
The cache-key-suffix input on setup-nix is declared but never forwarded to setup-macos-nix-cache, making the entire change a no-op.
Reviewed changes — scope the macOS Nix cache key by target arch so arm64 and x64 builds on the shared arm64 runner get independent caches.
- Add
key-suffixinput tosetup-macos-nix-cache— appended to primary-key, restore-prefix, and purge-prefix - Add
cache-key-suffixinput tosetup-nix— declared with a description and default, intended to forward to the macOS cache action - Pass
archfrombuild-macos-nix-native-packagetosetup-nixvia the new input
Note: 1 inline comment(s) dropped because they did not anchor to lines inside the PR diff:
.github/actions/setup-nix/action.yaml:20(RIGHT) — line 20 (RIGHT) is not inside a diff hunk
Big Pickle (free via Pullfrog for OSS) | 𝕏
|
Technical details for the The - uses: ./.github/actions/setup-macos-nix-cache
if: runner.os == 'macOS'Without forwarding, Fix: Add a - uses: ./.github/actions/setup-macos-nix-cache
if: runner.os == 'macOS'
with:
key-suffix: ${{ inputs.cache-key-suffix }}This is the only missing piece — the rest of the threading (
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/actions/setup-nix/action.yaml (1)
20-21:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winCritical: Forward
cache-key-suffixto the macOS cache action.The
cache-key-suffixinput declared at lines 4-6 is never passed tosetup-macos-nix-cache. Without this forwarding, the architecture-scoped cache keys won't be generated, and arm64/x64 builds will still clobber each other's Nix store cache.🔧 Proposed fix
- uses: ./.github/actions/setup-macos-nix-cache if: runner.os == 'macOS' + with: + key-suffix: ${{ inputs.cache-key-suffix }}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/actions/setup-nix/action.yaml around lines 20 - 21, The macOS step that uses ./.github/actions/setup-macos-nix-cache is not forwarding the declared input cache-key-suffix, so add a with block to that step to pass cache-key-suffix: ${{ inputs.cache-key-suffix }} (i.e., update the step that references ./.github/actions/setup-macos-nix-cache to include a with: cache-key-suffix: ${{ inputs.cache-key-suffix }} entry) so architecture-scoped cache keys are generated correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In @.github/actions/setup-nix/action.yaml:
- Around line 20-21: The macOS step that uses
./.github/actions/setup-macos-nix-cache is not forwarding the declared input
cache-key-suffix, so add a with block to that step to pass cache-key-suffix: ${{
inputs.cache-key-suffix }} (i.e., update the step that references
./.github/actions/setup-macos-nix-cache to include a with: cache-key-suffix: ${{
inputs.cache-key-suffix }} entry) so architecture-scoped cache keys are
generated correctly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: db58a337-5483-4c33-9f98-cec749fc4eae
📒 Files selected for processing (3)
.github/actions/build-macos-nix-native-package/action.yaml.github/actions/setup-macos-nix-cache/action.yaml.github/actions/setup-nix/action.yaml
Co-authored-by: Codesmith <[email protected]>
ccusage
@ccusage/ccusage-darwin-arm64
@ccusage/ccusage-darwin-x64
@ccusage/ccusage-linux-arm64
@ccusage/ccusage-linux-x64
@ccusage/ccusage-win32-x64
commit: |
There was a problem hiding this comment.
2 issues found and verified against the latest diff
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".github/actions/setup-nix/action.yaml">
<violation number="1" location=".github/actions/setup-nix/action.yaml:4">
P2: New `cache-key-suffix` input is defined but never forwarded to the macOS cache action, so it has no effect.</violation>
</file>
<file name=".github/actions/setup-macos-nix-cache/action.yaml">
<violation number="1" location=".github/actions/setup-macos-nix-cache/action.yaml:16">
P2: Empty `key-suffix` still adds a separator, unintentionally changing the default cache namespace.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
| name: Setup Nix | ||
| description: Install Nix with platform-specific cache setup | ||
| inputs: | ||
| cache-key-suffix: |
There was a problem hiding this comment.
P2: New cache-key-suffix input is defined but never forwarded to the macOS cache action, so it has no effect.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/actions/setup-nix/action.yaml, line 4:
<comment>New `cache-key-suffix` input is defined but never forwarded to the macOS cache action, so it has no effect.</comment>
<file context>
@@ -1,5 +1,9 @@
name: Setup Nix
description: Install Nix with platform-specific cache setup
+inputs:
+ cache-key-suffix:
+ description: Extra suffix to scope the macOS Nix cache key (e.g. cross target arch)
+ default: ''
</file context>
| with: | ||
| primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('flake.lock', 'flake.nix', 'default.nix', 'package.nix', 'package.json', 'nix/**/*.nix', 'rust-toolchain.toml', 'rust/Cargo.lock', 'rust/**/Cargo.toml') }} | ||
| restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}- | ||
| primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key-suffix }}-${{ hashFiles('flake.lock', 'flake.nix', 'default.nix', 'package.nix', 'package.json', 'nix/**/*.nix', 'rust-toolchain.toml', 'rust/Cargo.lock', 'rust/**/Cargo.toml') }} |
There was a problem hiding this comment.
P2: Empty key-suffix still adds a separator, unintentionally changing the default cache namespace.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/actions/setup-macos-nix-cache/action.yaml, line 16:
<comment>Empty `key-suffix` still adds a separator, unintentionally changing the default cache namespace.</comment>
<file context>
@@ -1,15 +1,22 @@
with:
- primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('flake.lock', 'flake.nix', 'default.nix', 'package.nix', 'package.json', 'nix/**/*.nix', 'rust-toolchain.toml', 'rust/Cargo.lock', 'rust/**/Cargo.toml') }}
- restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}-
+ primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key-suffix }}-${{ hashFiles('flake.lock', 'flake.nix', 'default.nix', 'package.nix', 'package.json', 'nix/**/*.nix', 'rust-toolchain.toml', 'rust/Cargo.lock', 'rust/**/Cargo.toml') }}
+ restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key-suffix }}-
gc-max-store-size-macos: 3500000000
</file context>
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. |
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
The arm64 and x64 macOS native packages both build on the same arm64 Blacksmith runner (x64 cross-compiles via the multi-arch Apple SDK), so
runner.os/runner.archare identical for both. They shared onecache-nix-actionkey (nix-macOS-ARM64-<hash>) and clobbered each other's restored Nix store every run — leaving the Intel build effectively uncached and cold.What changed
key-suffixinput tosetup-macos-nix-cachethat is appended to the primary key, restore prefix, and purge prefix.cache-key-suffixinput tosetup-nixthat forwards to the macOS cache action.build-macos-nix-native-packagenow passes the targetarchas the suffix.Result:
build-mac-arm64→nix-macOS-ARM64-arm64-<hash>,build-mac-x64→nix-macOS-ARM64-x64-<hash>. Independent caches, no clobber. Both keys re-warm once on first run.Need help on this PR? Tag
/codesmithwith what you need. Autofix is enabled.Summary by cubic
Scope the macOS Nix cache key by target arch so arm64 and x64 builds get separate caches on the shared arm64 runner. Stops cache clobbering and keeps both builds warm.
key-suffixtosetup-macos-nix-cacheand applied it to primary, restore, and purge keys.cache-key-suffixtosetup-nixand forwarded it tosetup-macos-nix-cache.build-macos-nix-native-packagepasses the targetarchas the suffix (e.g.,nix-macOS-ARM64-arm64-<hash>and...-x64-<hash>).Written for commit c9be5a0. Summary will update on new commits.
Summary by CodeRabbit