Skip to content

Commit 5ac0552

Browse files
authored
🌍 Add github-token support for safe outputs (#826)
* safe outputs env settings * safe outputs env settings * safe outputs github-token setting
1 parent cdb1d0f commit 5ac0552

11 files changed

Lines changed: 912 additions & 2 deletions

docs/src/content/docs/reference/safe-outputs.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,8 +551,29 @@ safe-outputs:
551551
- github.com # Default GitHub domains are always included
552552
- api.github.com # Additional trusted domains can be specified
553553
- trusted-domain.com # URIs from unlisted domains are replaced with "(redacted)"
554+
github-token: ${{ secrets.CUSTOM_PAT }} # Optional: custom GitHub token for safe output jobs
554555
```
555556

557+
## Global Configuration Options
558+
559+
### Custom GitHub Token (`github-token:`)
560+
561+
By default, safe output jobs use the standard `GITHUB_TOKEN` provided by GitHub Actions. You can specify a custom GitHub token for all safe output jobs:
562+
563+
```yaml
564+
safe-outputs:
565+
create-issue:
566+
add-issue-comment:
567+
github-token: ${{ secrets.CUSTOM_PAT }} # Use custom PAT instead of GITHUB_TOKEN
568+
```
569+
570+
This is useful when:
571+
- You need additional permissions beyond what `GITHUB_TOKEN` provides
572+
- You want to perform actions across multiple repositories
573+
- You need to bypass GitHub Actions token restrictions
574+
575+
**Note:** The custom `github-token` is applied to all safe output jobs (create-issue, add-issue-comment, create-pull-request, etc.). Individual safe output types cannot have different tokens.
576+
556577
## Related Documentation
557578

558579
- [Frontmatter Options](frontmatter.md) - All configuration options for workflows

pkg/cli/templates/instructions.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,17 @@ The YAML frontmatter supports these fields:
212212
body: true # Optional: allow updating issue body
213213
max: 3 # Optional: maximum number of issues to update (default: 1)
214214
```
215-
When using `safe-outputs.update-issue`, the main job does **not** need `issues: write` permission since issue updates are handled by a separate job with appropriate permissions.
215+
When using `safe-outputs.update-issue`, the main job does **not** need `issues: write` permission since issue updates are handled by a separate job with appropriate permissions.
216+
217+
**Global Safe Output Configuration:**
218+
- `github-token:` - Custom GitHub token for all safe output jobs
219+
```yaml
220+
safe-outputs:
221+
create-issue:
222+
add-issue-comment:
223+
github-token: ${{ secrets.CUSTOM_PAT }} # Use custom PAT instead of GITHUB_TOKEN
224+
```
225+
Useful when you need additional permissions or want to perform actions across repositories.
216226

217227
- **`alias:`** - Alternative workflow name (string)
218228
- **`cache:`** - Cache configuration for workflow dependencies (object or array)

pkg/parser/schemas/main_workflow_schema.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,6 +1600,21 @@
16001600
"staged": {
16011601
"type": "boolean",
16021602
"description": "If true, emit step summary messages instead of making GitHub API calls (preview mode)"
1603+
},
1604+
"env": {
1605+
"type": "object",
1606+
"description": "Environment variables to pass to safe output jobs",
1607+
"patternProperties": {
1608+
"^[A-Za-z_][A-Za-z0-9_]*$": {
1609+
"type": "string",
1610+
"description": "Environment variable value, typically a secret reference like ${{ secrets.TOKEN_NAME }}"
1611+
}
1612+
},
1613+
"additionalProperties": false
1614+
},
1615+
"github-token": {
1616+
"type": "string",
1617+
"description": "GitHub token to use for safe output jobs. Typically a secret reference like ${{ secrets.GITHUB_TOKEN }} or ${{ secrets.CUSTOM_PAT }}"
16031618
}
16041619
},
16051620
"additionalProperties": false

pkg/workflow/compiler.go

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,9 @@ type SafeOutputsConfig struct {
173173
PushToPullRequestBranch *PushToPullRequestBranchConfig `yaml:"push-to-pr-branch,omitempty"`
174174
MissingTool *MissingToolConfig `yaml:"missing-tool,omitempty"` // Optional for reporting missing functionality
175175
AllowedDomains []string `yaml:"allowed-domains,omitempty"`
176-
Staged *bool `yaml:"staged,omitempty"` // If true, emit step summary messages instead of making GitHub API calls
176+
Staged *bool `yaml:"staged,omitempty"` // If true, emit step summary messages instead of making GitHub API calls
177+
Env map[string]string `yaml:"env,omitempty"` // Environment variables to pass to safe output jobs
178+
GitHubToken string `yaml:"github-token,omitempty"` // GitHub token for safe output jobs
177179
}
178180

179181
// CreateIssuesConfig holds configuration for creating GitHub issues from agent output
@@ -2204,7 +2206,12 @@ func (c *Compiler) buildCreateOutputIssueJob(data *WorkflowData, mainJobName str
22042206
steps = append(steps, " GITHUB_AW_SAFE_OUTPUTS_STAGED: \"true\"\n")
22052207
}
22062208

2209+
// Add custom environment variables from safe-outputs.env
2210+
c.addCustomSafeOutputEnvVars(&steps, data)
2211+
22072212
steps = append(steps, " with:\n")
2213+
// Add github-token if specified
2214+
c.addSafeOutputGitHubToken(&steps, data)
22082215
steps = append(steps, " script: |\n")
22092216

22102217
// Add each line of the script with proper indentation
@@ -2281,7 +2288,12 @@ func (c *Compiler) buildCreateOutputDiscussionJob(data *WorkflowData, mainJobNam
22812288
steps = append(steps, " GITHUB_AW_SAFE_OUTPUTS_STAGED: \"true\"\n")
22822289
}
22832290

2291+
// Add custom environment variables from safe-outputs.env
2292+
c.addCustomSafeOutputEnvVars(&steps, data)
2293+
22842294
steps = append(steps, " with:\n")
2295+
// Add github-token if specified
2296+
c.addSafeOutputGitHubToken(&steps, data)
22852297
steps = append(steps, " script: |\n")
22862298

22872299
// Add each line of the script with proper indentation
@@ -2338,7 +2350,12 @@ func (c *Compiler) buildCreateOutputAddIssueCommentJob(data *WorkflowData, mainJ
23382350
steps = append(steps, fmt.Sprintf(" GITHUB_AW_COMMENT_TARGET: %q\n", data.SafeOutputs.AddIssueComments.Target))
23392351
}
23402352

2353+
// Add custom environment variables from safe-outputs.env
2354+
c.addCustomSafeOutputEnvVars(&steps, data)
2355+
23412356
steps = append(steps, " with:\n")
2357+
// Add github-token if specified
2358+
c.addSafeOutputGitHubToken(&steps, data)
23422359
steps = append(steps, " script: |\n")
23432360

23442361
// Add each line of the script with proper indentation
@@ -2415,7 +2432,12 @@ func (c *Compiler) buildCreateOutputPullRequestReviewCommentJob(data *WorkflowDa
24152432
steps = append(steps, fmt.Sprintf(" GITHUB_AW_PR_REVIEW_COMMENT_SIDE: %q\n", data.SafeOutputs.CreatePullRequestReviewComments.Side))
24162433
}
24172434

2435+
// Add custom environment variables from safe-outputs.env
2436+
c.addCustomSafeOutputEnvVars(&steps, data)
2437+
24182438
steps = append(steps, " with:\n")
2439+
// Add github-token if specified
2440+
c.addSafeOutputGitHubToken(&steps, data)
24192441
steps = append(steps, " script: |\n")
24202442

24212443
// Add each line of the script with proper indentation
@@ -2491,7 +2513,12 @@ func (c *Compiler) buildCreateOutputCodeScanningAlertJob(data *WorkflowData, mai
24912513
// Pass the workflow filename for rule ID prefix
24922514
steps = append(steps, fmt.Sprintf(" GITHUB_AW_WORKFLOW_FILENAME: %s\n", workflowFilename))
24932515

2516+
// Add custom environment variables from safe-outputs.env
2517+
c.addCustomSafeOutputEnvVars(&steps, data)
2518+
24942519
steps = append(steps, " with:\n")
2520+
// Add github-token if specified
2521+
c.addSafeOutputGitHubToken(&steps, data)
24952522
steps = append(steps, " script: |\n")
24962523

24972524
// Add each line of the script with proper indentation
@@ -2611,7 +2638,12 @@ func (c *Compiler) buildCreateOutputPullRequestJob(data *WorkflowData, mainJobNa
26112638
steps = append(steps, " GITHUB_AW_SAFE_OUTPUTS_STAGED: \"true\"\n")
26122639
}
26132640

2641+
// Add custom environment variables from safe-outputs.env
2642+
c.addCustomSafeOutputEnvVars(&steps, data)
2643+
26142644
steps = append(steps, " with:\n")
2645+
// Add github-token if specified
2646+
c.addSafeOutputGitHubToken(&steps, data)
26152647
steps = append(steps, " script: |\n")
26162648

26172649
// Add each line of the script with proper indentation
@@ -3719,12 +3751,47 @@ func (c *Compiler) extractSafeOutputsConfig(frontmatter map[string]any) *SafeOut
37193751
config.Staged = &stagedBool
37203752
}
37213753
}
3754+
3755+
// Handle env configuration
3756+
if env, exists := outputMap["env"]; exists {
3757+
if envMap, ok := env.(map[string]any); ok {
3758+
config.Env = make(map[string]string)
3759+
for key, value := range envMap {
3760+
if valueStr, ok := value.(string); ok {
3761+
config.Env[key] = valueStr
3762+
}
3763+
}
3764+
}
3765+
}
3766+
3767+
// Handle github-token configuration
3768+
if githubToken, exists := outputMap["github-token"]; exists {
3769+
if githubTokenStr, ok := githubToken.(string); ok {
3770+
config.GitHubToken = githubTokenStr
3771+
}
3772+
}
37223773
}
37233774
}
37243775

37253776
return config
37263777
}
37273778

3779+
// addCustomSafeOutputEnvVars adds custom environment variables to safe output job steps
3780+
func (c *Compiler) addCustomSafeOutputEnvVars(steps *[]string, data *WorkflowData) {
3781+
if data.SafeOutputs != nil && len(data.SafeOutputs.Env) > 0 {
3782+
for key, value := range data.SafeOutputs.Env {
3783+
*steps = append(*steps, fmt.Sprintf(" %s: %s\n", key, value))
3784+
}
3785+
}
3786+
}
3787+
3788+
// addSafeOutputGitHubToken adds github-token to the with section of github-script actions
3789+
func (c *Compiler) addSafeOutputGitHubToken(steps *[]string, data *WorkflowData) {
3790+
if data.SafeOutputs != nil && data.SafeOutputs.GitHubToken != "" {
3791+
*steps = append(*steps, fmt.Sprintf(" github-token: %s\n", data.SafeOutputs.GitHubToken))
3792+
}
3793+
}
3794+
37283795
// extractCacheMemoryConfig extracts cache-memory configuration from tools section
37293796
func (c *Compiler) extractCacheMemoryConfig(tools map[string]any) *CacheMemoryConfig {
37303797
cacheMemoryValue, exists := tools["cache-memory"]

pkg/workflow/output_labels.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ func (c *Compiler) buildCreateOutputLabelJob(data *WorkflowData, mainJobName str
4242
steps = append(steps, " GITHUB_AW_SAFE_OUTPUTS_STAGED: \"true\"\n")
4343
}
4444

45+
// Add custom environment variables from safe-outputs.env
46+
c.addCustomSafeOutputEnvVars(&steps, data)
47+
4548
steps = append(steps, " with:\n")
49+
// Add github-token if specified
50+
c.addSafeOutputGitHubToken(&steps, data)
4651
steps = append(steps, " script: |\n")
4752

4853
// Add each line of the script with proper indentation

pkg/workflow/output_missing_tool.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ func (c *Compiler) buildCreateOutputMissingToolJob(data *WorkflowData, mainJobNa
2525
steps = append(steps, fmt.Sprintf(" GITHUB_AW_MISSING_TOOL_MAX: %d\n", data.SafeOutputs.MissingTool.Max))
2626
}
2727

28+
// Add custom environment variables from safe-outputs.env
29+
c.addCustomSafeOutputEnvVars(&steps, data)
30+
2831
steps = append(steps, " with:\n")
32+
// Add github-token if specified
33+
c.addSafeOutputGitHubToken(&steps, data)
2934
steps = append(steps, " script: |\n")
3035

3136
// Add each line of the script with proper indentation

pkg/workflow/output_push_to_branch.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@ func (c *Compiler) buildCreateOutputPushToPullRequestBranchJob(data *WorkflowDat
4747
// Pass the if-no-changes configuration
4848
steps = append(steps, fmt.Sprintf(" GITHUB_AW_PUSH_IF_NO_CHANGES: %q\n", data.SafeOutputs.PushToPullRequestBranch.IfNoChanges))
4949

50+
// Add custom environment variables from safe-outputs.env
51+
c.addCustomSafeOutputEnvVars(&steps, data)
52+
5053
steps = append(steps, " with:\n")
54+
// Add github-token if specified
55+
c.addSafeOutputGitHubToken(&steps, data)
5156
steps = append(steps, " script: |\n")
5257

5358
// Add each line of the script with proper indentation

pkg/workflow/output_update_issue.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,12 @@ func (c *Compiler) buildCreateOutputUpdateIssueJob(data *WorkflowData, mainJobNa
3030
steps = append(steps, fmt.Sprintf(" GITHUB_AW_UPDATE_TARGET: %q\n", data.SafeOutputs.UpdateIssues.Target))
3131
}
3232

33+
// Add custom environment variables from safe-outputs.env
34+
c.addCustomSafeOutputEnvVars(&steps, data)
35+
3336
steps = append(steps, " with:\n")
37+
// Add github-token if specified
38+
c.addSafeOutputGitHubToken(&steps, data)
3439
steps = append(steps, " script: |\n")
3540

3641
// Add each line of the script with proper indentation

0 commit comments

Comments
 (0)