Skip to content

Geko [minor] Added declarative target selection and generated test plans - #123

Open
dmnre wants to merge 12 commits into
mainfrom
autogenerated-schemes-and-test-plans
Open

dmnre wants to merge 12 commits into
mainfrom
autogenerated-schemes-and-test-plans

Conversation

@dmnre

@dmnre dmnre commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Description

This PR reworks how Geko lets you declare schemes and test plans in your manifests. Instead of manually listing every target or hand-writing .xctestplan files, you now describe a scheme with target selection scopes and let Geko resolve them into concrete targets during generation. Generated test plans become a first-class part of a scheme's test action.

Declarative target selection (targetSelection)

A scheme's BuildAction and TestAction now accept a targetSelection parameter. Instead of enumerating targets one by one, you declare a set of scopes and Geko fills in the targets at generation time:

  • .all – include all build targets (build action) or all test targets (test action).
  • .scope(platform:products:regexp:exclude:) – include only targets matching the given filters (platform, product types, name regexes, and exclusions). The filters are combined with AND.

Schemes are declared in the schemes: parameter of the Workspace or Project manifest, and the scopes are resolved against the targets of that project (or workspace).

Generated test plans (GeneratedTestPlan)

Test plans are now declared on a scheme's testAction via .testPlans(list: [...]). Each entry is either:

  • .file(path) – reference an existing .xctestplan file on disk, or
  • .generated(...) – a test plan that Geko generates during geko generate.

.generated(...) accepts name, directory (defaults to Derived/TestPlans/<name>.xctestplan), explicit testTargets, targetSelection scopes (the same .all / .scope(...) used by test actions), configurations and defaultOptions for fine-grained control of the generated plan, and a missingTargetPolicy (.skipTestPlan, .skipTarget, or .fail).

geko test --edit-test-plan

A new --edit-test-plan flag was added to the geko test command. When passed together with --test-plan, Geko rewrites the selected test plan so that its testTargets contain exactly the targets passed via --test-targets (or all available test targets if the argument is omitted), and corrects the container: project paths so they are relative to the workspace. This avoids the problem where Xcode builds all test targets listed in a test plan even when only a subset is run, which previously dragged in unnecessary module builds and slowed down the build for projects with many focused targets.

Related Issue

geko-tech/project-description#26

Motivation and Context

For large modular projects, manually maintaining schemes and test plans in the manifests is tedious and error-prone, and hard-coded .xctestplan files become stale as targets are added or removed. Declarative target selection and generated test plans let teams define the shape of their build/test setup once and keep it in sync automatically: targets that match a scope are picked up when they are added and dropped when they are removed.

The --edit-test-plan flag solves a specific pain point: Xcode builds every test target present in a test plan even when -only-testing restricts which tests actually run. Extra test targets could pull in extra module builds (mocks, resources, etc.), which significantly hurts build times when many targets are in the focus. Rewriting the plan so it contains only the requested test targets produces a more optimal build graph.

The change also includes:

  • A new SchemeTargetSelectionResolver that resolves targetSelection scopes into concrete targets at generation time, wired into the pipeline through the new SchemeScopeResolverWorkspaceMapper.
  • A new ios_app_with_generated_test_plan fixture demonstrating a generated plan combined with an existing plan.
  • Extensive unit tests for the target-selection resolver and the XCTest plan descriptor generator.
  • Documentation for the Build and Test feature under docs/guides/features/build_and_test/ (target selection, test plan generation, scheme generation, and geko test).

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@dmnre
dmnre force-pushed the autogenerated-schemes-and-test-plans branch 2 times, most recently from 8d20a1f to 065d562 Compare September 2, 2026 10:23
Comment thread Sources/GekoGenerator/Mappers/AutogeneratedSchemesGraphMapper.swift Outdated
Comment thread Sources/GekoKit/Services/TestService.swift
Comment thread Sources/GekoSupport/Models/GenerateMetadata.swift
Comment thread Sources/GekoGenerator/Mappers/AutogeneratedSchemesGraphMapper.swift Outdated
Comment thread Sources/GekoGenerator/Generator/WorkspaceDescriptorGenerator.swift Outdated
Comment thread Sources/GekoGenerator/Generator/WorkspaceDescriptorGenerator.swift Outdated
Comment thread Sources/GekoGenerator/Generator/WorkspaceDescriptorGenerator.swift Outdated
Comment thread Sources/GekoGenerator/Mappers/AutogeneratedSchemesGraphMapper.swift Outdated
Comment thread Sources/GekoSupport/Models/AutogeneratedXCTestPlan.swift Outdated
@dmnre
dmnre force-pushed the autogenerated-schemes-and-test-plans branch from ca92a6c to 09a7d01 Compare September 10, 2026 16:00
@dmnre
dmnre marked this pull request as ready for review September 16, 2026 08:09
@dmnre
dmnre requested a review from a team September 16, 2026 08:09
Comment thread docs/guides/features/build_and_test/best_practices.md
Comment thread docs/guides/features/build_and_test/build.md
Comment thread Sources/GekoGenerator/Mappers/AutogeneratedSchemesWorkspaceGraphMapper.swift Outdated
Comment thread Sources/GekoKit/Commands/TestCommand.swift
@dmnre dmnre changed the title Geko [minor] Added AutogeneratedSchemes and AutogeneratedTestPlan Geko [minor] Added declarative target selection and generated test plans Oct 7, 2026
@dmnre
dmnre force-pushed the autogenerated-schemes-and-test-plans branch from 7257ec7 to fb29d7b Compare October 7, 2026 14:07
var scheme = schemes[index]

if var buildAction = scheme.buildAction, !buildAction.targetSelection.isEmpty {
buildAction.targets = try buildAction.targets + resolveBuildTargets(

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.

What will happen if there are multiple instances of same target references with different options?
Preferrably, we should deduplicate targets here and keep only first instance of each target reference, so users could overwrite settings from target selection.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I added deduplication of targets by their name in all places.

Comment thread Sources/GekoSupport/Models/XCTestPlan.swift
@dmnre
dmnre force-pushed the autogenerated-schemes-and-test-plans branch 2 times, most recently from 80386b7 to 60078df Compare October 19, 2026 13:13
@dmnre
dmnre force-pushed the autogenerated-schemes-and-test-plans branch from 60078df to e82a217 Compare October 20, 2026 14:02
@dmnre
dmnre force-pushed the autogenerated-schemes-and-test-plans branch from 58dbcc5 to 12eb7a5 Compare October 20, 2026 14:48

This branch has not been deployed

No deployments
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.

3 participants