From c15f77bdf9c750d54f215fe76d247c227baa3dff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 04:26:11 +0000 Subject: [PATCH 1/3] Initial plan From 5e81b627eb82ebad7d1f78ed908e3ecb63aa6cb7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 04:32:19 +0000 Subject: [PATCH 2/3] Fix campaign orchestrator to use correct label convention - Update security-alert-burndown.campaign.md tracker-label from campaign:security-alert-burndown to z_campaign_security-alert-burndown - Update validation in pkg/campaign/validation.go to enforce z_campaign_ prefix instead of campaign: prefix - Recompile campaign workflow to regenerate lock file with correct environment variable Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com> --- .../workflows/security-alert-burndown.campaign.lock.yml | 2 +- .github/workflows/security-alert-burndown.campaign.md | 2 +- pkg/campaign/validation.go | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/security-alert-burndown.campaign.lock.yml b/.github/workflows/security-alert-burndown.campaign.lock.yml index f3ca458a8e..e3642194a4 100644 --- a/.github/workflows/security-alert-burndown.campaign.lock.yml +++ b/.github/workflows/security-alert-burndown.campaign.lock.yml @@ -117,7 +117,7 @@ jobs: GH_AW_MAX_DISCOVERY_ITEMS: "100" GH_AW_MAX_DISCOVERY_PAGES: "5" GH_AW_PROJECT_URL: https://github.com/orgs/githubnext/projects/134 - GH_AW_TRACKER_LABEL: campaign:security-alert-burndown + GH_AW_TRACKER_LABEL: z_campaign_security-alert-burndown GH_AW_WORKFLOWS: code-scanning-fixer,security-fix-pr,dependabot-bundler,secret-scanning-triage id: discovery name: Run campaign discovery precomputation diff --git a/.github/workflows/security-alert-burndown.campaign.md b/.github/workflows/security-alert-burndown.campaign.md index 519cb03f10..b8c63340f5 100644 --- a/.github/workflows/security-alert-burndown.campaign.md +++ b/.github/workflows/security-alert-burndown.campaign.md @@ -14,7 +14,7 @@ allowed-repos: - githubnext/gh-aw discovery-repos: - githubnext/gh-aw -tracker-label: campaign:security-alert-burndown +tracker-label: z_campaign_security-alert-burndown memory-paths: - memory/campaigns/security-alert-burndown/** metrics-glob: memory/campaigns/security-alert-burndown/metrics/*.json diff --git a/pkg/campaign/validation.go b/pkg/campaign/validation.go index 61cfa495f8..42de7b43e8 100644 --- a/pkg/campaign/validation.go +++ b/pkg/campaign/validation.go @@ -69,9 +69,10 @@ func ValidateSpec(spec *CampaignSpec) []string { // Validate tracker-label format if provided if strings.TrimSpace(spec.TrackerLabel) != "" { trimmedLabel := strings.TrimSpace(spec.TrackerLabel) - // Tracker labels should follow the pattern "campaign:campaign-id" - if !strings.HasPrefix(trimmedLabel, "campaign:") { - problems = append(problems, fmt.Sprintf("tracker-label should start with 'campaign:' prefix - got '%s', recommended: 'campaign:%s'", trimmedLabel, spec.ID)) + // Tracker labels should follow the pattern "z_campaign_" + expectedLabel := fmt.Sprintf("z_campaign_%s", strings.ToLower(strings.ReplaceAll(spec.ID, "_", "-"))) + if !strings.HasPrefix(trimmedLabel, "z_campaign_") { + problems = append(problems, fmt.Sprintf("tracker-label should start with 'z_campaign_' prefix - got '%s', recommended: '%s'", trimmedLabel, expectedLabel)) } // Check for invalid characters in labels (GitHub label restrictions) if strings.Contains(trimmedLabel, " ") { From 4efeafbe87fbde2fbdbc75ca447a7233d33a8b92 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 04:36:57 +0000 Subject: [PATCH 3/3] Add tests for tracker label validation - Added comprehensive tests for tracker label format validation - Tests verify z_campaign_ prefix requirement - Tests ensure old campaign: prefix is rejected - All tests passing Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com> --- pkg/campaign/validation_test.go | 76 +++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/pkg/campaign/validation_test.go b/pkg/campaign/validation_test.go index 8cac36d51d..b2a66484d9 100644 --- a/pkg/campaign/validation_test.go +++ b/pkg/campaign/validation_test.go @@ -754,3 +754,79 @@ func TestValidateSpec_AllowedOrgsWildcard(t *testing.T) { t.Errorf("Expected wildcard validation problem for orgs, got: %v", problems) } } + +func TestValidateSpec_TrackerLabelFormat(t *testing.T) { + tests := []struct { + name string + campaignID string + trackerLabel string + expectError bool + errorContains string + }{ + { + name: "valid tracker label with z_campaign_ prefix", + campaignID: "security-alert-burndown", + trackerLabel: "z_campaign_security-alert-burndown", + expectError: false, + }, + { + name: "invalid tracker label with old campaign: prefix", + campaignID: "security-alert-burndown", + trackerLabel: "campaign:security-alert-burndown", + expectError: true, + errorContains: "tracker-label should start with 'z_campaign_' prefix", + }, + { + name: "invalid tracker label with wrong format", + campaignID: "test-campaign", + trackerLabel: "wrong-label-format", + expectError: true, + errorContains: "tracker-label should start with 'z_campaign_' prefix", + }, + { + name: "empty tracker label is valid (optional field)", + campaignID: "test-campaign", + trackerLabel: "", + expectError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + spec := &CampaignSpec{ + ID: tt.campaignID, + Name: "Test Campaign", + ProjectURL: "https://github.com/orgs/org/projects/1", + DiscoveryRepos: []string{"test/repo"}, + Workflows: []string{"workflow1"}, + TrackerLabel: tt.trackerLabel, + } + + problems := ValidateSpec(spec) + + if tt.expectError { + if len(problems) == 0 { + t.Errorf("Expected validation error but got none") + return + } + found := false + for _, p := range problems { + if strings.Contains(p, tt.errorContains) { + found = true + break + } + } + if !found { + t.Errorf("Expected error containing %q, got: %v", tt.errorContains, problems) + } + } else { + // Filter out problems that are not related to tracker-label + for _, p := range problems { + if strings.Contains(p, "tracker-label") { + t.Errorf("Unexpected tracker-label validation error: %s", p) + } + } + } + }) + } +}