You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .github/aw/workflow-constraints.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -69,7 +69,7 @@ When a requested feature increases risk:
69
69
70
70
When a workflow targets a self-hosted runner (any `runs-on` value other than GitHub-hosted labels such as `ubuntu-latest`, `ubuntu-slim`, `windows-latest`, or `macos-latest`), keep the generated workflow compatible with self-hosted constraints:
71
71
72
-
- Set `runs-on` explicitly (it is not inherited from imports) to the runner the user's setup provides; `runs-on` accepts a string, array, or runner-group object. Framework/generated jobs (activation, safe-outputs, unlock, etc.) default to the hosted `ubuntu-slim`, so also set `runs-on-slim` to route them to the self-hosted runner, otherwise they try to run on a hosted runner. `runs-on-slim`takes a single string label, so give it a self-hosted label the runner answers to (it cannot mirror an array or object value).
72
+
- Set `runs-on` explicitly (it is not inherited from imports) to the runner the user's setup provides; `runs-on` accepts a string, array, or runner-group object. Framework/generated jobs (activation, safe-outputs, unlock, etc.) default to the hosted `ubuntu-slim`, so also set `runs-on-slim` to route them to the self-hosted runner, otherwise they try to run on a hosted runner. `runs-on-slim`accepts the same string, array, or runner-group object forms as `runs-on`.
73
73
- Write transient state, tool downloads, and intermediate outputs under `$RUNNER_TEMP`, not `/tmp`, which can persist across jobs on shared runners.
74
74
- The agent job's own steps run as the runner user, not root — don't write steps that assume root (for example, installing to system-wide paths). Separately, the egress firewall needs host-level privileges (sudo) on the runner; if the host cannot provide that, the firewall can be disabled, which removes egress filtering. Surface that trade-off to the user rather than encoding it in the workflow.
75
75
- Declare every outbound domain the workflow contacts in `network.allowed` (keep `defaults` for the core GitHub/Copilot/registry endpoints). When the egress firewall is enabled (the default once network permissions are set), any domain that is not allow-listed is blocked.
# ADR-38965: Reuse the runs-on schema and rendering pipeline for runs-on-slim
2
+
3
+
**Date**: 2026-06-13
4
+
**Status**: Accepted
5
+
6
+
## Context
7
+
8
+
`runs-on-slim` selects the runner for all framework/generated jobs (activation, safe-outputs, unlock, APM, etc.), while `runs-on` selects the runner for the main agent job. `runs-on` already accepts the full set of GitHub Actions runner forms — a plain string label, an array of labels, or a `{ group, labels }` runner-group object — but `runs-on-slim` was schema-validated and parsed as a string only. Self-hosted users who select runners by label array or runner group therefore could not route framework jobs to the same runner they use for `runs-on`, and any such value failed to compile. The two fields configure the same concept (runner selection) and should accept the same syntax.
9
+
10
+
## Decision
11
+
12
+
We will treat `runs-on-slim` as the same kind of value as `runs-on` rather than as a distinct string field. Concretely: the JSON schema entry for `runs-on-slim` now `$ref`s the shared `#/$defs/github_actions_runs_on` definition; the in-memory `FrontmatterConfig.RunsOnSlim` field changes from `string` to `any` and is validated through the existing `validateRunsOnValue`; and `WorkflowData.RunsOnSlim` holds a **rendered `runs-on:` YAML snippet** (produced by the same extraction path as `runs-on`) instead of a bare label. Downstream consumers re-indent that snippet for the framework job context via helpers (`formatRunsOnSnippetForInlineValue`, `indentYAMLLines`). This guarantees parity with `runs-on` and avoids a second, drift-prone validation/rendering path.
13
+
14
+
## Alternatives Considered
15
+
16
+
### Alternative 1: Keep `runs-on-slim` as a string and document the limitation
17
+
Leave the type as `string` and tell users that `runs-on-slim` cannot mirror an array or runner-group value. Rejected because it permanently blocks legitimate self-hosted configurations and forces an inconsistent mental model where two runner-selection fields accept different syntax.
18
+
19
+
### Alternative 2: Add a separate schema and parser for `runs-on-slim`'s array/object forms
20
+
Duplicate the array/runner-group validation and YAML-rendering logic specifically for `runs-on-slim`. Rejected because it duplicates non-trivial logic already maintained for `runs-on`, inviting divergence over time as one path gains features or fixes the other misses.
21
+
22
+
## Consequences
23
+
24
+
### Positive
25
+
-`runs-on-slim` reaches full parity with `runs-on`, accepting string, label-array, and `{ group, labels }` forms.
26
+
- Validation and rendering reuse the existing shared `runs-on` schema and code paths, so future changes apply to both fields automatically.
27
+
- Self-hosted setups that select runners by label array or runner group can now route framework jobs correctly.
28
+
29
+
### Negative
30
+
- The internal contract of `RunsOnSlim` changes: `FrontmatterConfig.RunsOnSlim` becomes `any` and `WorkflowData.RunsOnSlim` now carries a rendered `runs-on:` snippet rather than a bare label, requiring every consumer (serialization, framework-job formatting, central slash-command resolution) to be updated and re-tested.
31
+
- Indentation handling adds complexity: snippets must be re-indented for differing YAML contexts, introducing helper functions whose correctness depends on the exact upstream rendering format.
32
+
33
+
### Neutral
34
+
- Existing tests were updated to expect rendered `runs-on:` snippets instead of bare labels, and new tests cover the array and runner-group forms.
35
+
- Reference docs, self-hosted-runner guidance, workflow constraints, and editor autocomplete metadata were updated to describe the expanded syntax.
Copy file name to clipboardExpand all lines: docs/src/content/docs/reference/frontmatter.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -195,7 +195,7 @@ runs-on-slim: ubuntu-slim # Defaults to ubuntu-slim (framework jobs o
195
195
timeout-minutes: 30 # Defaults to 20 minutes
196
196
```
197
197
198
-
`runs-on`applies to the main agent job only. `runs-on-slim` applies to all framework/generated jobs (activation, safe-outputs, unlock, etc.) and defaults to `ubuntu-slim`. `safe-outputs.runs-on` takes precedence over `runs-on-slim` for safe-output jobs specifically.
198
+
`runs-on`applies to the main agent job only. `runs-on-slim` applies to all framework/generated jobs (activation, safe-outputs, unlock, etc.), accepts the same string, array, or runner-group object forms as `runs-on`, and defaults to `ubuntu-slim`. `safe-outputs.runs-on` takes precedence over `runs-on-slim` for safe-output jobs specifically.
199
199
200
200
`timeout-minutes`accepts an integer or a GitHub Actions expression string (e.g. `${{ inputs.timeout }}`), letting a reusable `workflow_call` workflow parameterize its own timeout from caller inputs. It applies to the workflow being compiled, **not** to plain caller jobs that invoke a reusable workflow with job-level `uses:` — GitHub rejects `timeout-minutes` there.
Copy file name to clipboardExpand all lines: docs/src/content/docs/reference/self-hosted-runners.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -113,6 +113,7 @@ safe-outputs:
113
113
114
114
> [!NOTE]
115
115
> `runs-on` controls only the main agent job. `runs-on-slim` controls all framework/generated jobs. `safe-outputs.runs-on` still takes precedence over `runs-on-slim` for safe-output jobs specifically.
116
+
> `runs-on-slim` accepts the same string, array, or runner-group object forms as `runs-on`.
Copy file name to clipboardExpand all lines: pkg/parser/schemas/main_workflow_schema.json
+12-3Lines changed: 12 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -2634,9 +2634,18 @@
2634
2634
]
2635
2635
},
2636
2636
"runs-on-slim": {
2637
-
"type": "string",
2638
-
"description": "Runner for all framework/generated jobs (activation, pre-activation, safe-outputs, unlock, APM, etc.). Provides a compile-stable override for generated job runners without requiring a safe-outputs section. Overridden by safe-outputs.runs-on when both are set. Defaults to 'ubuntu-slim'. Use this when your infrastructure does not provide the default runner or when you need consistent runner selection across all jobs.",
"description": "Runner for all framework/generated jobs (activation, pre-activation, safe-outputs, unlock, APM, etc.). Provides a compile-stable override for generated job runners without requiring a safe-outputs section. Supports the same string, array, and runner-group object forms as runs-on. Overridden by safe-outputs.runs-on when both are set. Defaults to 'ubuntu-slim'. Use this when your infrastructure does not provide the default runner or when you need consistent runner selection across all jobs.",
0 commit comments