Hive
fix(server): give the suite catch-all shard every module’s test products
GitHub issue · Closed
Fixes the suite-granularity catch-all shard failing with
Missing test product, which is currently red onmainin our own acceptance-test CI (main CLI → Acceptance Tests (1) → Run shard 1).
What changed
For suite-granularity shard plans, the catch-all shard (the last shard) selects nothing via -only-testing — its modules list is intentionally empty and it instead runs “everything except the suites assigned to earlier shards” via -skip-testing. This PR gives that shard the products it actually needs to run:
- At plan creation we record the per-shard download modules for suite plans in the existing
shard_plan_modulestable: regular shards get their assigned suites’ modules; the catch-all gets the full built-module inventory (the deterministic.xctestrunmodule set the CLI already sends), which includes targets that have no suite history and therefore no planned suites. Tuist.Shards.get_shard/5now separates download modules from selection modules: the-only-testing/-skip-testingselection is unchanged, but the products to download come fromshard_plan_modulesfor the shard (uniform across module and suite granularity). A fallback keeps plans created before this change working when read across a deploy.- The CLI needs no change — it downloads whatever
download_urlsthe server returns.
Why — the root cause
Per-shard split downloads (#11314) hand each shard the single shared artifact plus one per-module .aar for the modules in its response. The catch-all’s response carries modules: [], so it only downloaded shared.aar.
But the shared artifact holds the .xctestrun, which references every built test target, and xcodebuild test-without-building loads all referenced targets before applying -skip-testing. With the per-module .xctest bundles missing, it fails:
xcodebuild: error: Failed to build workspace Tuist with scheme TuistAcceptanceTests.:
Cannot test target "TuistDependenciesAcceptanceTests" on "My Mac":
Missing test product at …/xctestproducts/Tests/0/Debug/TuistDependenciesAcceptanceTests.xctest
Simply downloading “the plan’s suite modules” is not enough: the plan is derived from suite history, so it only knows targets that have historical suites. In our own acceptance run the plan knew 3 of 6 acceptance-test targets — and the missing ones (e.g. TuistDependenciesAcceptanceTests) are exactly the un-enumerated targets the catch-all exists to run. The only reliable source of the full built-module universe is what the CLI enumerated from the .xctestrun at plan creation, so we persist that.
Design notes
- The catch-all’s full-inventory download set is genuinely new information (it isn’t derivable from
shard_plan_test_suites, which never sees history-less targets), so it has to be persisted somewhere. We store it in the existingshard_plan_modulestable rather than adding a column toshard_plans, so there’s no migration and the per-shard download-module read is uniform across granularities. - Module names in
shard_plan_modulesmatch the per-module upload keys (both are the target/.xctestblueprint name), consistent with how regular per-module downloads already resolve. Server-only; no client contract change (download_urlsalready existed).
Impact
- Suite-granularity sharding with split (per-module) uploads: the catch-all shard can load and run the whole
.xctestrun. This unblocks our own acceptance CI and any project on suite granularity that downloads products (rather than passing--shard-archive-path, which already carries a full local archive and so did not hit this).
Validation
mix test test/tuist/shards_test.exs— 34 passed, incl. a new test reproducing the failure: a built module (NewTests) with no suite history that the catch-all must still download, plus an assertion that a regular shard does not over-download it.mix test test/tuist_web/controllers/api/shards_controller_test.exs— 24 passed.
How to test locally
cd server && mise exec -- mix test test/tuist/shards_test.exs— the case"catch-all shard downloads products for every module, including un-enumerated ones"asserts the catch-all’sdownload_urlsinclude a module that has no planned suites, and that a regular shard’s do not.- End to end: our own
--shard-granularity suiteacceptance CI (.github/workflows/cli.yml) exercises this against the branch’s server; it is red onmainand should go green with this change.
Note
There is a related, separate issue not addressed here: the server enables the suite catch-all for CLIs >= 4.202.0-canary.21, but the tuist test path only applies the catch-all’s -skip-testing from canary.26 (#11314) — so tuist test on canary.21–canary.25 silently drops the skip and re-runs the whole plan. The follow-up is to bump @suite_catch_all_minimum_cli_version to canary.26. Happy to fold that into this PR if preferred.
🤖 Generated with Claude Code
Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.
Start a Flight and preserve its objective, outcome, and session here.
No GitHub comments yet.