Hive Hive
Sign in

fix(server): give the suite catch-all shard every module’s test products

GitHub issue · Closed

Metadata
Source
tuist/tuist #11635
Updated
Jul 5, 2026
Domains
Testing
Details

Fixes the suite-granularity catch-all shard failing with Missing test product, which is currently red on main in 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_modules table: regular shards get their assigned suites’ modules; the catch-all gets the full built-module inventory (the deterministic .xctestrun module set the CLI already sends), which includes targets that have no suite history and therefore no planned suites.
  • Tuist.Shards.get_shard/5 now separates download modules from selection modules: the -only-testing/-skip-testing selection is unchanged, but the products to download come from shard_plan_modules for 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_urls the 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 existing shard_plan_modules table rather than adding a column to shard_plans, so there’s no migration and the per-shard download-module read is uniform across granularities.
  • Module names in shard_plan_modules match the per-module upload keys (both are the target/.xctest blueprint name), consistent with how regular per-module downloads already resolve. Server-only; no client contract change (download_urls already 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

  1. 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’s download_urls include a module that has no planned suites, and that a regular shard’s do not.
  2. End to end: our own --shard-granularity suite acceptance CI (.github/workflows/cli.yml) exercises this against the branch’s server; it is red on main and 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.21canary.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

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

No GitHub comments yet.