Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ai-moderator.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/dependabot-go-checker.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/semantic-function-refactor.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 11 additions & 3 deletions .github/workflows/smoke-copilot.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions .github/workflows/smoke-copilot.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ safe-outputs:
add-comment:
hide-older-comments: true
max: 2
allowed-repos: ["github/gh-aw"]
create-issue:
expires: 2h
group: true
close-older-issues: true
add-labels:
allowed: [smoke-copilot]
allowed-repos: ["github/gh-aw"]
remove-labels:
allowed: [smoke]
dispatch-workflow:
Expand Down
14 changes: 14 additions & 0 deletions pkg/parser/schemas/main_workflow_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -4570,6 +4570,13 @@
"target-repo": {
"type": "string",
"description": "Target repository in format 'owner/repo' for cross-repository operations. Takes precedence over trial target repo settings."
},
"allowed-repos": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of additional repositories in format 'owner/repo' that issues can be closed in. When specified, the agent can use a 'repo' field in the output to specify which repository to close the issue in. The target repository (current or target-repo) is always implicitly allowed."
}
},
"additionalProperties": false,
Expand Down Expand Up @@ -5018,6 +5025,13 @@
"github-token": {
"$ref": "#/$defs/github_token",
"description": "GitHub token to use for this specific output type. Overrides global github-token if specified."
},
"allowed-repos": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of additional repositories in format 'owner/repo' that labels can be added to. When specified, the agent can use a 'repo' field in the output to specify which repository to add labels to. The target repository (current or target-repo) is always implicitly allowed."
}
},
"additionalProperties": false
Expand Down
35 changes: 28 additions & 7 deletions pkg/workflow/safe_outputs_config_generation.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,19 @@ func generateSafeOutputsConfig(data *WorkflowData) string {
)
}
if data.SafeOutputs.AddComments != nil {
safeOutputsConfig["add_comment"] = generateMaxWithTargetConfig(
additionalFields := make(map[string]any)
// Note: AddCommentsConfig has Target, TargetRepoSlug, AllowedRepos but not embedded SafeOutputTargetConfig
// So we need to construct the target config manually
targetConfig := SafeOutputTargetConfig{
Target: data.SafeOutputs.AddComments.Target,
TargetRepoSlug: data.SafeOutputs.AddComments.TargetRepoSlug,
AllowedRepos: data.SafeOutputs.AddComments.AllowedRepos,
}
safeOutputsConfig["add_comment"] = generateTargetConfigWithRepos(
targetConfig,
data.SafeOutputs.AddComments.Max,
1, // default max
data.SafeOutputs.AddComments.Target,
additionalFields,
)
Comment on lines +93 to 106
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The additionalFields map for add_comment is created but left empty. Consider adding hide_older_comments and allowed_reasons fields to maintain consistency with the handler config in compiler_safe_outputs_config.go (lines 132-137), which includes these fields.

While this is a pre-existing discrepancy (the old code also didn't include these fields), it would be beneficial to address it while refactoring this section. The JavaScript handler (add_comment.cjs) expects hide_older_comments in the config (line 278).

Example:

additionalFields := make(map[string]any)
if data.SafeOutputs.AddComments.HideOlderComments {
    additionalFields["hide_older_comments"] = true
}
if len(data.SafeOutputs.AddComments.AllowedReasons) > 0 {
    additionalFields["allowed_reasons"] = data.SafeOutputs.AddComments.AllowedReasons
}

Copilot uses AI. Check for mistakes.
}
if data.SafeOutputs.CreateDiscussions != nil {
Expand All @@ -118,11 +127,18 @@ func generateSafeOutputsConfig(data *WorkflowData) string {
)
}
if data.SafeOutputs.CloseIssues != nil {
safeOutputsConfig["close_issue"] = generateMaxWithRequiredFieldsConfig(
additionalFields := make(map[string]any)
if len(data.SafeOutputs.CloseIssues.RequiredLabels) > 0 {
additionalFields["required_labels"] = data.SafeOutputs.CloseIssues.RequiredLabels
}
if data.SafeOutputs.CloseIssues.RequiredTitlePrefix != "" {
additionalFields["required_title_prefix"] = data.SafeOutputs.CloseIssues.RequiredTitlePrefix
}
safeOutputsConfig["close_issue"] = generateTargetConfigWithRepos(
data.SafeOutputs.CloseIssues.SafeOutputTargetConfig,
data.SafeOutputs.CloseIssues.Max,
1, // default max
data.SafeOutputs.CloseIssues.RequiredLabels,
data.SafeOutputs.CloseIssues.RequiredTitlePrefix,
additionalFields,
)
}
if data.SafeOutputs.CreatePullRequests != nil {
Expand Down Expand Up @@ -152,10 +168,15 @@ func generateSafeOutputsConfig(data *WorkflowData) string {
)
}
if data.SafeOutputs.AddLabels != nil {
safeOutputsConfig["add_labels"] = generateMaxWithAllowedConfig(
additionalFields := make(map[string]any)
if len(data.SafeOutputs.AddLabels.Allowed) > 0 {
additionalFields["allowed"] = data.SafeOutputs.AddLabels.Allowed
}
safeOutputsConfig["add_labels"] = generateTargetConfigWithRepos(
data.SafeOutputs.AddLabels.SafeOutputTargetConfig,
data.SafeOutputs.AddLabels.Max,
3, // default max
data.SafeOutputs.AddLabels.Allowed,
additionalFields,
)
}
if data.SafeOutputs.RemoveLabels != nil {
Expand Down
31 changes: 31 additions & 0 deletions pkg/workflow/safe_outputs_config_generation_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,34 @@ func generateHideCommentConfig(max int, defaultMax int, allowedReasons []string)
}
return config
}

// generateTargetConfigWithRepos creates a config with target, target-repo, allowed_repos, and optional fields.
// Note on naming conventions:
// - "target-repo" uses hyphen to match frontmatter YAML format (key in config.json)
// - "allowed_repos" uses underscore to match JavaScript handler expectations (see repo_helpers.cjs)
// This inconsistency is intentional to maintain compatibility with existing handler code.
func generateTargetConfigWithRepos(targetConfig SafeOutputTargetConfig, max int, defaultMax int, additionalFields map[string]any) map[string]any {
config := generateMaxConfig(max, defaultMax)

// Add target if specified
if targetConfig.Target != "" {
config["target"] = targetConfig.Target
}

// Add target-repo if specified (use hyphenated key for consistency with frontmatter)
if targetConfig.TargetRepoSlug != "" {
config["target-repo"] = targetConfig.TargetRepoSlug
}

// Add allowed_repos if specified (use underscore for consistency with handler code)
if len(targetConfig.AllowedRepos) > 0 {
config["allowed_repos"] = targetConfig.AllowedRepos
}

// Add any additional fields
for key, value := range additionalFields {
config[key] = value
}

return config
}
Loading