diff --git a/.github/aw/schemas/agentic-workflow.json b/.github/aw/schemas/agentic-workflow.json index 7efbf15361..72e8900943 100644 --- a/.github/aw/schemas/agentic-workflow.json +++ b/.github/aw/schemas/agentic-workflow.json @@ -3890,7 +3890,8 @@ "description": "Relative time (e.g., '2h', '7d', '2w', '1m', '1y'); minimum 2h for hour values" } ], - "description": "Time until the discussion expires and should be automatically closed. Supports integer (days) or relative time format like '2h' (2 hours), '7d' (7 days), '2w' (2 weeks), '1m' (1 month), '1y' (1 year). Minimum duration: 2 hours. When set, a maintenance workflow will be generated." + "default": 7, + "description": "Time until the discussion expires and should be automatically closed. Supports integer (days) or relative time format like '2h' (2 hours), '7d' (7 days), '2w' (2 weeks), '1m' (1 month), '1y' (1 year). Minimum duration: 2 hours. When set, a maintenance workflow will be generated. Defaults to 7 days if not specified." } }, "additionalProperties": false, diff --git a/.github/workflows/github-remote-mcp-auth-test.lock.yml b/.github/workflows/github-remote-mcp-auth-test.lock.yml index aa6c5b2888..b729fd6e08 100644 --- a/.github/workflows/github-remote-mcp-auth-test.lock.yml +++ b/.github/workflows/github-remote-mcp-auth-test.lock.yml @@ -1062,7 +1062,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"max\":1,\"title_prefix\":\"[auth-test] \"}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":168,\"max\":1,\"title_prefix\":\"[auth-test] \"}}" with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | diff --git a/pkg/cli/compile_campaign.go b/pkg/cli/compile_campaign.go index 0df4a30686..5edf8313f7 100644 --- a/pkg/cli/compile_campaign.go +++ b/pkg/cli/compile_campaign.go @@ -130,8 +130,13 @@ func validateCampaigns(workflowDir string, verbose bool, campaignFiles []string) // Validate the spec itself problems := campaign.ValidateSpec(&spec) - // Validate that referenced workflows exist - workflowProblems := campaign.ValidateWorkflowsExist(&spec, absWorkflowDir) + // Validate that referenced workflows exist in the same directory as the campaign spec + // Use the directory of the campaign spec file, not a global workflow directory + campaignDir := filepath.Dir(spec.ConfigPath) + if !filepath.IsAbs(campaignDir) { + campaignDir = filepath.Join(gitRoot, campaignDir) + } + workflowProblems := campaign.ValidateWorkflowsExist(&spec, campaignDir) problems = append(problems, workflowProblems...) if len(problems) > 0 { diff --git a/pkg/cli/compile_campaign_validation_test.go b/pkg/cli/compile_campaign_validation_test.go new file mode 100644 index 0000000000..58c33a4ba9 --- /dev/null +++ b/pkg/cli/compile_campaign_validation_test.go @@ -0,0 +1,88 @@ +package cli + +import ( + "os" + "path/filepath" + "testing" + + "github.com/githubnext/gh-aw/pkg/campaign" +) + +// TestValidateCampaignsUsesCorrectDirectory tests that validateCampaigns uses +// the campaign spec file's directory to validate referenced workflows, not +// a global workflow directory parameter. +func TestValidateCampaignsUsesCorrectDirectory(t *testing.T) { + tmpDir := t.TempDir() + + // Create a campaign spec file + workflowsDir := filepath.Join(tmpDir, ".github", "workflows") + if err := os.MkdirAll(workflowsDir, 0755); err != nil { + t.Fatal(err) + } + + // Create referenced workflow files + workflowFile := filepath.Join(workflowsDir, "example-workflow.md") + workflowContent := `--- +engine: copilot +--- + +# Test workflow +Test workflow content +` + if err := os.WriteFile(workflowFile, []byte(workflowContent), 0644); err != nil { + t.Fatal(err) + } + + // Create campaign spec file + campaignFile := filepath.Join(workflowsDir, "test-campaign.campaign.md") + campaignContent := `--- +id: test-campaign +name: Test Campaign +description: A test campaign +version: v1 +project-url: https://github.com/orgs/test/projects/1 +workflows: + - example-workflow +state: active +--- + +# Campaign Test +Test campaign +` + if err := os.WriteFile(campaignFile, []byte(campaignContent), 0644); err != nil { + t.Fatal(err) + } + + // Change to tmpDir so it becomes the git root for the test + origDir, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + defer os.Chdir(origDir) + + if err := os.Chdir(tmpDir); err != nil { + t.Fatal(err) + } + + // Initialize a git repo + if err := os.WriteFile(".git", []byte("fake git"), 0644); err != nil { + t.Fatal(err) + } + + // Load the campaign spec + specs, err := campaign.LoadSpecs(tmpDir) + if err != nil { + t.Fatalf("LoadSpecs failed: %v", err) + } + + if len(specs) == 0 { + t.Fatal("Expected to load 1 campaign spec, got 0") + } + + // Validate campaigns with an incorrect workflow directory + // This should still work because validateCampaigns should use each spec's directory + err = validateCampaigns(".github/workflows", false, []string{campaignFile}) + if err != nil { + t.Fatalf("validateCampaigns failed: %v", err) + } +}