Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
51 changes: 51 additions & 0 deletions pkg/workflow/bots_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"testing"

"github.com/github/gh-aw/pkg/testutil"
"github.com/stretchr/testify/assert"
)

// TestBotsFieldExtraction tests the extraction of the bots field from frontmatter
Expand Down Expand Up @@ -196,6 +197,56 @@ Test workflow content with bot and default roles.`
}
}

// TestMergeBots tests the mergeBots helper function
func TestMergeBots(t *testing.T) {
compiler := NewCompiler()

tests := []struct {
name string
top []string
imported []string
expected []string
}{
{
name: "top only",
top: []string{"dependabot[bot]"},
imported: nil,
expected: []string{"dependabot[bot]"},
},
{
name: "imported only",
top: nil,
imported: []string{"renovate[bot]"},
expected: []string{"renovate[bot]"},
},
{
name: "both with no overlap",
top: []string{"dependabot[bot]"},
imported: []string{"renovate[bot]"},
expected: []string{"dependabot[bot]", "renovate[bot]"},
},
{
name: "both with duplicates deduped",
top: []string{"dependabot[bot]", "renovate[bot]"},
imported: []string{"renovate[bot]", "github-actions[bot]"},
expected: []string{"dependabot[bot]", "renovate[bot]", "github-actions[bot]"},
},
{
name: "both nil",
top: nil,
imported: nil,
expected: []string{},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := compiler.mergeBots(tt.top, tt.imported)
assert.Equal(t, tt.expected, result, "mergeBots result mismatch")
})
}
}

// TestBotsWithRolesAll tests that bots field works even when roles: all is set
func TestBotsWithRolesAll(t *testing.T) {
tmpDir := testutil.TempDir(t, "workflow-bots-roles-all-test")
Expand Down
2 changes: 1 addition & 1 deletion pkg/workflow/compiler_orchestrator_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ func (c *Compiler) extractAdditionalConfigurations(
}

workflowData.Roles = c.extractRoles(frontmatter)
workflowData.Bots = c.extractBots(frontmatter)
workflowData.Bots = c.mergeBots(c.extractBots(frontmatter), importsResult.MergedBots)

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

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

This change fixes imported bots propagation, but the added test only validates mergeBots in isolation. Consider adding an end-to-end test that compiles a workflow importing another workflow that defines on.bots, and assert the compiled lock output includes the expected GH_AW_ALLOWED_BOTS (and that top-level + imported bots are unioned/deduped). This will guard against regressions where the orchestrator stops applying importsResult.MergedBots.

Copilot uses AI. Check for mistakes.
workflowData.LabelNames = c.extractLabelNames(frontmatter)
workflowData.RateLimit = c.extractRateLimitConfig(frontmatter)
workflowData.SkipRoles = c.mergeSkipRoles(c.extractSkipRoles(frontmatter), importsResult.MergedSkipRoles)
Expand Down
5 changes: 5 additions & 0 deletions pkg/workflow/role_checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,11 @@ func (c *Compiler) mergeSkipBots(topSkipBots []string, importedSkipBots []string
return mergeStringSlicesDedup(topSkipBots, importedSkipBots, "skip-bots")
}

// mergeBots merges top-level bots with imported bots (union)
func (c *Compiler) mergeBots(topBots []string, importedBots []string) []string {
return mergeStringSlicesDedup(topBots, importedBots, "bots")
}

// extractActivationGitHubToken extracts the 'github-token' field from the 'on:' section of frontmatter.
// This token is used for pre-activation reactions and activation status comments.
func (c *Compiler) extractActivationGitHubToken(frontmatter map[string]any) string {
Expand Down
Loading