feat: allow multiple targets in apm.yml and --target CLI flag#628
Open
sergio-sisternes-epam wants to merge 15 commits intomicrosoft:mainfrom
Open
feat: allow multiple targets in apm.yml and --target CLI flag#628sergio-sisternes-epam wants to merge 15 commits intomicrosoft:mainfrom
sergio-sisternes-epam wants to merge 15 commits intomicrosoft:mainfrom
Conversation
Fixes microsoft#529 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add ALL_CANONICAL_TARGETS, TARGET_ALIASES, and normalize_target_list() helper to target_detection.py. These are the foundation for multi-target support (microsoft#529). Purely additive — no existing functions changed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Widen APMPackage.target type from Optional[str] to Optional[Union[str, List[str]]]. PyYAML naturally returns list for YAML sequences, so no parsing changes needed. Add 6 tests covering string, list, missing, single-item-list, and direct construction. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ft#529) Widen explicit_target parameter in active_targets(), active_targets_user_scope(), and resolve_targets() from Optional[str] to Optional[Union[str, List[str]]]. List handling: iterate targets, resolve aliases (vscode/agents -> copilot), deduplicate by profile name, short-circuit on 'all'. Single-string path unchanged for backward compatibility. Add 11 tests for list input covering single-element, multi-element, alias dedup, all-in-list, mixed known/unknown, order preservation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t#529) Add TargetParamType (Click parameter type) that accepts comma-separated target values. Single values and 'all' return strings for backward compat; multiple targets return deduplicated list of canonical names. - Validates each token against VALID_TARGET_VALUES (derived, not hardcoded) - Enforces 'all' exclusivity ('all,claude' is rejected) - Resolves aliases (vscode/agents -> copilot) on multi-target path - Handles whitespace, empty parts, case normalization Replace click.Choice with TargetParamType in compile, install, pack, and deps commands. Add 37 tests for TargetParamType. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The install command already uses resolve_targets() for multi-target resolution. The detect_target() call was assigning to unused variables (detected_target, detection_reason). Remove the dead code and its now-unused imports to prepare for multi-target list support where detect_target() would break on list input. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…oft#529) Update _check_compilation_target() to handle target field being a list: - enforce: check if enforced value is present in the target list - allow: check every item in target list is in the allow set - Backward compat: single strings normalized to [string] internally Add 6 tests covering list enforce/allow scenarios plus backward compat. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Compile command: - Add _resolve_compile_target() to map list inputs to compiler strings (copilot+claude -> 'all', claude-only -> 'claude', etc.) - Apply to both CLI --target and apm.yml config_target - Update progress logging for multi-target display Pack/bundle: - Update _filter_files_by_target() to compute union of prefixes and cross-target maps for list targets - Update enrich_lockfile_for_pack() to accept and serialize list targets - Update pack_bundle() to pass lists directly, bypassing detect_target() Add 23 tests covering list target resolution, filtering, and packing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- CHANGELOG: add multi-target feature entry - manifest-schema: target field type widened to string|list - cli-commands: --target accepts comma-separated values - compilation guide: multi-target examples - pack-distribute: multi-target pack example - policy-reference: enforce/allow semantics with lists - apm-guide skills: update commands, workflow, governance Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds multi-target support across APM’s manifest parsing, target resolution, CLI parsing, packing, and policy checks so users can specify a subset of targets (e.g. claude,copilot) instead of all.
Changes:
- Extend target handling to accept
str | list[str]in manifests, CLI, and target resolution. - Introduce a Click
TargetParamTypeto parse comma-separated--targetvalues with alias handling. - Update pack/lockfile enrichment, policy checks, and documentation; add unit tests for list-target behavior.
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/test_packer.py | Adds pack-time coverage for list target filtering and pack metadata serialization. |
| tests/unit/test_lockfile_enrichment.py | Adds coverage for list-target filtering and lockfile pack.target serialization. |
| tests/unit/test_apm_package.py | Adds coverage for apm.yml target field accepting string or list. |
| tests/unit/policy/test_policy_checks.py | Adds list-target coverage for compilation target policy enforcement/allow lists. |
| tests/unit/integration/test_targets.py | Adds coverage for active_targets() handling explicit target lists. |
| tests/unit/core/test_target_detection.py | Adds coverage for the new TargetParamType and accepted values. |
| tests/unit/compilation/test_compile_target_flag.py | Adds coverage for compile list-target mapping via _resolve_compile_target(). |
| src/apm_cli/policy/policy_checks.py | Updates compilation target policy checks to handle list targets. |
| src/apm_cli/models/apm_package.py | Widens APMPackage.target type to Optional[Union[str, List[str]]]. |
| src/apm_cli/integration/targets.py | Extends active_targets*()/resolve_targets() to accept list explicit targets. |
| src/apm_cli/core/target_detection.py | Adds multi-target constants/helpers and the Click TargetParamType. |
| src/apm_cli/commands/pack.py | Switches --target to TargetParamType() and updates help text. |
| src/apm_cli/commands/install.py | Switches --target to TargetParamType() and removes dead detection code. |
| src/apm_cli/commands/deps/cli.py | Switches --target to TargetParamType() and updates help text. |
| src/apm_cli/commands/compile/cli.py | Adds _resolve_compile_target() and supports list targets in compile flow/logging. |
| src/apm_cli/bundle/packer.py | Allows pack_bundle() to accept list targets from CLI or manifest. |
| src/apm_cli/bundle/lockfile_enrichment.py | Extends target filtering/enrichment to accept list targets and serialize pack.target. |
| packages/apm-guide/.apm/skills/apm-usage/workflow.md | Documents manifest/CLI multi-target syntax and updated detection wording. |
| packages/apm-guide/.apm/skills/apm-usage/governance.md | Clarifies policy semantics when targets are lists. |
| packages/apm-guide/.apm/skills/apm-usage/commands.md | Documents comma-separated --target on relevant commands. |
| docs/src/content/docs/reference/manifest-schema.md | Updates manifest target schema to allow `string |
| docs/src/content/docs/reference/cli-commands.md | Documents comma-separated multi-target --target for install/pack/compile/deps update. |
| docs/src/content/docs/introduction/how-it-works.md | Notes that apm.yml target can restrict auto-detected targets (string or list). |
| docs/src/content/docs/guides/pack-distribute.md | Adds example for comma-separated multi-target packing. |
| docs/src/content/docs/guides/compilation.md | Adds example for comma-separated multi-target compilation and manifest list syntax. |
| docs/src/content/docs/enterprise/policy-reference.md | Updates policy docs to describe list-target enforcement and expanded allowed values. |
| CHANGELOG.md | Adds an entry describing multi-target support. |
…osoft#628) - Replace all non-ASCII characters (em dashes, Unicode arrows, box-drawing) with ASCII equivalents across 4 source files - Fix normalize_target_list('all') to return sorted target list instead of None (clearer semantics, function currently unused) - Add code comment documenting dict.update() last-wins limitation in cross-target map merging for multi-target packs - Move CHANGELOG entry to [Unreleased] section, reference PR microsoft#628 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
danielmeppiel
approved these changes
Apr 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Multi-target support for
apm.ymland CLI--targetCloses #529
Problem
Users deploying to 2-3 tools (e.g. Copilot + Claude) had to choose between a single
--targetorall, which generates redundant output for tools they don't use.Solution
Allow specifying multiple targets via list syntax in
apm.ymland comma-separated values on the CLI:# CLI apm compile -t claude,copilot apm install owner/repo -t claude,copilot apm pack -t claude,copilot apm deps update -t claude,copilotArchitecture
Unified through the existing
active_targets()/resolve_targets()TargetProfile system -- no breaking API changes:detect_target()stays scalar (Optional[str]) -- unchangedactive_targets()/resolve_targets()widened to acceptOptional[Union[str, List[str]]]TargetParamType(new Click parameter type) handles comma-separated parsing, alias resolution, validation_resolve_compile_target()List[TargetProfile]-- minimal change (removed dead code)enforce/allowchecks handle list targetsChanges
feat: add normalize_target_list() and multi-target constantsfeat(manifest): accept list in apm.yml target fieldAPMPackage.targettype widenedfeat(targets): accept list in active_targets/resolve_targetsfeat(cli): add TargetParamType for comma-separated --targetrefactor(install): remove dead detect_target callfeat(policy): handle list targets in compilation target checkfeat(compile,pack): handle multi-target listsdocs: document multi-target supportBackward compatibility
target: copilotand-t copilotwork exactly as before"all"is exclusive -- cannot be combined with other targetsvscode,agents) resolve tocopilotin multi-target contextdetect_target()return type or lockfile schemaTesting