diff --git a/.github/aw/syntax-agentic.md b/.github/aw/syntax-agentic.md index c7d40f45cab..f14ac157c77 100644 --- a/.github/aw/syntax-agentic.md +++ b/.github/aw/syntax-agentic.md @@ -217,59 +217,7 @@ description: Agentic workflow specific frontmatter fields for GitHub Agentic Wor - Set `run-install-scripts: true` under `runtimes.node` to allow scripts for Node.js installs - A supply chain security warning is emitted at compile time; in strict mode this is an error -- **`checkout:`** - Override how the repository is checked out in the agent job (object, array, or `false`) - - By default, the workflow automatically checks out the repository. Use this field to customize checkout behavior. - - Set to `false` to disable automatic checkout entirely (reduces startup time when repo access is not needed): - - ```yaml - checkout: false - ``` - - - Target-only checkout for sidecar/MultiRepoOps workflows: set `permissions.contents: none` to skip only the automatic workflow-repository checkout while still checking out other explicitly configured `checkout:` entries (e.g. a target repository). Unlike `checkout: false`, additional checkout entries are unaffected: - - ```yaml - permissions: - contents: none - checkout: - - repository: octo-org/target-repository - path: target - github-token: ${{ secrets.TARGET_REPO_PAT }} - ``` - - - Single checkout (object): - - ```yaml - checkout: - fetch-depth: 0 # Fetch full history (default: 1 = shallow clone) - github-token: ${{ secrets.MY_PAT }} # Override token for private repos - ``` - - - Multiple checkouts (array): - - ```yaml - checkout: - - path: . - fetch-depth: 0 - - repository: owner/other-repo - path: ./libs/other - ref: main - ``` - - - Supported fields per checkout entry: - - `repository:` - Repository in `owner/repo` format (defaults to current repository) - - `ref:` - Branch, tag, or SHA to check out (defaults to triggering ref) - - `path:` - Relative path within `GITHUB_WORKSPACE` (defaults to workspace root) - - `fetch-depth:` - Number of commits to fetch; `0` = full history, `1` = shallow (default) - - `fetch:` - Additional Git refs to fetch after checkout (array of patterns) - - `"*"` - fetch all remote branches - - `"refs/pulls/open/*"` - all open pull-request refs - - Branch names, glob patterns (e.g., `"feature/*"`) - - Example: `fetch: ["*"]`, `fetch: ["refs/pulls/open/*"]` - - `sparse-checkout:` - Newline-separated glob patterns for sparse checkout - - `submodules:` - Submodule handling: `"recursive"`, `"true"`, or `"false"` - - `lfs:` - Download Git LFS objects (boolean, default: `false`) - - `wiki:` - Check out the repository's wiki (boolean, default: `false`). When `true`, automatically appends `.wiki` to the repository name. Combine with `repository:` to check out a different repo's wiki. - - `github-token:` - Token for authentication (`${{ secrets.MY_PAT }}`); credentials removed after checkout +- **`checkout:`** - Override how the repository is checked out in the agent job (object, array, or `false`). By default, the workflow automatically checks out the repository. Set to `false` to disable automatic checkout entirely, or set `permissions.contents: none` to skip only the automatic workflow-repository checkout while still running other explicitly configured `checkout:` entries. Supports single or multiple checkout entries, GitHub App/token auth, sparse/shallow/LFS/submodule/wiki options, and an opt-in `multi: true` allowlisted multi-repository mode. Full field reference and examples: [syntax-checkout.md](syntax-checkout.md). - **`jobs:`** - Groups together all the jobs that run in the workflow (object) - Standard GitHub Actions jobs configuration diff --git a/.github/aw/syntax-checkout.md b/.github/aw/syntax-checkout.md new file mode 100644 index 00000000000..a34a2e637ec --- /dev/null +++ b/.github/aw/syntax-checkout.md @@ -0,0 +1,87 @@ +--- +description: Full `checkout:` field reference — single/array/disabled checkout, per-entry fields, and the multi-repository allowlist (`multi`, `allowed-repos`, `allow-private-repos`, `max-repos`). +--- + +# Checkout Configuration (`checkout:`) + +Override how the repository is checked out in the agent job. Accepts a single checkout object, an array of checkout objects, or `false`. + +## Disabling checkout + +Set to `false` to skip automatic checkout entirely (reduces startup time when repo access is not needed): + +```yaml +checkout: false +``` + +Target-only checkout for sidecar/MultiRepoOps workflows: set `permissions.contents: none` to skip only the automatic workflow-repository checkout while still checking out other explicitly configured `checkout:` entries (e.g. a target repository). Unlike `checkout: false`, additional checkout entries are unaffected: + +```yaml +permissions: + contents: none +checkout: + - repository: octo-org/target-repository + path: target + github-token: ${{ secrets.TARGET_REPO_PAT }} +``` + +## Single and multiple checkouts + +Single checkout (object): + +```yaml +checkout: + fetch-depth: 0 # Fetch full history (default: 1 = shallow clone) + github-token: ${{ secrets.MY_PAT }} # Override token for private repos +``` + +Multiple checkouts (array): + +```yaml +checkout: + - path: . + fetch-depth: 0 + - repository: owner/other-repo + path: ./libs/other + ref: main +``` + +## Per-entry fields + +- `repository:` / `repo:` (alias) - Repository in `owner/repo` format (defaults to current repository). Without `multi: true`, must resolve to exactly one repository; wildcards are not supported. +- `ref:` - Branch, tag, or SHA to check out (defaults to the triggering ref) +- `path:` - Relative path within `GITHUB_WORKSPACE` (defaults to workspace root). In `multi: true` mode this is a literal prefix: repositories land under `prefix/owner/repo`. +- `fetch-depth:` - Number of commits to fetch; `0` = full history, `1` = shallow (default). When multiple configs target the same path, the deepest value wins. +- `fetch:` - Additional Git refs to fetch after checkout (string or array of patterns) + - `"*"` - fetch all remote branches + - `"refs/pulls/open/*"` - all open pull-request refs + - Branch names, glob patterns (e.g., `"feature/*"`) +- `sparse-checkout:` - Newline-separated glob patterns for sparse checkout; merged when multiple configs target the same path +- `submodules:` - Submodule handling: `"recursive"`, `"true"`, or `"false"`. `multi: true` checkouts require `false` or omission — submodule URLs can otherwise bypass the allowlist. +- `lfs:` - Download Git LFS objects (boolean, default: `false`). `multi: true` checkouts reject `lfs: true` for the same allowlist-bypass reason. +- `wiki:` - Check out the repository's wiki (boolean, default: `false`). When `true`, appends `.wiki` to the repository name. +- `github-token:` - Token for authentication (`${{ secrets.MY_PAT }}`); credentials are always removed after checkout (`persist-credentials: false` is enforced). `token:` is a deprecated alias. +- `github-app:` - GitHub App authentication (mints a short-lived installation token via `actions/create-github-app-token`); mutually exclusive with `github-token` +- `safe-outputs-github-app:` - GitHub App used only by safe-output checkout/fetch/push operations for this target; does not change activation/agent checkout authentication +- `current:` - Marks this checkout as the logical current/primary repository for the workflow (only one entry may set this) +- `pull-request:` - Set `false` to disable the compiler-generated PR branch checkout and its base-config snapshot/restore steps +- `force-clean-git-credentials:` - Persist credentials during checkout, then run a post-checkout cleanup step that removes them from root and submodule git configs + +## Multi-repository checkout (`multi: true`) + +Runtime-expanded repository lists (e.g. a newline-separated `repository:`/`repo:` value, or a dynamic expression) require explicit opt-in — without `multi: true`, `repository`/`repo` must resolve to exactly one `owner/repo` slug and ordinary single-checkout behavior applies. + +```yaml +checkout: + - repository: ${{ github.event.inputs.repos }} # newline-separated list + multi: true + allowed-repos: ["myorg/*"] # required allowlist + path: workspace +``` + +- `multi:` (boolean, default `false`) - Explicitly enables runtime repository-list expansion and its allowlist, visibility, path, and secondary-fetch restrictions. Requires `allowed-repos`. +- `allowed-repos:` - Required allowlist when `multi: true` is set; does not enable multi mode by itself. Accepts a newline-separated string, an array, or a whole GitHub Actions expression referencing a repository or organization configuration variable (e.g. `${{ vars.ALLOWED_REPOS }}`). Supports scoped wildcard patterns such as `owner/*` or `*/repo`, but not unrestricted wildcards such as `*` or `*/*`. Caller-controlled contexts, dynamic indexing, and composite/mixed expressions are rejected. +- `allow-private-repos:` (boolean, default `false`) - With `multi: true`, allows private or internal targets only when the hosting workflow repository is itself private or internal. Public hosting repositories always reject non-public targets, even when `true`. Every merged multi entry must opt in explicitly. Has no effect in single-repository mode. +- `max-repos:` (integer, default `10`) - Maximum number of unique repositories per `multi: true` checkout entry. Oversized lists fail before any metadata request or checkout; matching and deduplication are case-insensitive. Merged multi entries use the smallest effective limit, including the default for omitted values. Has no effect in single-repository mode. + +See [network.md](network.md) for firewall/egress interactions and [workflow-constraints.md](workflow-constraints.md) for other job-level security boundaries. diff --git a/.github/aw/syntax-engine.md b/.github/aw/syntax-engine.md index a439211dd28..ab2899b90aa 100644 --- a/.github/aw/syntax-engine.md +++ b/.github/aw/syntax-engine.md @@ -94,5 +94,5 @@ See [syntax-agentic.md](syntax-agentic.md) for the full frontmatter field index. Constraints: exactly one runtime key per `driver` object; source must be non-empty; only supported on the `copilot` engine. Use `runtimes..version` to pin the runtime version used for the generated module files (e.g. `runtimes.go.version: "1.22"`). - **`engine.auth:`** — keyless Workload Identity Federation via the AWF API proxy instead of a static API key; requires `id-token: write`. Set `type: github-oidc` (only supported type) plus `provider: azure` (`azure-tenant-id`, `azure-client-id`, optional `azure-scope`/`azure-cloud`) for Azure OpenAI, `provider: anthropic` (`federation-rule-id`, `organization-id`, `service-account-id`, `workspace-id`) for Claude, or `provider: gcp` (`workload-identity-provider`, `service-account`, optional `project`/`location`, default region `us-central1`) for Vertex AI / Gemini Enterprise. Optional `audience:`. Maps to `AWF_AUTH_*` env vars. - - **`engine.model-routing:`** (experimental; Copilot, Claude, Codex, and pi engines) — lets AWF pick a Copilot model per task from the rendered prompt instead of a fixed `model`/effort. Requires the AWF firewall and a minimum AWF version; not combinable with `fallback-models`, a custom driver, or harness. Required sub-fields: `goal` (`cost` | `cost-speed`), `mode` (`economy` | `balanced` | `robust` | `auto`), `allowed-models` (non-empty list of routing-candidate Copilot model names the router may select and the routed task may call; declared sub-agent models are admitted separately and do not need to appear here; supports GitHub Actions expressions when no `models.allowed`/`models.blocked` policy is set, and merges lists from imported workflows selecting the same engine; static lists must satisfy those policies). See [model-routing reference](https://github.github.com/gh-aw/reference/model-routing/). + - **`engine.model-routing:`** (experimental; Copilot, Claude, Codex, and pi engines) — lets AWF pick a Copilot model per task from the rendered prompt instead of a fixed `model`/effort. Requires the AWF firewall and a minimum AWF version; not combinable with `fallback-models`, a custom driver, or harness. Required sub-fields: `goal` (`cost` | `cost-speed`), `mode` (`economy` | `balanced` | `robust` | `auto`). Optional `allowed-models` (exact Copilot model names that narrow the router's choice for the main agent only; this is not a request policy — put patterns like `gpt-*` in `models.allowed`/`models.blocked` instead; when omitted, the router picks from whatever the policy allows, with Claude/Codex limited to their own model family; across imported workflows routing the same engine, any one omission means no shortlist, otherwise their lists are combined; GitHub Actions expressions are allowed only when neither `models.allowed` nor `models.blocked` is set). See [model-routing reference](https://github.github.com/gh-aw/reference/model-routing/). - **Advanced engine sub-fields** (see the `engine_config` definition in `pkg/parser/schemas/main_workflow_schema.json`): `model-provider` (`github` | `anthropic` | `openai`), `harness` (`max-retries`/`initial-delay-ms`/`backoff-multiplier`/`max-delay-ms` retry policy, plus `watchdog-timeout` — a post-result idle-process watchdog, in seconds, for the built-in Copilot/Codex harnesses), engine-level `mcp` (`session-timeout`/`tool-timeout`), `extensions`, and `cwd`. See [Harness Settings and Runtime Tuning Variables](https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/environment-variables.md#harness-settings-and-runtime-tuning-variables) for defaults, units, and `GH_AW_HARNESS_*` env var equivalents. diff --git a/.github/aw/syntax.md b/.github/aw/syntax.md index b6065a589e6..3b3b8a81582 100644 --- a/.github/aw/syntax.md +++ b/.github/aw/syntax.md @@ -12,6 +12,7 @@ Use the smallest relevant reference instead of loading one large schema file. | Agentic workflow specific fields (`strict`, `bots`, `labels`, metadata) | [syntax-agentic.md](syntax-agentic.md) | | `engine:` field detail (per-engine support, inline drivers, auth) | [syntax-engine.md](syntax-engine.md) | | Cache configuration, tools, imports, and permission patterns | [syntax-tools-imports.md](syntax-tools-imports.md) | +| `checkout:` field detail (single/array/disabled checkout, multi-repository allowlist) | [syntax-checkout.md](syntax-checkout.md) | | `skills` field | [skills.md](skills.md) | | `plugins` field (experimental Agent Plugins) | [syntax-tools-imports.md](syntax-tools-imports.md#agent-plugins-plugins) | | `lsp` field | [lsp.md](lsp.md) | diff --git a/.github/skills/agentic-workflows/SKILL.md b/.github/skills/agentic-workflows/SKILL.md index 4f2e5077650..d6322dd9d34 100644 --- a/.github/skills/agentic-workflows/SKILL.md +++ b/.github/skills/agentic-workflows/SKILL.md @@ -77,6 +77,7 @@ Load these files from `github/gh-aw` (they are not available locally). - `.github/aw/skills.md` - `.github/aw/subagents.md` - `.github/aw/syntax-agentic.md` +- `.github/aw/syntax-checkout.md` - `.github/aw/syntax-core.md` - `.github/aw/syntax-engine.md` - `.github/aw/syntax-tools-imports.md` diff --git a/pkg/cli/data/agentic_workflows_fallback_aw_files.json b/pkg/cli/data/agentic_workflows_fallback_aw_files.json index ee490816ff5..bb2d48643a0 100644 --- a/pkg/cli/data/agentic_workflows_fallback_aw_files.json +++ b/pkg/cli/data/agentic_workflows_fallback_aw_files.json @@ -61,6 +61,7 @@ "skills.md", "subagents.md", "syntax-agentic.md", + "syntax-checkout.md", "syntax-core.md", "syntax-engine.md", "syntax-tools-imports.md",