Skip to content

Commit f1109c6

Browse files
CopilotjamesadevineCopilot
authored
feat(compile): add pool-overrides for per-job pool configuration (#1464) (#1472)
* feat(compile): add pool-overrides for per-job pool configuration (#1464) Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> * refactor(compile): use imported HashMap in resolve_pool_overrides_typed signature Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> * feat(compile): move pool-overrides into pool.overrides nested key Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> * refactor(compile): add is_reviewed to SafeOutputsVariant; consolidate EMPTY_OVERRIDES static Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> * fix(compile): address second rust-review suggestions for pool-overrides Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> * fix(compile): restrict pool.overrides values to object form only (no legacy strings) Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> * refactor(compile): drop legacy scalar pool form (object-only) Remove the untagged PoolConfig::Name(String) variant and collapse PoolConfigFull into PoolConfig. Legacy scalar pool: sources are still accepted as input and migrated to object form by codemod 0002_pool_object_form before typed deserialization, so the typed layer is object-only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: fc152016-8608-47c3-bb4b-30d3565e63f0 * refactor(compile): route resolve_pool_typed through PoolConfig accessors Production code in resolve_pool_typed read the pub fields directly, which left name()/vm_image() marked #[cfg(test)] and os() marked #[allow(dead_code)]. Use the accessors consistently so they are genuinely production-used and drop the test-only/dead-code attributes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: fc152016-8608-47c3-bb4b-30d3565e63f0 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> Co-authored-by: James Devine <devinejames@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 79931cf commit f1109c6

6 files changed

Lines changed: 729 additions & 147 deletions

File tree

docs/front-matter.md

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ pool: # Optional pool configuration
2626
# pool: # 1ES pool format
2727
# name: AZS-1ES-L-MMS-ubuntu-22.04
2828
# os: linux # Operating system: "linux" or "windows". Defaults to "linux".
29+
# pool: # Pool with per-job overrides (see "Per-Job Pool Overrides" below)
30+
# name: SpecializedPool
31+
# overrides:
32+
# detection:
33+
# vmImage: ubuntu-22.04
34+
# safe-outputs:
35+
# vmImage: ubuntu-22.04
36+
# conclusion:
37+
# vmImage: ubuntu-22.04
2938
repos: # compact repository declarations (replaces repositories: + checkout:)
3039
- my-org/my-repo # shorthand: alias="my-repo", type=git, ref=refs/heads/main, checkout=true
3140
- reponame=my-org/another-repo # shorthand with explicit alias
@@ -271,7 +280,66 @@ local diagnostics. It is **not** a regular safe-output tool. Use
271280
`create-issue` to file a GitHub issue from debug pipelines; see
272281
[`ado-aw-debug.md`](ado-aw-debug.md) for the full reference.
273282

274-
## Workspace Defaults
283+
## Per-Job Pool Overrides (`pool.overrides:`)
284+
285+
By default `pool:` is applied to every generated job — Setup, Agent, Detection,
286+
SafeOutputs, Teardown, and Conclusion. The optional `pool.overrides:` map lets
287+
you assign a different pool to individual jobs while keeping the default for the
288+
rest. It is a sub-key of `pool:`, not a separate top-level key.
289+
290+
```yaml
291+
pool:
292+
name: SpecializedLinuxPool # default for all jobs
293+
overrides:
294+
detection:
295+
vmImage: ubuntu-22.04 # lightweight Microsoft-hosted image
296+
safe-outputs:
297+
vmImage: ubuntu-22.04
298+
conclusion:
299+
vmImage: ubuntu-22.04
300+
```
301+
302+
### Valid keys
303+
304+
| Key | Generated job |
305+
|---|---|
306+
| `setup` | Setup (emitted only when `setup:` steps are declared) |
307+
| `agent` | Agent |
308+
| `detection` | Detection |
309+
| `safe-outputs` | SafeOutputs (and SafeOutputs_Reviewed — see below) |
310+
| `safe-outputs-reviewed` | SafeOutputs_Reviewed only (overrides the `safe-outputs` inheritance) |
311+
| `teardown` | Teardown (emitted only when `teardown:` steps are declared) |
312+
| `conclusion` | Conclusion (emitted only when `safe-outputs:` is configured) |
313+
314+
`safe-outputs-reviewed` inherits the `safe-outputs` override unless it has its
315+
own entry. `manual-review` is **not** a valid key — the ManualReview job is
316+
agentless and always runs on `pool: server`.
317+
318+
Unknown keys produce a compiler warning and are ignored (forward-compat).
319+
320+
### Constraints
321+
322+
- Each override value accepts the same **object** pool format as the top-level
323+
`pool:` (Microsoft-hosted `vmImage:` or self-hosted `name:`). A bare pool-name
324+
string is not accepted here — use `name:`. The same mutual-exclusion rules
325+
apply: `name:` and `vmImage:` cannot both be specified; `demands:` requires
326+
`name:`.
327+
- Not supported for `target: 1es` — the 1ES pipeline template controls pool
328+
selection. Specifying `pool.overrides:` with `target: 1es` is a compile-time
329+
error.
330+
331+
### Trust boundary note
332+
333+
> When a `pool.overrides:` entry points to a different **self-hosted** pool
334+
> than the default `pool:`, that pool's administrators and agents are trusted
335+
> with the pipeline artifacts and credentials available to that job. For
336+
> Detection, SafeOutputs, and Conclusion, this includes the safe-output NDJSON
337+
> and the write-capable `SC_WRITE_TOKEN`. For `agent` and `setup`, the
338+
> overridden pool's administrators are trusted with the checked-out source tree
339+
> and the read-only build token. Using a Microsoft-hosted `vmImage:` override
340+
> does not change the trust boundary.
341+
342+
275343

276344
The `workspace:` field controls which directory the agent runs in. When it is
277345
not set explicitly, the compiler chooses a default based on which repositories

docs/safe-outputs.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,15 @@ apply one note to every tool.
123123
The Detection threat gate always runs first, so a flagged run applies nothing —
124124
automatic or reviewed.
125125

126+
> **Trust boundary note for `pool.overrides:`:** When `pool.overrides:` is used
127+
> to move Detection, SafeOutputs, or Conclusion onto a different **self-hosted**
128+
> pool than the Agent job, that pool's administrators and agents are trusted with
129+
> the pipeline artifacts and credentials available to those jobs — including the
130+
> safe-output NDJSON and the write-capable `SC_WRITE_TOKEN`. Using a
131+
> Microsoft-hosted `vmImage:` override does not change the trust boundary.
132+
> See [`docs/front-matter.md`](front-matter.md#per-job-pool-overrides-pooloverrides)
133+
> for the full reference.
134+
126135
### Safe-outputs summary tab
127136

128137
Every run that proposes safe outputs publishes a human-readable **build summary

0 commit comments

Comments
 (0)