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 pkg/workflow/compiler_parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (c *Compiler) ParseWorkflowFile(markdownPath string) (*WorkflowData, error)
}

// Preprocess schedule fields to convert human-friendly format to cron expressions
if err := c.preprocessScheduleFields(result.Frontmatter); err != nil {
if err := c.preprocessScheduleFields(result.Frontmatter, markdownPath, string(content)); err != nil {
return nil, err
}

Expand Down
60 changes: 30 additions & 30 deletions pkg/workflow/frontmatter_extraction.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (c *Compiler) extractTopLevelYAMLSection(frontmatter map[string]any, key st
// Exception: names fields in sections with __gh_aw_native_label_filter__ marker in frontmatter are NOT commented out
func (c *Compiler) commentOutProcessedFieldsInOnSection(yamlStr string, frontmatter map[string]any) string {
frontmatterLog.Print("Processing 'on' section to comment out processed fields")

// Check frontmatter for native label filter markers
nativeLabelFilterSections := make(map[string]bool)
if onValue, exists := frontmatter["on"]; exists {
Expand Down Expand Up @@ -289,42 +289,42 @@ func (c *Compiler) commentOutProcessedFieldsInOnSection(yamlStr string, frontmat
// Look back to see if the previous uncommented line was "names:"
// Only do this if NOT using native label filtering for this section
if !nativeLabelFilterSections[currentSection] {
if len(result) > 0 {
for i := len(result) - 1; i >= 0; i-- {
prevLine := result[i]
prevTrimmed := strings.TrimSpace(prevLine)

// Skip empty lines
if prevTrimmed == "" {
continue
}
if len(result) > 0 {
for i := len(result) - 1; i >= 0; i-- {
prevLine := result[i]
prevTrimmed := strings.TrimSpace(prevLine)

// Skip empty lines
if prevTrimmed == "" {
continue
}

// If we find "names:", and current line is an array item, comment it
if strings.Contains(prevTrimmed, "names:") && strings.Contains(prevTrimmed, "# Label filtering") {
if strings.HasPrefix(trimmedLine, "-") {
shouldComment = true
commentReason = " # Label filtering applied via job conditions"
// If we find "names:", and current line is an array item, comment it
if strings.Contains(prevTrimmed, "names:") && strings.Contains(prevTrimmed, "# Label filtering") {
if strings.HasPrefix(trimmedLine, "-") {
shouldComment = true
commentReason = " # Label filtering applied via job conditions"
}
break
}
break
}

// If we find a different field or commented names array item, break
if !strings.HasPrefix(prevTrimmed, "#") || !strings.Contains(prevTrimmed, "Label filtering") {
break
}
// If we find a different field or commented names array item, break
if !strings.HasPrefix(prevTrimmed, "#") || !strings.Contains(prevTrimmed, "Label filtering") {
break
}

// If it's a commented names array item, continue
if strings.HasPrefix(prevTrimmed, "# -") && strings.Contains(prevTrimmed, "Label filtering") {
if strings.HasPrefix(trimmedLine, "-") {
shouldComment = true
commentReason = " # Label filtering applied via job conditions"
// If it's a commented names array item, continue
if strings.HasPrefix(prevTrimmed, "# -") && strings.Contains(prevTrimmed, "Label filtering") {
if strings.HasPrefix(trimmedLine, "-") {
shouldComment = true
commentReason = " # Label filtering applied via job conditions"
}
continue
}
continue
}

break
break
}
}
}
} // Close native filter check
}

Expand Down
10 changes: 5 additions & 5 deletions pkg/workflow/label_trigger_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func TestLabelTriggerIntegrationSimple(t *testing.T) {
}

compiler := NewCompiler(false, "", "test")
err := compiler.preprocessScheduleFields(frontmatter)
err := compiler.preprocessScheduleFields(frontmatter, "", "")
if err != nil {
t.Fatalf("preprocessScheduleFields() error = %v", err)
}
Expand Down Expand Up @@ -90,7 +90,7 @@ func TestLabelTriggerIntegrationIssue(t *testing.T) {
}

compiler := NewCompiler(false, "", "test")
err := compiler.preprocessScheduleFields(frontmatter)
err := compiler.preprocessScheduleFields(frontmatter, "", "")
if err != nil {
t.Fatalf("preprocessScheduleFields() error = %v", err)
}
Expand Down Expand Up @@ -120,7 +120,7 @@ func TestLabelTriggerIntegrationPullRequest(t *testing.T) {
}

compiler := NewCompiler(false, "", "test")
err := compiler.preprocessScheduleFields(frontmatter)
err := compiler.preprocessScheduleFields(frontmatter, "", "")
if err != nil {
t.Fatalf("preprocessScheduleFields() error = %v", err)
}
Expand Down Expand Up @@ -186,7 +186,7 @@ func TestLabelTriggerIntegrationDiscussion(t *testing.T) {
}

compiler := NewCompiler(false, "", "test")
err := compiler.preprocessScheduleFields(frontmatter)
err := compiler.preprocessScheduleFields(frontmatter, "", "")
if err != nil {
t.Fatalf("preprocessScheduleFields() error = %v", err)
}
Expand Down Expand Up @@ -249,7 +249,7 @@ func TestLabelTriggerIntegrationError(t *testing.T) {
}

compiler := NewCompiler(false, "", "test")
err := compiler.preprocessScheduleFields(frontmatter)
err := compiler.preprocessScheduleFields(frontmatter, "", "")
if err != nil {
t.Fatalf("preprocessScheduleFields() unexpected error = %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/workflow/label_trigger_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func expandLabelTriggerShorthand(entityType string, labelNames []string) map[str
triggerConfig := map[string]any{
"types": []any{"labeled"},
}

// Only add names field for issues and pull_request (GitHub Actions supports it)
// For discussions, names field is not supported by GitHub Actions
if entityType == "issues" || entityType == "pull_request" {
Expand Down
34 changes: 17 additions & 17 deletions pkg/workflow/label_trigger_parser_fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,23 @@ func FuzzParseLabelTriggerShorthand(f *testing.F) {
f.Add("issue labeled bug enhancement")
f.Add("ISSUE LABELED BUG")
f.Add("Issue Labeled Bug")

f.Fuzz(func(t *testing.T, input string) {
// The function should never panic regardless of input
entityType, labelNames, isLabelTrigger, err := parseLabelTriggerShorthand(input)

// Validate the output is consistent
if isLabelTrigger {
// If it's recognized as a label trigger, must have entity type
if entityType == "" {
t.Errorf("isLabelTrigger=true but entityType is empty for input: %q", input)
}

// If no error, must have at least one label name
if err == nil && len(labelNames) == 0 {
t.Errorf("isLabelTrigger=true and err=nil but no label names for input: %q", input)
}

// If error is present, label names should be nil or empty
if err != nil && len(labelNames) > 0 {
t.Errorf("isLabelTrigger=true with error but labelNames is not empty for input: %q", input)
Expand All @@ -52,23 +52,23 @@ func FuzzParseLabelTriggerShorthand(f *testing.F) {
if entityType != "" {
t.Errorf("isLabelTrigger=false but entityType=%q for input: %q", entityType, input)
}

// If not a label trigger, label names should be nil
if labelNames != nil {
t.Errorf("isLabelTrigger=false but labelNames=%v for input: %q", labelNames, input)
}

// If not a label trigger, should not have an error
if err != nil {
t.Errorf("isLabelTrigger=false but has error for input: %q, error: %v", input, err)
}
}

// Validate entity types are only the expected ones
if entityType != "" && entityType != "issues" && entityType != "pull_request" && entityType != "discussion" {
t.Errorf("unexpected entityType=%q for input: %q", entityType, input)
}

// Validate label names don't contain empty strings
for _, label := range labelNames {
if label == "" {
Expand All @@ -88,7 +88,7 @@ func FuzzExpandLabelTriggerShorthand(f *testing.F) {
f.Add("issues", "bug,enhancement,priority-high")
f.Add("unknown", "test")
f.Add("", "bug")

f.Fuzz(func(t *testing.T, entityType string, labelsStr string) {
// Parse labels string into array
var labelNames []string
Expand All @@ -99,32 +99,32 @@ func FuzzExpandLabelTriggerShorthand(f *testing.F) {
}
}
}

if len(labelNames) == 0 {
// Skip if no labels
return
}

// The function should never panic
result := expandLabelTriggerShorthand(entityType, labelNames)

// Validate result structure
if result == nil {
t.Errorf("expandLabelTriggerShorthand returned nil for entityType=%q, labels=%v", entityType, labelNames)
return
}

// Check for workflow_dispatch
if _, hasDispatch := result["workflow_dispatch"]; !hasDispatch {
t.Errorf("result missing workflow_dispatch for entityType=%q", entityType)
}

// Check for trigger key (issues, pull_request, or discussion)
hasTrigger := false
for key := range result {
if key == "issues" || key == "pull_request" || key == "discussion" {
hasTrigger = true

// Validate trigger structure
if triggerMap, ok := result[key].(map[string]any); ok {
// Check for types field
Expand All @@ -135,7 +135,7 @@ func FuzzExpandLabelTriggerShorthand(f *testing.F) {
} else if len(typeArray) == 0 {
t.Errorf("types array is empty for entityType=%q", entityType)
}

// Check for names field
if names, hasNames := triggerMap["names"]; !hasNames {
t.Errorf("trigger missing names field for entityType=%q", entityType)
Expand All @@ -147,7 +147,7 @@ func FuzzExpandLabelTriggerShorthand(f *testing.F) {
}
}
}

if !hasTrigger {
t.Errorf("result missing trigger key (issues/pull_request/discussion) for entityType=%q", entityType)
}
Expand Down
Loading