-
Notifications
You must be signed in to change notification settings - Fork 454
Add formal checkout behavior specification for agent and safe_outputs jobs #44225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+326
−0
Merged
Changes from 6 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
4c3a990
Plan checkout behavior specification
Copilot 8e60d71
Add checkout behavior specification
Copilot 63ab086
Refine checkout spec validation language
Copilot fee4a9f
Merge remote-tracking branch 'origin/main' into copilot/specify-check…
Copilot 1a913a0
Merge main and recompile workflow lock files
Copilot a90e088
Plan: revert lock.yml changes
Copilot f4562a1
Specify checkout-level safe-output auth and manifest generation rules
Copilot 045bf15
docs: remove safe-output-github-token; only safe-output-github-app su…
Copilot dbe996f
Merge branch 'main' into copilot/specify-checkout-behavior
github-actions[bot] c0968e3
docs: add app alias note, fix cleanCreds → force-clean-git-credential…
Copilot 11bd0ed
Merge remote-tracking branch 'origin/main' into copilot/specify-check…
Copilot f909134
docs: fix §4.3 - safe-outputs auth must not be used for checkout (iss…
Copilot 2155164
docs: shorten safe-output-github-app table description, link to section
Copilot 795ae59
Merge remote-tracking branch 'origin/main' into copilot/specify-check…
Copilot ac24527
Merge remote-tracking branch 'origin/main' into copilot/specify-check…
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
279 changes: 279 additions & 0 deletions
279
docs/src/content/docs/specs/checkout-behavior-specification.md
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,279 @@ | ||
| --- | ||
| title: Checkout Behavior Specification | ||
| description: Formal specification of checkout behavior across activation, agent, and safe_outputs jobs in gh-aw workflows | ||
| sidebar: | ||
| order: 1365 | ||
| --- | ||
|
|
||
| # Checkout Behavior Specification | ||
|
|
||
| **Version**: 1.0.0 | ||
| **Status**: Working Draft | ||
| **Publication Date**: 2026-07-08 | ||
| **Editor**: GitHub Agentic Workflows Team | ||
| **This Version**: [checkout-behavior-specification](/gh-aw/specs/checkout-behavior-specification/) | ||
| **Latest Published Version**: This document | ||
|
|
||
| --- | ||
|
|
||
| ## Abstract | ||
|
|
||
| This specification defines normative checkout behavior in GitHub Agentic Workflows (`gh-aw`) for activation, agent, and `safe_outputs` jobs. It specifies credential and token precedence, `github-token` and `github-app` resolution, trial mode behavior, side-repo targeting, sparse/shallow/fetch semantics, symlink handling during sparse activation checkout, submodule cleanup semantics, and checkout-manifest behavior used by safe output handlers. | ||
|
|
||
| ## Status of This Document | ||
|
|
||
| This is a working draft and may change. It describes behavior mined from the current implementation in `pkg/workflow/` and `actions/setup/js/`. | ||
|
|
||
| ## Table of Contents | ||
|
|
||
| 1. [Introduction](#1-introduction) | ||
| 2. [Conformance](#2-conformance) | ||
| 3. [Checkout Model](#3-checkout-model) | ||
| 4. [Authentication and Token Resolution](#4-authentication-and-token-resolution) | ||
| 5. [Sparse, Shallow, Fetch, Symlink, and Submodule Behavior](#5-sparse-shallow-fetch-symlink-and-submodule-behavior) | ||
| 6. [Trial Mode and Side-Repo Behavior](#6-trial-mode-and-side-repo-behavior) | ||
| 7. [Compliance Testing](#7-compliance-testing) | ||
| 8. [References](#8-references) | ||
| 9. [Change Log](#9-change-log) | ||
|
|
||
| --- | ||
|
|
||
| ## 1. Introduction | ||
|
|
||
| ### 1.1 Purpose | ||
|
|
||
| This document defines exactly how checkout is compiled and executed for: | ||
|
|
||
| - Activation job sparse checkouts | ||
| - Agent job checkouts | ||
| - `safe_outputs` job PR/push checkouts | ||
|
|
||
| ### 1.2 Scope | ||
|
|
||
| This specification covers: | ||
|
|
||
| - `checkout:` parsing and merge behavior | ||
| - `actions/checkout` step generation | ||
| - Checkout credential persistence/cleanup behavior | ||
| - Token and GitHub App precedence across checkout and `safe_outputs` | ||
| - Sparse/shallow/fetch mechanics | ||
| - Symlink handling for activation sparse checkout | ||
| - Submodule credential cleanup behavior | ||
| - Trial mode and side-repo derivation behavior | ||
|
|
||
| --- | ||
|
|
||
| ## 2. Conformance | ||
|
|
||
| ### 2.1 Requirements Notation | ||
|
|
||
| The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). | ||
|
|
||
| ### 2.2 Conformance Classes | ||
|
|
||
| - **C1 (Compiler conformance)**: emits checkout YAML conforming to Sections 3–6. | ||
| - **C2 (Runtime conformance)**: JS/sh handlers honor manifest safety, fetch behavior, and credential boundaries in Sections 4–6. | ||
|
|
||
| --- | ||
|
|
||
| ## 3. Checkout Model | ||
|
|
||
| ### 3.1 Checkout Entry Parsing | ||
|
|
||
| `checkout:` MUST accept either a single object or an array of objects. | ||
| Each entry MAY define: `repository`, `ref`, `path`, `github-token` (or legacy `token`), `github-app`, `fetch-depth`, `fetch`, `sparse-checkout`, `submodules`, `lfs`, `current`, `wiki`, and `force-clean-git-credentials`. | ||
|
|
||
| `github-token` and `github-app` MUST be mutually exclusive per entry. | ||
|
|
||
| ### 3.2 Entry Merge Rules | ||
|
|
||
| Entries with the same `(repository, path, wiki)` key MUST merge with these rules: | ||
|
|
||
| - `fetch-depth`: deepest wins (`0` wins over all) | ||
| - `ref`: first non-empty wins | ||
| - auth (`github-token` vs `github-app`): first auth wins | ||
| - sparse patterns: union | ||
| - fetch refs: union | ||
| - `lfs`: OR | ||
| - `submodules`: first non-empty wins | ||
| - `cleanCreds`: OR | ||
|
Copilot marked this conversation as resolved.
Outdated
|
||
|
|
||
| ### 3.3 Job-specific Checkout Generation | ||
|
|
||
| - **Activation job** MUST use sparse checkout for `.github` and `.agents`, with `persist-credentials: false`. | ||
| - **Agent job** MUST generate default checkout plus additional checkouts from `CheckoutManager`, with `persist-credentials: false` by default. | ||
| - **safe_outputs job** MUST reuse the same checkout generators but set keep-credentials mode for push/fetch use and inject a `Configure Git credentials` step. | ||
|
|
||
| ### 3.4 Checkout Manifest | ||
|
|
||
| For non-default cross-repo checkouts, the compiler MUST emit a checkout manifest step. | ||
| Runtime lookup (`find_repo_checkout`) MUST prefer manifest paths and MUST reject manifest paths that are absolute or escape workspace roots. | ||
|
|
||
| --- | ||
|
|
||
| ## 4. Authentication and Token Resolution | ||
|
|
||
| ### 4.1 Checkout Entry Auth | ||
|
|
||
| For each checkout step, token resolution MUST be: | ||
|
|
||
| 1. Entry `github-app` minted token (with fallback behavior if `ignore-if-missing: true`) | ||
| 2. Entry `github-token` | ||
| 3. Default token fallback when required by context | ||
|
|
||
| Top-level `github-app` fallback MUST be applied to checkout entries only when that entry has neither `github-app` nor `github-token`. | ||
|
|
||
| ### 4.2 Activation Job Token | ||
|
|
||
| Activation token precedence MUST be: | ||
|
|
||
| 1. `on.github-app` minted token; when `ignore-if-missing: true`, this resolves to `steps.activation-app-token.outputs.token || secrets.GITHUB_TOKEN` | ||
| 2. `on.github-token` | ||
| 3. `secrets.GITHUB_TOKEN` | ||
|
|
||
| ### 4.3 safe_outputs PR Checkout Token | ||
|
|
||
| `resolvePRCheckoutToken` precedence MUST be: | ||
|
|
||
| 1. `safe-outputs.create-pull-request.github-token` | ||
| 2. `safe-outputs.push-to-pull-request-branch.github-token` | ||
| 3. `safe-outputs.github-app` minted token (with fallback chain when `ignore-if-missing: true`) | ||
| 4. `safe-outputs.github-token` | ||
| 5. `${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}` | ||
|
|
||
| When safe_outputs checkout retention is enabled, checkouts without explicit entry tokens MUST persist the resolved PR checkout token so local git credentials match push/fetch token usage. | ||
|
|
||
| ### 4.4 Credential Lifecycle Boundary | ||
|
|
||
| - Agent job checkouts MUST remove persisted credentials by default (`persist-credentials: false`). | ||
| - safe_outputs PR checkout path MUST retain credentials (`persist-credentials: true`) and run explicit git remote credential configuration for root and sub-repo checkouts. | ||
| - Agent guidance MUST state that authenticated `git fetch/pull/push` is unavailable after checkout unless refs were already fetched. | ||
|
|
||
| ### 4.5 Credential-less Safe-outputs MCP Context | ||
|
|
||
| `generate_git_patch` and `generate_git_bundle` in the safe-outputs MCP server context MUST fail softly when required refs are unavailable and private-repo fetch cannot authenticate, with actionable error text directing users to add refs via `checkout.fetch`. | ||
|
|
||
| --- | ||
|
|
||
| ## 5. Sparse, Shallow, Fetch, Symlink, and Submodule Behavior | ||
|
|
||
| ### 5.1 Shallow and Additional Fetch | ||
|
|
||
| - Default shallow behavior MUST be `fetch-depth: 1` when unset. | ||
| - Additional `fetch:` refs MUST emit a follow-up `git fetch` step per checkout entry. | ||
| - Follow-up fetch MUST mirror effective depth (omit `--depth` only when effective depth is `0`). | ||
| - Follow-up fetch MUST inject credentials via command-level `http.extraheader` and MUST NOT persist credentials to git config. | ||
|
|
||
| ### 5.2 Sparse Checkout and Partial-clone Repair | ||
|
|
||
| When sparse checkout is configured, compiler-generated checkout steps MUST emit: | ||
|
|
||
| - `filter: 'blob:limit=1073741824'` | ||
| - a post-checkout step clearing: | ||
| - `remote.origin.promisor` | ||
| - `remote.origin.partialclonefilter` | ||
|
|
||
| This avoids blobless partial-clone behavior that would require later authenticated lazy fetches in agent contexts. | ||
|
|
||
| ### 5.3 Activation Symlink Handling | ||
|
|
||
| Activation sparse checkout path expansion MUST detect symlinks for known `.github` subpaths and include resolved in-repo targets. | ||
| Resolved targets escaping repository root MUST be rejected. | ||
|
|
||
| ### 5.4 Submodules and Credential Cleanup | ||
|
|
||
| `submodules` MUST accept string or boolean and compile to string form accepted by `actions/checkout`. | ||
| When `force-clean-git-credentials: true` is set (and keep-credentials-for-push is not enabled), checkout MUST keep credentials long enough for checkout internals and then run cleanup that removes credential sections/headers from: | ||
|
|
||
| - `.git/config` | ||
| - `.git/modules/**/config` | ||
|
|
||
| --- | ||
|
|
||
| ## 6. Trial Mode and Side-Repo Behavior | ||
|
|
||
| ### 6.1 Trial Mode Checkout | ||
|
|
||
| In trial mode, default checkout generation MUST: | ||
|
|
||
| - Override repository to `trialLogicalRepoSlug` when provided | ||
| - Emit token via default GitHub token chain (`getEffectiveGitHubToken("")`) | ||
| - Keep additional fetch-step behavior aligned with non-trial mode | ||
|
|
||
| For safe-output environment variables, trial mode SHOULD set `GH_AW_TARGET_REPO_SLUG` to the logical trial repo when no explicit target repo is configured. | ||
|
|
||
| ### 6.2 Side-Repo Target Derivation | ||
|
|
||
| Side-repo maintenance target detection MUST use checkout entries marked `current: true` with static repository slugs. | ||
| Expression-based repositories MUST be excluded. | ||
| Auth selection for repeated targets MUST preserve first-seen auth, except that empty auth MAY be upgraded by a later non-empty auth. | ||
|
|
||
| Effective side-repo token precedence MUST be: | ||
|
|
||
| 1. side-repo target checkout `github-token` | ||
| 2. side-repo target checkout `github-app` minted token reference | ||
| 3. `${{ secrets.GH_AW_GITHUB_TOKEN }}` | ||
|
|
||
| --- | ||
|
|
||
| ## 7. Compliance Testing | ||
|
|
||
| ### 7.1 Required Tests | ||
|
|
||
| - **T-CHK-001**: `checkout.github-token` and `checkout.github-app` mutual exclusivity validation | ||
| - **T-CHK-002**: Merge behavior by `(repository,path,wiki)` key | ||
| - **T-CHK-003**: Agent job emits `persist-credentials: false` by default | ||
| - **T-CHK-004**: safe_outputs PR checkout path retains credentials and configures git remotes | ||
| - **T-CHK-005**: Sparse checkout emits blob-limit filter and partial-clone reset step | ||
| - **T-CHK-006**: Additional `fetch:` emits depth-mirrored fetch with `http.extraheader` | ||
| - **T-CHK-007**: Manifest path resolution rejects absolute/out-of-workspace paths | ||
| - **T-CHK-008**: Trial mode repository/token override behavior | ||
| - **T-CHK-009**: Side-repo target extraction and auth precedence | ||
| - **T-CHK-010**: `force-clean-git-credentials` cleanup covers `.git/modules/**/config` | ||
|
|
||
| ### 7.2 Compliance Checklist | ||
|
|
||
| | Requirement | Test ID | Level | Status | | ||
| |---|---|---|---| | ||
| | Checkout parse + merge semantics | T-CHK-001, T-CHK-002 | C1 | Required | | ||
| | Agent vs safe_outputs credential lifecycle | T-CHK-003, T-CHK-004 | C1/C2 | Required | | ||
| | Sparse/shallow/fetch semantics | T-CHK-005, T-CHK-006 | C1 | Required | | ||
| | Manifest path safety | T-CHK-007 | C2 | Required | | ||
| | Trial and side-repo behavior | T-CHK-008, T-CHK-009 | C1 | Required | | ||
| | Submodule cleanup behavior | T-CHK-010 | C1/C2 | Required | | ||
|
|
||
| --- | ||
|
|
||
| ## 8. References | ||
|
|
||
| ### Normative References | ||
|
|
||
| - [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) | ||
| - `pkg/workflow/checkout_manager.go` | ||
| - `pkg/workflow/checkout_config_parser.go` | ||
| - `pkg/workflow/checkout_step_generator.go` | ||
| - `pkg/workflow/compiler_yaml_main_job.go` | ||
| - `pkg/workflow/compiler_safe_outputs_steps.go` | ||
| - `pkg/workflow/safe_outputs_app_config.go` | ||
| - `pkg/workflow/github_token.go` | ||
| - `actions/setup/js/generate_git_patch.cjs` | ||
| - `actions/setup/js/generate_git_bundle.cjs` | ||
| - `actions/setup/js/find_repo_checkout.cjs` | ||
| - `actions/setup/sh/configure_git_credentials.sh` | ||
| - `actions/setup/sh/clean_git_credentials.sh` | ||
|
|
||
| ### Informative References | ||
|
|
||
| - `/gh-aw/reference/checkout/` | ||
| - `/gh-aw/reference/safe-outputs-pull-requests/` | ||
| - `/gh-aw/docs/sparseness.md` | ||
|
|
||
| --- | ||
|
|
||
| ## 9. Change Log | ||
|
|
||
| ### Version 1.0.0 (Working Draft) | ||
|
|
||
| - Initial specification for checkout behavior in activation, agent, and safe_outputs jobs | ||
| - Added normative credential precedence and lifecycle requirements | ||
| - Added sparse/shallow/fetch, symlink, submodule, trial mode, and side-repo requirements | ||
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot also handle checkout manifest generation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in
f4562a1: added normative checkout-manifest generation requirements, including safe-outputs auth metadata handling and no persisted resolved tokens.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Section 3.4 (Checkout Manifest) was added in
f4562a1and is in the current spec — see lines 111–118 ofcheckout-behavior-specification.md. It covers the compiler requirement to emit a manifest step, manifest-path safety (absolute/out-of-workspace rejection), and the requirement to include safe_outputs auth metadata without persisting resolved token values.