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

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

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

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

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/test-safe-outputs-custom-engine.lock.yml

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

28 changes: 28 additions & 0 deletions pkg/workflow/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3712,9 +3712,37 @@ func (c *Compiler) generateOutputCollectionStep(yaml *strings.Builder, data *Wor
}
safeOutputsConfig["add-issue-comment"] = commentConfig
}
if data.SafeOutputs.CreateDiscussions != nil {
discussionConfig := map[string]interface{}{
"enabled": true,
}
if data.SafeOutputs.CreateDiscussions.Max > 0 {
discussionConfig["max"] = data.SafeOutputs.CreateDiscussions.Max
}
safeOutputsConfig["create-discussion"] = discussionConfig
}
if data.SafeOutputs.CreatePullRequests != nil {
safeOutputsConfig["create-pull-request"] = true
}
if data.SafeOutputs.CreatePullRequestReviewComments != nil {
prReviewCommentConfig := map[string]interface{}{
"enabled": true,
}
if data.SafeOutputs.CreatePullRequestReviewComments.Max > 0 {
prReviewCommentConfig["max"] = data.SafeOutputs.CreatePullRequestReviewComments.Max
}
safeOutputsConfig["create-pull-request-review-comment"] = prReviewCommentConfig
}
if data.SafeOutputs.CreateSecurityReports != nil {
securityReportConfig := map[string]interface{}{
"enabled": true,
}
// Security reports typically have unlimited max, but check if configured
if data.SafeOutputs.CreateSecurityReports.Max > 0 {
securityReportConfig["max"] = data.SafeOutputs.CreateSecurityReports.Max
}
safeOutputsConfig["create-security-report"] = securityReportConfig
}
if data.SafeOutputs.AddIssueLabels != nil {
safeOutputsConfig["add-issue-label"] = true
}
Expand Down
125 changes: 125 additions & 0 deletions pkg/workflow/output_config_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package workflow

import (
"strings"
"testing"
)

Expand Down Expand Up @@ -115,6 +116,130 @@ func TestAllowedDomainsInWorkflow(t *testing.T) {
}
}

func TestSafeOutputsConfigGeneration(t *testing.T) {
tests := []struct {
name string
frontmatter map[string]any
expectedInConfig []string
unexpectedInConfig []string
}{
{
name: "create-discussion config",
frontmatter: map[string]any{
"safe-outputs": map[string]any{
"create-discussion": map[string]any{
"title-prefix": "[discussion] ",
"max": 2,
},
},
},
expectedInConfig: []string{"create-discussion"},
},
{
name: "create-pull-request-review-comment config",
frontmatter: map[string]any{
"safe-outputs": map[string]any{
"create-pull-request-review-comment": map[string]any{
"max": 5,
},
},
},
expectedInConfig: []string{"create-pull-request-review-comment"},
},
{
name: "create-security-report config",
frontmatter: map[string]any{
"safe-outputs": map[string]any{
"create-security-report": map[string]any{},
},
},
expectedInConfig: []string{"create-security-report"},
},
{
name: "multiple safe outputs including previously missing ones",
frontmatter: map[string]any{
"safe-outputs": map[string]any{
"create-issue": map[string]any{"max": 1},
"create-discussion": map[string]any{"max": 3},
"create-pull-request-review-comment": map[string]any{"max": 10},
"create-security-report": map[string]any{},
"add-issue-comment": map[string]any{},
},
},
expectedInConfig: []string{
"create-issue",
"create-discussion",
"create-pull-request-review-comment",
"create-security-report",
"add-issue-comment",
},
},
{
name: "no safe outputs config",
frontmatter: map[string]any{
"engine": "claude",
},
expectedInConfig: []string{},
unexpectedInConfig: []string{},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
compiler := NewCompiler(false, "", "test")
config := compiler.extractSafeOutputsConfig(tt.frontmatter)

// Test the config generation in generateOutputCollectionStep by creating a mock workflow data
workflowData := &WorkflowData{
SafeOutputs: config,
}

// Use the compiler's generateOutputCollectionStep to test the GITHUB_AW_SAFE_OUTPUTS_CONFIG generation
var yamlBuilder strings.Builder
compiler.generateOutputCollectionStep(&yamlBuilder, workflowData)
generatedYAML := yamlBuilder.String()

// Look specifically for the GITHUB_AW_SAFE_OUTPUTS_CONFIG environment variable line
configLinePresent := strings.Contains(generatedYAML, "GITHUB_AW_SAFE_OUTPUTS_CONFIG:")

if len(tt.expectedInConfig) > 0 {
// If we expect items in config, the config line should be present
if !configLinePresent {
t.Errorf("Expected GITHUB_AW_SAFE_OUTPUTS_CONFIG environment variable to be present, but it was not found")
return
}

// Extract the config line to check its contents
configLine := ""
lines := strings.Split(generatedYAML, "\n")
for _, line := range lines {
if strings.Contains(line, "GITHUB_AW_SAFE_OUTPUTS_CONFIG:") {
configLine = line
break
}
}

// Check expected items are present in the config line
for _, expected := range tt.expectedInConfig {
if !strings.Contains(configLine, expected) {
t.Errorf("Expected %q to be in GITHUB_AW_SAFE_OUTPUTS_CONFIG, but it was not found in config line: %s", expected, configLine)
}
}

// Check unexpected items are not present in the config line
for _, unexpected := range tt.unexpectedInConfig {
if strings.Contains(configLine, unexpected) {
t.Errorf("Did not expect %q to be in GITHUB_AW_SAFE_OUTPUTS_CONFIG, but it was found in config line: %s", unexpected, configLine)
}
}
}
// If we don't expect any items and no unexpected items specified,
// the config line may or may not be present (depending on whether SafeOutputs is nil)
// This is acceptable behavior
})
}
}

func TestCreateDiscussionConfigParsing(t *testing.T) {
tests := []struct {
name string
Expand Down
Loading