diff --git a/docs/src/content/docs/reference/cross-repository.md b/docs/src/content/docs/reference/cross-repository.md index 14d72ac3419..4636ff0f4e5 100644 --- a/docs/src/content/docs/reference/cross-repository.md +++ b/docs/src/content/docs/reference/cross-repository.md @@ -25,8 +25,8 @@ If only a the current repository, you can use `checkout:` to override default ch ```yaml wrap checkout: - fetch-depth: 0 # Full git history - github-token: ${{ secrets.MY_TOKEN }} # Custom authentication + fetch-depth: 0 # Full git history + token: ${{ secrets.MY_TOKEN }} # Custom authentication ``` You can also use `checkout:` to check out additional repositories alongside the main repository: @@ -37,7 +37,7 @@ checkout: - repository: owner/other-repo path: ./libs/other ref: main - github-token: ${{ secrets.CROSS_REPO_PAT }} + token: ${{ secrets.CROSS_REPO_PAT }} ``` ### Checkout Configuration Options @@ -47,7 +47,7 @@ checkout: | `repository` | string | Repository in `owner/repo` format. Defaults to the current repository. | | `ref` | string | Branch, tag, or SHA to checkout. Defaults to the triggering ref. | | `path` | string | Path within `GITHUB_WORKSPACE` to place the checkout. Defaults to workspace root. | -| `github-token` | string | Token for authentication. Use `${{ secrets.MY_TOKEN }}` syntax. | +| `token` | string | Token for authentication. Use `${{ secrets.MY_TOKEN }}` syntax. | | `fetch-depth` | integer | Commits to fetch. `0` = full history, `1` = shallow clone (default). | | `sparse-checkout` | string | Newline-separated patterns for sparse checkout (e.g., `.github/\nsrc/`). | | `submodules` | string/bool | Submodule handling: `"recursive"`, `"true"`, or `"false"`. | @@ -74,7 +74,7 @@ When a workflow running from a central repository targets a different repository checkout: - repository: org/target-repo path: ./target - github-token: ${{ secrets.CROSS_REPO_PAT }} + token: ${{ secrets.CROSS_REPO_PAT }} current: true # agent's primary target ``` @@ -150,7 +150,7 @@ checkout: - repository: org/shared-libs path: ./libs/shared ref: main - github-token: ${{ secrets.LIBS_PAT }} + token: ${{ secrets.LIBS_PAT }} - repository: org/config-repo path: ./config sparse-checkout: | diff --git a/docs/src/content/docs/reference/frontmatter.md b/docs/src/content/docs/reference/frontmatter.md index d61d0ee3481..4aba86ac013 100644 --- a/docs/src/content/docs/reference/frontmatter.md +++ b/docs/src/content/docs/reference/frontmatter.md @@ -575,7 +575,7 @@ Configure how `actions/checkout` is invoked in the agent job. Override default c # Single repository with custom settings checkout: fetch-depth: 0 - github-token: ${{ secrets.MY_TOKEN }} + token: ${{ secrets.MY_TOKEN }} ``` ```yaml wrap diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index b18826631fd..defbabecfd2 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -7894,7 +7894,7 @@ "type": "boolean", "description": "Whether to download Git LFS objects. Defaults to false." }, - "github-token": { + "token": { "type": "string", "description": "GitHub token for authentication. Use ${{ secrets.MY_TOKEN }} to reference a secret. Credentials are always removed after checkout (persist-credentials: false is enforced).", "examples": ["${{ secrets.MY_PAT }}", "${{ secrets.GITHUB_TOKEN }}"] diff --git a/pkg/workflow/checkout_manager.go b/pkg/workflow/checkout_manager.go index fb5ed9fe85d..a0e086247cf 100644 --- a/pkg/workflow/checkout_manager.go +++ b/pkg/workflow/checkout_manager.go @@ -17,7 +17,7 @@ var checkoutManagerLog = logger.New("workflow:checkout_manager") // // checkout: // fetch-depth: 0 -// github-token: ${{ secrets.MY_TOKEN }} +// token: ${{ secrets.MY_TOKEN }} // // Or multiple checkouts: // @@ -36,13 +36,10 @@ type CheckoutConfig struct { // Path within GITHUB_WORKSPACE to place the checkout. Defaults to the workspace root. Path string `json:"path,omitempty"` - // GitHubToken overrides the default GITHUB_TOKEN for authentication. + // Token overrides the default GITHUB_TOKEN for authentication. // Use ${{ secrets.MY_TOKEN }} to reference a repository secret. - // - // Frontmatter key: "github-token" (user-facing name used here and in the schema) - // Generated YAML key: "token" (the actual input name for actions/checkout) - // The compiler maps frontmatter "github-token" → lock.yml "token" during step generation. - GitHubToken string `json:"github-token,omitempty"` + // Matches the "token" input of actions/checkout. + Token string `json:"token,omitempty"` // FetchDepth controls the number of commits to fetch. // 0 fetches all history (full clone). 1 is a shallow clone (default). @@ -138,8 +135,8 @@ func (cm *CheckoutManager) add(cfg *CheckoutConfig) { if cfg.Ref != "" && entry.ref == "" { entry.ref = cfg.Ref // first-seen ref wins } - if cfg.GitHubToken != "" && entry.token == "" { - entry.token = cfg.GitHubToken // first-seen token wins + if cfg.Token != "" && entry.token == "" { + entry.token = cfg.Token // first-seen token wins } if cfg.SparseCheckout != "" { entry.sparsePatterns = mergeSparsePatterns(entry.sparsePatterns, cfg.SparseCheckout) @@ -158,7 +155,7 @@ func (cm *CheckoutManager) add(cfg *CheckoutConfig) { entry := &resolvedCheckout{ key: key, ref: cfg.Ref, - token: cfg.GitHubToken, + token: cfg.Token, fetchDepth: cfg.FetchDepth, submodules: cfg.Submodules, lfs: cfg.LFS, @@ -257,7 +254,6 @@ func (cm *CheckoutManager) GenerateDefaultCheckoutStep( fmt.Fprintf(&sb, " ref: %s\n", override.ref) } if override.token != "" { - // actions/checkout input is "token", not "github-token" fmt.Fprintf(&sb, " token: %s\n", override.token) } if override.fetchDepth != nil { @@ -301,7 +297,6 @@ func generateCheckoutStepLines(entry *resolvedCheckout, getActionPin func(string fmt.Fprintf(&sb, " path: %s\n", entry.key.path) } if entry.token != "" { - // actions/checkout input is "token", not "github-token" fmt.Fprintf(&sb, " token: %s\n", entry.token) } if entry.fetchDepth != nil { @@ -480,12 +475,12 @@ func checkoutConfigFromMap(m map[string]any) (*CheckoutConfig, error) { cfg.Path = s } - if v, ok := m["github-token"]; ok { + if v, ok := m["token"]; ok { s, ok := v.(string) if !ok { - return nil, errors.New("checkout.github-token must be a string") + return nil, errors.New("checkout.token must be a string") } - cfg.GitHubToken = s + cfg.Token = s } if v, ok := m["fetch-depth"]; ok { diff --git a/pkg/workflow/checkout_manager_test.go b/pkg/workflow/checkout_manager_test.go index 0ece10301e6..9bdedec402b 100644 --- a/pkg/workflow/checkout_manager_test.go +++ b/pkg/workflow/checkout_manager_test.go @@ -32,7 +32,7 @@ func TestNewCheckoutManager(t *testing.T) { t.Run("custom token on default checkout", func(t *testing.T) { cm := NewCheckoutManager([]*CheckoutConfig{ - {GitHubToken: "${{ secrets.MY_TOKEN }}"}, + {Token: "${{ secrets.MY_TOKEN }}"}, }) override := cm.GetDefaultCheckoutOverride() require.NotNil(t, override, "should have default override") @@ -132,7 +132,7 @@ func TestGenerateDefaultCheckoutStep(t *testing.T) { t.Run("user token is included in default checkout", func(t *testing.T) { cm := NewCheckoutManager([]*CheckoutConfig{ - {GitHubToken: "${{ secrets.MY_TOKEN }}"}, + {Token: "${{ secrets.MY_TOKEN }}"}, }) lines := cm.GenerateDefaultCheckoutStep(false, "", getPin) combined := strings.Join(lines, "") @@ -161,7 +161,7 @@ func TestGenerateDefaultCheckoutStep(t *testing.T) { t.Run("trial mode overrides user config", func(t *testing.T) { cm := NewCheckoutManager([]*CheckoutConfig{ - {GitHubToken: "${{ secrets.MY_TOKEN }}"}, + {Token: "${{ secrets.MY_TOKEN }}"}, }) lines := cm.GenerateDefaultCheckoutStep(true, "owner/trial-repo", getPin) combined := strings.Join(lines, "") @@ -224,6 +224,16 @@ func TestGenerateAdditionalCheckoutSteps(t *testing.T) { combined := strings.Join(lines, "") assert.Contains(t, combined, "submodules: recursive", "should include submodules option") }) + + t.Run("additional checkout emits token not github-token", func(t *testing.T) { + cm := NewCheckoutManager([]*CheckoutConfig{ + {Path: "./libs", Repository: "owner/libs", Token: "${{ secrets.MY_TOKEN }}"}, + }) + lines := cm.GenerateAdditionalCheckoutSteps(getPin) + combined := strings.Join(lines, "") + assert.Contains(t, combined, "token: ${{ secrets.MY_TOKEN }}", "actions/checkout input must be 'token'") + assert.NotContains(t, combined, "github-token:", "must not emit 'github-token' as actions/checkout input") + }) } // TestParseCheckoutConfigs verifies parsing of raw frontmatter values. @@ -236,13 +246,13 @@ func TestParseCheckoutConfigs(t *testing.T) { t.Run("single object", func(t *testing.T) { raw := map[string]any{ - "fetch-depth": float64(0), - "github-token": "${{ secrets.MY_TOKEN }}", + "fetch-depth": float64(0), + "token": "${{ secrets.MY_TOKEN }}", } configs, err := ParseCheckoutConfigs(raw) require.NoError(t, err, "single object should parse without error") require.Len(t, configs, 1, "should produce one config") - assert.Equal(t, "${{ secrets.MY_TOKEN }}", configs[0].GitHubToken, "token should be set") + assert.Equal(t, "${{ secrets.MY_TOKEN }}", configs[0].Token, "token should be set") require.NotNil(t, configs[0].FetchDepth, "fetch-depth should be set") assert.Equal(t, 0, *configs[0].FetchDepth, "fetch-depth should be 0") }) diff --git a/pkg/workflow/trial_mode_test.go b/pkg/workflow/trial_mode_test.go index 402a77fa466..1aaa232ec98 100644 --- a/pkg/workflow/trial_mode_test.go +++ b/pkg/workflow/trial_mode_test.go @@ -74,8 +74,8 @@ This is a test workflow for trial mode compilation. t.Error("Expected safe_outputs job in normal mode") } - // Checkout should not include github-token in normal mode - // Check specifically that the checkout step doesn't have a token parameter + // Checkout should not include an implicit/default token in normal mode when the workflow doesn't configure one + // Check specifically that the generated checkout step doesn't include a token parameter unless explicitly configured in the workflow lines := strings.Split(lockContent, "\n") for i, line := range lines { if strings.Contains(line, "actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd") { @@ -85,7 +85,7 @@ This is a test workflow for trial mode compilation. // Found "with:" section, check for token for k := j + 1; k < len(lines) && k < j+5; k++ { if strings.Contains(lines[k], "token:") { - t.Error("Did not expect github-token in checkout step in normal mode") + t.Error("Did not expect token in checkout step in normal mode") break } // If we hit another step or section, stop checking @@ -133,7 +133,7 @@ This is a test workflow for trial mode compilation. t.Error("Expected safe_outputs job in trial mode") } - // Checkout in agent job should include github-token in trial mode + // Checkout in agent job should include token in trial mode // Extract the agent job section first agentJobStart := strings.Index(lockContent, "agent:") if agentJobStart == -1 { @@ -205,7 +205,7 @@ This is a test workflow for trial mode compilation. } } if !foundCheckoutToken { - t.Error("Expected github-token in checkout step in trial mode") + t.Error("Expected token in checkout step in trial mode") } // Should still include the main workflow job @@ -318,10 +318,10 @@ This is a test workflow for trial mode compilation. t.Error("Expected jobs section to be present in trial mode") } - // In trial mode, checkout should always include github-token + // In trial mode, checkout should always include token (as "token:" input for actions/checkout) if strings.Contains(lockContent, "uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd") { if !strings.Contains(lockContent, "token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}") { - t.Error("Expected github-token in checkout step in trial mode") + t.Error("Expected token in checkout step in trial mode") } } })