Hive Hive
Sign in

feat(cli): print a cache warm summary with remote/local hits and misses

GitHub issue · Closed

Metadata
Source
tuist/tuist #11609
Updated
Jul 5, 2026
Domains
CLI Cache
Details

Requested on Slack: at the end of a tuist cache warm run, print how many targets were served from the remote cache, so setup/CI logs can report the remote hit rate without a server round-trip.

What changed

tuist cache warm now prints a single machine-readable summary line at the end of the warm step:

Cache warm summary: 42 remote hits, 3 local hits, 12 misses

It’s emitted on both end states of a warm run:

  • after a successful build + store (right after “All cacheable targets have been cached successfully as xcframeworks”)
  • in the “All cacheable targets are already cached” early return

Why

The CLI already computes these counts during a warm run and posts them to the server (e.g. remote_cache_target_hits), but they were only readable back after the fact (via tuist cache-run show or GET /cache-runs). They were never surfaced during the run, and the existing “Using cache binaries: …” output mixes local and remote hits, so clients couldn’t cleanly tell how many came from the remote cache.

Printing it inline lets setup and CI logs report the cache result locally, without a server round-trip each time. Including misses alongside the hits lets reporting clients compute a hit rate (hits / (hits + misses)) directly from the CLI output.

Why this approach

All three counts are derived from the same RunMetadataStorage.current.binaryCacheItems (grouped by source: .remote / .local / .miss) that flows into CommandEventFactory and gets posted to the server. So the printed numbers are consistent by construction with what tuist cache-run show and GET /cache-runs report — no separate computation that could drift. On a clean CI machine (empty local cache) hits come back from CacheStorage.fetch as .remote, so the numbers are meaningful for the reporting use case.

Scope notes:

  • Upload failures are intentionally not aggregated here. They’re already surfaced per-target as Failed to upload <name> … warnings from CacheRemoteStorage, and an aggregate count would require threading through archive/store for marginal gain. Easy to add later if needed.
  • The --generate-only path is intentionally not covered, since it doesn’t build or store anything.
  • misses equals the existing Targets to be cached: … count; it’s included as a structured field so the summary is grep-able as one line.

How to test locally

Run tuist cache warm against a project with a remote cache configured and authenticated. At the end of the run you’ll see a line such as:

Cache warm summary: 42 remote hits, 3 local hits, 12 misses

The remote hits value matches remote_cache_target_hits for the same run in tuist cache-run show / GET /cache-runs.

Validation

  • TUIST_EE=1 tuist generate tuist + xcodebuild build -scheme tuist → BUILD SUCCEEDED (recompiles CacheWarmCommandService.swift).
  • SwiftFormat clean; SwiftLint introduces no new warnings.
Flights

Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.

New Flights are paused Configure model inference, GitHub, and a sandbox provider to start another Flight. Existing results remain available below.
No Flights yet

Start a Flight and preserve its objective, outcome, and session here.

Comments
T
tuist[bot] Jul 2, 2026

🛠️ Tuist Run Report 🛠️

Tests 🧪
Scheme Status Cache hit rate Tests Skipped Ran Commit
TuistAcceptanceTests 96 % 352 0 352 b2e78a711
TuistUnitTests 97 % 668 38 630 b2e78a711
Failed Tests ❌
Flaky Tests ⚠️
  • TuistAcceptanceTests: 1 flaky test (View all)
Test case Module Suite
app_with_plugins() TuistKitAcceptanceTests PluginAcceptanceTests
Builds 🔨
Scheme Status Duration Commit
TuistAcceptanceTests 2m 2s b2e78a711
TuistUnitTests 2m 11s b2e78a711