From ca0646a96d6845c453ae7f8888c7928740d7e3d6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 07:18:04 +0000 Subject: [PATCH 1/5] Initial plan From b98b5a70c18b0966512d3b4c648a11105457fa1c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 07:39:27 +0000 Subject: [PATCH 2/5] Fix gh aw status workflow count message to distinguish user and internal workflows Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/workflows.go | 34 +++++-- pkg/cli/workflows_count_test.go | 97 ++++++++++++++++++++ pkg/workflow/compiler_safe_outputs_config.go | 4 - 3 files changed, 125 insertions(+), 10 deletions(-) create mode 100644 pkg/cli/workflows_count_test.go diff --git a/pkg/cli/workflows.go b/pkg/cli/workflows.go index 77a75c5e10e..098a7f19867 100644 --- a/pkg/cli/workflows.go +++ b/pkg/cli/workflows.go @@ -110,18 +110,40 @@ func fetchGitHubWorkflows(repoOverride string, verbose bool) (map[string]*GitHub return nil, fmt.Errorf("failed to parse workflow data: %w", err) } - // Stop spinner with success message - if !verbose { - spinner.StopWithMessage(fmt.Sprintf("✓ Fetched %d workflows", len(workflows))) - } - workflowMap := make(map[string]*GitHubWorkflow) for i, workflow := range workflows { name := extractWorkflowNameFromPath(workflow.Path) workflowMap[name] = &workflows[i] } - workflowsLog.Printf("Fetched %d GitHub workflows", len(workflowMap)) + // Count user workflows (those with .md files) vs internal workflows + mdFiles, _ := getMarkdownWorkflowFiles("") + mdWorkflowNames := make(map[string]bool) + for _, file := range mdFiles { + base := filepath.Base(file) + name := strings.TrimSuffix(base, ".md") + mdWorkflowNames[name] = true + } + + var userWorkflowCount, internalWorkflowCount int + for name := range workflowMap { + if mdWorkflowNames[name] { + userWorkflowCount++ + } else { + internalWorkflowCount++ + } + } + + // Stop spinner with success message showing user and internal workflow counts + if !verbose { + if internalWorkflowCount > 0 { + spinner.StopWithMessage(fmt.Sprintf("✓ Fetched %d public and %d internal workflows", userWorkflowCount, internalWorkflowCount)) + } else { + spinner.StopWithMessage(fmt.Sprintf("✓ Fetched %d workflows", userWorkflowCount)) + } + } + + workflowsLog.Printf("Fetched %d GitHub workflows (%d user, %d internal)", len(workflowMap), userWorkflowCount, internalWorkflowCount) return workflowMap, nil } diff --git a/pkg/cli/workflows_count_test.go b/pkg/cli/workflows_count_test.go new file mode 100644 index 00000000000..e26b190ad1c --- /dev/null +++ b/pkg/cli/workflows_count_test.go @@ -0,0 +1,97 @@ +package cli + +import ( + "os" + "path/filepath" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +// TestWorkflowCounting tests that user and internal workflows are counted correctly +func TestWorkflowCounting(t *testing.T) { + // This test verifies the logic for counting user vs internal workflows + // It simulates what fetchGitHubWorkflows does + + // Save current directory + originalDir, err := os.Getwd() + assert.NoError(t, err, "Should get current directory") + + // Change to repository root + repoRoot := filepath.Join(originalDir, "..", "..") + err = os.Chdir(repoRoot) + assert.NoError(t, err, "Should change to repository root") + defer os.Chdir(originalDir) + + // Get markdown workflow files (simulating what fetchGitHubWorkflows does) + mdFiles, err := getMarkdownWorkflowFiles("") + if err != nil { + t.Skipf("Skipping test: no .github/workflows directory found: %v", err) + } + + // Build set of workflow names from .md files + mdWorkflowNames := make(map[string]bool) + for _, file := range mdFiles { + base := filepath.Base(file) + name := strings.TrimSuffix(base, ".md") + mdWorkflowNames[name] = true + } + + // We should have at least some .md files + assert.NotEmpty(t, mdWorkflowNames, "Should have at least some .md workflow files") + + // Simulate having some GitHub workflows where not all have .md files + // (in reality, this would come from GitHub API) + simulatedGitHubWorkflows := make(map[string]*GitHubWorkflow) + + // Add all the .md workflows as "user workflows" + for name := range mdWorkflowNames { + simulatedGitHubWorkflows[name] = &GitHubWorkflow{ + Name: name, + Path: ".github/workflows/" + name + ".lock.yml", + State: "active", + } + } + + // Add some internal workflows (those without .md files) + internalWorkflows := []string{"agentics-maintenance", "ci", "auto-close-parent-issues"} + for _, name := range internalWorkflows { + // Only add if not already present (to avoid duplicates) + if !mdWorkflowNames[name] { + simulatedGitHubWorkflows[name] = &GitHubWorkflow{ + Name: name, + Path: ".github/workflows/" + name + ".yml", + State: "active", + } + } + } + + // Count user vs internal workflows + var userWorkflowCount, internalWorkflowCount int + for name := range simulatedGitHubWorkflows { + if mdWorkflowNames[name] { + userWorkflowCount++ + } else { + internalWorkflowCount++ + } + } + + // Verify counts + assert.Equal(t, len(mdWorkflowNames), userWorkflowCount, "User workflow count should match .md file count") + assert.GreaterOrEqual(t, internalWorkflowCount, 0, "Internal workflow count should be non-negative") + + // Verify message format + var message string + if internalWorkflowCount > 0 { + message = "✓ Fetched " + string(rune(userWorkflowCount+'0')) + " public and " + string(rune(internalWorkflowCount+'0')) + " internal workflows" + assert.Contains(t, message, "public", "Message should contain 'public' when internal workflows exist") + assert.Contains(t, message, "internal", "Message should contain 'internal' when internal workflows exist") + } else { + message = "✓ Fetched " + string(rune(userWorkflowCount+'0')) + " workflows" + assert.NotContains(t, message, "internal", "Message should not contain 'internal' when no internal workflows") + } + + t.Logf("User workflows: %d, Internal workflows: %d", userWorkflowCount, internalWorkflowCount) + t.Logf("Expected message format: %s", message) +} diff --git a/pkg/workflow/compiler_safe_outputs_config.go b/pkg/workflow/compiler_safe_outputs_config.go index abf6cdaee56..19077f93e6b 100644 --- a/pkg/workflow/compiler_safe_outputs_config.go +++ b/pkg/workflow/compiler_safe_outputs_config.go @@ -3,12 +3,8 @@ package workflow import ( "encoding/json" "fmt" - - "github.com/githubnext/gh-aw/pkg/logger" ) -var compilerSafeOutputsLog = logger.New("workflow:compiler_safe_outputs_config") - func (c *Compiler) addHandlerManagerConfigEnvVar(steps *[]string, data *WorkflowData) { if data.SafeOutputs == nil { compilerSafeOutputsLog.Print("No safe-outputs configuration, skipping handler manager config") From 6b2a4c8b4101f7a1d821e33d27e8e72850a39974 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 07:53:39 +0000 Subject: [PATCH 3/5] Fix testifylint issues in workflow count test Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/workflows_count_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/cli/workflows_count_test.go b/pkg/cli/workflows_count_test.go index e26b190ad1c..207004b0b03 100644 --- a/pkg/cli/workflows_count_test.go +++ b/pkg/cli/workflows_count_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // TestWorkflowCounting tests that user and internal workflows are counted correctly @@ -16,12 +17,12 @@ func TestWorkflowCounting(t *testing.T) { // Save current directory originalDir, err := os.Getwd() - assert.NoError(t, err, "Should get current directory") + require.NoError(t, err, "Should get current directory") // Change to repository root repoRoot := filepath.Join(originalDir, "..", "..") err = os.Chdir(repoRoot) - assert.NoError(t, err, "Should change to repository root") + require.NoError(t, err, "Should change to repository root") defer os.Chdir(originalDir) // Get markdown workflow files (simulating what fetchGitHubWorkflows does) From 3e9440e236d6fdccee4343b2bc92d65cdde115a7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 11:48:27 +0000 Subject: [PATCH 4/5] Fix merge conflict in compiler_safe_outputs_config.go and recompile workflows Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/compiler_safe_outputs_config.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/workflow/compiler_safe_outputs_config.go b/pkg/workflow/compiler_safe_outputs_config.go index 292d5083ef9..c9db00636d9 100644 --- a/pkg/workflow/compiler_safe_outputs_config.go +++ b/pkg/workflow/compiler_safe_outputs_config.go @@ -3,13 +3,12 @@ package workflow import ( "encoding/json" "fmt" + + "github.com/githubnext/gh-aw/pkg/logger" ) -<<<<<<< HEAD -======= var compilerSafeOutputsConfigLog = logger.New("workflow:compiler_safe_outputs_config") ->>>>>>> origin/main func (c *Compiler) addHandlerManagerConfigEnvVar(steps *[]string, data *WorkflowData) { if data.SafeOutputs == nil { compilerSafeOutputsConfigLog.Print("No safe-outputs configuration, skipping handler manager config") From e012d6981c41a7eb7879330f0398e57c4d8447c9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 11:58:59 +0000 Subject: [PATCH 5/5] Use extractWorkflowNameFromPath helper to resolve workflow names Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/workflows.go | 3 +-- pkg/cli/workflows_count_test.go | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/pkg/cli/workflows.go b/pkg/cli/workflows.go index 098a7f19867..7f221a58a27 100644 --- a/pkg/cli/workflows.go +++ b/pkg/cli/workflows.go @@ -120,8 +120,7 @@ func fetchGitHubWorkflows(repoOverride string, verbose bool) (map[string]*GitHub mdFiles, _ := getMarkdownWorkflowFiles("") mdWorkflowNames := make(map[string]bool) for _, file := range mdFiles { - base := filepath.Base(file) - name := strings.TrimSuffix(base, ".md") + name := extractWorkflowNameFromPath(file) mdWorkflowNames[name] = true } diff --git a/pkg/cli/workflows_count_test.go b/pkg/cli/workflows_count_test.go index 207004b0b03..3e243ad6672 100644 --- a/pkg/cli/workflows_count_test.go +++ b/pkg/cli/workflows_count_test.go @@ -3,7 +3,6 @@ package cli import ( "os" "path/filepath" - "strings" "testing" "github.com/stretchr/testify/assert" @@ -34,8 +33,7 @@ func TestWorkflowCounting(t *testing.T) { // Build set of workflow names from .md files mdWorkflowNames := make(map[string]bool) for _, file := range mdFiles { - base := filepath.Base(file) - name := strings.TrimSuffix(base, ".md") + name := extractWorkflowNameFromPath(file) mdWorkflowNames[name] = true }