Skip to content

Commit d9ed877

Browse files
authored
Refactor: Move misplaced functions from add_command.go to domain-specific files (#3761)
1 parent 8c270ad commit d9ed877

5 files changed

Lines changed: 159 additions & 161 deletions

File tree

docs/src/content/docs/status.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Status of all agentic workflows. [Browse source files](https://github.com/github
1515
| [Basic Research Agent](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/research.md) | copilot | [![Basic Research Agent](https://github.com/githubnext/gh-aw/actions/workflows/research.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/research.lock.yml) | - | - |
1616
| [Blog Auditor](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/blog-auditor.md) | claude | [![Blog Auditor](https://github.com/githubnext/gh-aw/actions/workflows/blog-auditor.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/blog-auditor.lock.yml) | `0 12 * * 3` | - |
1717
| [Brave Web Search Agent](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/brave.md) | copilot | [![Brave Web Search Agent](https://github.com/githubnext/gh-aw/actions/workflows/brave.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/brave.lock.yml) | - | `/brave` |
18-
| [Changeset Generator](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/changeset.md) | copilot | [![Changeset Generator](https://github.com/githubnext/gh-aw/actions/workflows/changeset.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/changeset.lock.yml) | - | - |
18+
| [Changeset Generator](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/changeset.md) | copilot | [![Changeset Generator](https://github.com/githubnext/gh-aw/actions/workflows/changeset.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/changeset.lock.yml) | `0 */2 * * *` | - |
1919
| [CI Failure Doctor](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/ci-doctor.md) | copilot | [![CI Failure Doctor](https://github.com/githubnext/gh-aw/actions/workflows/ci-doctor.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/ci-doctor.lock.yml) | - | - |
2020
| [CLI Consistency Checker](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/cli-consistency-checker.md) | copilot | [![CLI Consistency Checker](https://github.com/githubnext/gh-aw/actions/workflows/cli-consistency-checker.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/cli-consistency-checker.lock.yml) | `0 13 * * 1-5` | - |
2121
| [CLI Version Checker](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/cli-version-checker.md) | copilot | [![CLI Version Checker](https://github.com/githubnext/gh-aw/actions/workflows/cli-version-checker.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/cli-version-checker.lock.yml) | `0 15 * * *` | - |

pkg/cli/add_command.go

Lines changed: 0 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package cli
22

33
import (
4-
"encoding/json"
54
"fmt"
65
"math/rand"
76
"os"
8-
"os/exec"
97
"path/filepath"
108
"strings"
119

@@ -815,164 +813,6 @@ func compileWorkflowWithTracking(filePath string, verbose bool, engineOverride s
815813
return nil
816814
}
817815

818-
// ensureCopilotInstructions ensures that .github/instructions/github-agentic-workflows.md contains the copilot instructions
819-
func ensureCopilotInstructions(verbose bool, skipInstructions bool) error {
820-
if skipInstructions {
821-
return nil // Skip writing instructions if flag is set
822-
}
823-
824-
gitRoot, err := findGitRoot()
825-
if err != nil {
826-
return err // Not in a git repository, skip
827-
}
828-
829-
copilotDir := filepath.Join(gitRoot, ".github", "instructions")
830-
copilotInstructionsPath := filepath.Join(copilotDir, "github-agentic-workflows.instructions.md")
831-
832-
// Ensure the .github/instructions directory exists
833-
if err := os.MkdirAll(copilotDir, 0755); err != nil {
834-
return fmt.Errorf("failed to create .github/instructions directory: %w", err)
835-
}
836-
837-
// Check if the instructions file already exists and matches the template
838-
existingContent := ""
839-
if content, err := os.ReadFile(copilotInstructionsPath); err == nil {
840-
existingContent = string(content)
841-
}
842-
843-
// Check if content matches our expected template
844-
expectedContent := strings.TrimSpace(copilotInstructionsTemplate)
845-
if strings.TrimSpace(existingContent) == expectedContent {
846-
if verbose {
847-
fmt.Printf("Copilot instructions are up-to-date: %s\n", copilotInstructionsPath)
848-
}
849-
return nil
850-
}
851-
852-
// Write the copilot instructions file
853-
if err := os.WriteFile(copilotInstructionsPath, []byte(copilotInstructionsTemplate), 0644); err != nil {
854-
return fmt.Errorf("failed to write copilot instructions: %w", err)
855-
}
856-
857-
if verbose {
858-
if existingContent == "" {
859-
fmt.Printf("Created copilot instructions: %s\n", copilotInstructionsPath)
860-
} else {
861-
fmt.Printf("Updated copilot instructions: %s\n", copilotInstructionsPath)
862-
}
863-
}
864-
865-
return nil
866-
}
867-
868-
// ensureAgenticWorkflowPrompt removes the old agentic workflow prompt file if it exists
869-
func ensureAgenticWorkflowPrompt(verbose bool, skipInstructions bool) error {
870-
// This function now removes the old prompt file since we've migrated to agent format
871-
if skipInstructions {
872-
return nil
873-
}
874-
875-
gitRoot, err := findGitRoot()
876-
if err != nil {
877-
return err // Not in a git repository, skip
878-
}
879-
880-
promptsDir := filepath.Join(gitRoot, ".github", "prompts")
881-
oldPromptPath := filepath.Join(promptsDir, "create-agentic-workflow.prompt.md")
882-
883-
// Check if the old prompt file exists and remove it
884-
if _, err := os.Stat(oldPromptPath); err == nil {
885-
if err := os.Remove(oldPromptPath); err != nil {
886-
return fmt.Errorf("failed to remove old prompt file: %w", err)
887-
}
888-
if verbose {
889-
fmt.Printf("Removed old prompt file: %s\n", oldPromptPath)
890-
}
891-
}
892-
893-
return nil
894-
}
895-
896-
// ensureAgenticWorkflowAgent ensures that .github/agents/create-agentic-workflow.md contains the agentic workflow creation agent
897-
func ensureAgenticWorkflowAgent(verbose bool, skipInstructions bool) error {
898-
return ensureAgentFromTemplate("create-agentic-workflow.md", agenticWorkflowAgentTemplate, verbose, skipInstructions)
899-
}
900-
901-
// ensureSharedAgenticWorkflowAgent ensures that .github/agents/create-shared-agentic-workflow.md contains the shared workflow creation agent
902-
func ensureSharedAgenticWorkflowAgent(verbose bool, skipInstructions bool) error {
903-
return ensureAgentFromTemplate("create-shared-agentic-workflow.md", sharedAgenticWorkflowAgentTemplate, verbose, skipInstructions)
904-
}
905-
906-
// ensureSetupAgenticWorkflowsAgent ensures that .github/agents/setup-agentic-workflows.md contains the setup guide agent
907-
func ensureSetupAgenticWorkflowsAgent(verbose bool, skipInstructions bool) error {
908-
return ensureAgentFromTemplate("setup-agentic-workflows.md", setupAgenticWorkflowsAgentTemplate, verbose, skipInstructions)
909-
}
910-
911-
// checkCleanWorkingDirectory checks if there are uncommitted changes
912-
func checkCleanWorkingDirectory(verbose bool) error {
913-
if verbose {
914-
fmt.Printf("Checking for uncommitted changes...\n")
915-
}
916-
917-
cmd := exec.Command("git", "status", "--porcelain")
918-
output, err := cmd.Output()
919-
if err != nil {
920-
return fmt.Errorf("failed to check git status: %w", err)
921-
}
922-
923-
if len(strings.TrimSpace(string(output))) > 0 {
924-
return fmt.Errorf("working directory has uncommitted changes, please commit or stash them first")
925-
}
926-
927-
if verbose {
928-
fmt.Printf("Working directory is clean\n")
929-
}
930-
return nil
931-
}
932-
933-
// createPR creates a pull request using GitHub CLI
934-
func createPR(branchName, title, body string, verbose bool) error {
935-
if verbose {
936-
fmt.Printf("Creating PR: %s\n", title)
937-
}
938-
939-
// Get the current repository info to ensure PR is created in the correct repo
940-
cmd := exec.Command("gh", "repo", "view", "--json", "owner,name")
941-
repoOutput, err := cmd.Output()
942-
if err != nil {
943-
return fmt.Errorf("failed to get current repository info: %w", err)
944-
}
945-
946-
var repoInfo struct {
947-
Owner struct {
948-
Login string `json:"login"`
949-
} `json:"owner"`
950-
Name string `json:"name"`
951-
}
952-
953-
if err := json.Unmarshal(repoOutput, &repoInfo); err != nil {
954-
return fmt.Errorf("failed to parse repository info: %w", err)
955-
}
956-
957-
repoSpec := fmt.Sprintf("%s/%s", repoInfo.Owner.Login, repoInfo.Name)
958-
959-
// Explicitly specify the repository to ensure PR is created in the current repo (not upstream)
960-
cmd = exec.Command("gh", "pr", "create", "--repo", repoSpec, "--title", title, "--body", body, "--head", branchName)
961-
output, err := cmd.Output()
962-
if err != nil {
963-
// Try to get stderr for better error reporting
964-
if exitError, ok := err.(*exec.ExitError); ok {
965-
return fmt.Errorf("failed to create PR: %w\nOutput: %s\nError: %s", err, string(output), string(exitError.Stderr))
966-
}
967-
return fmt.Errorf("failed to create PR: %w", err)
968-
}
969-
970-
prURL := strings.TrimSpace(string(output))
971-
fmt.Printf("📢 Pull Request created: %s\n", prURL)
972-
973-
return nil
974-
}
975-
976816
// addSourceToWorkflow adds the source field to the workflow's frontmatter
977817
func addSourceToWorkflow(content, source string) (string, error) {
978818
// Use shared frontmatter logic that preserves formatting

pkg/cli/copilot-agents.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,96 @@ func ensureAgentFromTemplate(agentFileName, templateContent string, verbose bool
5656

5757
return nil
5858
}
59+
60+
// ensureCopilotInstructions ensures that .github/instructions/github-agentic-workflows.md contains the copilot instructions
61+
func ensureCopilotInstructions(verbose bool, skipInstructions bool) error {
62+
if skipInstructions {
63+
return nil // Skip writing instructions if flag is set
64+
}
65+
66+
gitRoot, err := findGitRoot()
67+
if err != nil {
68+
return err // Not in a git repository, skip
69+
}
70+
71+
copilotDir := filepath.Join(gitRoot, ".github", "instructions")
72+
copilotInstructionsPath := filepath.Join(copilotDir, "github-agentic-workflows.instructions.md")
73+
74+
// Ensure the .github/instructions directory exists
75+
if err := os.MkdirAll(copilotDir, 0755); err != nil {
76+
return fmt.Errorf("failed to create .github/instructions directory: %w", err)
77+
}
78+
79+
// Check if the instructions file already exists and matches the template
80+
existingContent := ""
81+
if content, err := os.ReadFile(copilotInstructionsPath); err == nil {
82+
existingContent = string(content)
83+
}
84+
85+
// Check if content matches our expected template
86+
expectedContent := strings.TrimSpace(copilotInstructionsTemplate)
87+
if strings.TrimSpace(existingContent) == expectedContent {
88+
if verbose {
89+
fmt.Printf("Copilot instructions are up-to-date: %s\n", copilotInstructionsPath)
90+
}
91+
return nil
92+
}
93+
94+
// Write the copilot instructions file
95+
if err := os.WriteFile(copilotInstructionsPath, []byte(copilotInstructionsTemplate), 0644); err != nil {
96+
return fmt.Errorf("failed to write copilot instructions: %w", err)
97+
}
98+
99+
if verbose {
100+
if existingContent == "" {
101+
fmt.Printf("Created copilot instructions: %s\n", copilotInstructionsPath)
102+
} else {
103+
fmt.Printf("Updated copilot instructions: %s\n", copilotInstructionsPath)
104+
}
105+
}
106+
107+
return nil
108+
}
109+
110+
// ensureAgenticWorkflowPrompt removes the old agentic workflow prompt file if it exists
111+
func ensureAgenticWorkflowPrompt(verbose bool, skipInstructions bool) error {
112+
// This function now removes the old prompt file since we've migrated to agent format
113+
if skipInstructions {
114+
return nil
115+
}
116+
117+
gitRoot, err := findGitRoot()
118+
if err != nil {
119+
return err // Not in a git repository, skip
120+
}
121+
122+
promptsDir := filepath.Join(gitRoot, ".github", "prompts")
123+
oldPromptPath := filepath.Join(promptsDir, "create-agentic-workflow.prompt.md")
124+
125+
// Check if the old prompt file exists and remove it
126+
if _, err := os.Stat(oldPromptPath); err == nil {
127+
if err := os.Remove(oldPromptPath); err != nil {
128+
return fmt.Errorf("failed to remove old prompt file: %w", err)
129+
}
130+
if verbose {
131+
fmt.Printf("Removed old prompt file: %s\n", oldPromptPath)
132+
}
133+
}
134+
135+
return nil
136+
}
137+
138+
// ensureAgenticWorkflowAgent ensures that .github/agents/create-agentic-workflow.md contains the agentic workflow creation agent
139+
func ensureAgenticWorkflowAgent(verbose bool, skipInstructions bool) error {
140+
return ensureAgentFromTemplate("create-agentic-workflow.md", agenticWorkflowAgentTemplate, verbose, skipInstructions)
141+
}
142+
143+
// ensureSharedAgenticWorkflowAgent ensures that .github/agents/create-shared-agentic-workflow.md contains the shared workflow creation agent
144+
func ensureSharedAgenticWorkflowAgent(verbose bool, skipInstructions bool) error {
145+
return ensureAgentFromTemplate("create-shared-agentic-workflow.md", sharedAgenticWorkflowAgentTemplate, verbose, skipInstructions)
146+
}
147+
148+
// ensureSetupAgenticWorkflowsAgent ensures that .github/agents/setup-agentic-workflows.md contains the setup guide agent
149+
func ensureSetupAgenticWorkflowsAgent(verbose bool, skipInstructions bool) error {
150+
return ensureAgentFromTemplate("setup-agentic-workflows.md", setupAgenticWorkflowsAgentTemplate, verbose, skipInstructions)
151+
}

pkg/cli/git.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,25 @@ func pushBranch(branchName string, verbose bool) error {
188188

189189
return nil
190190
}
191+
192+
// checkCleanWorkingDirectory checks if there are uncommitted changes
193+
func checkCleanWorkingDirectory(verbose bool) error {
194+
if verbose {
195+
fmt.Printf("Checking for uncommitted changes...\n")
196+
}
197+
198+
cmd := exec.Command("git", "status", "--porcelain")
199+
output, err := cmd.Output()
200+
if err != nil {
201+
return fmt.Errorf("failed to check git status: %w", err)
202+
}
203+
204+
if len(strings.TrimSpace(string(output))) > 0 {
205+
return fmt.Errorf("working directory has uncommitted changes, please commit or stash them first")
206+
}
207+
208+
if verbose {
209+
fmt.Printf("Working directory is clean\n")
210+
}
211+
return nil
212+
}

pkg/cli/pr_command.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,3 +739,46 @@ func transferPR(prURL, targetRepo string, verbose bool) error {
739739

740740
return nil
741741
}
742+
743+
// createPR creates a pull request using GitHub CLI
744+
func createPR(branchName, title, body string, verbose bool) error {
745+
if verbose {
746+
fmt.Printf("Creating PR: %s\n", title)
747+
}
748+
749+
// Get the current repository info to ensure PR is created in the correct repo
750+
cmd := exec.Command("gh", "repo", "view", "--json", "owner,name")
751+
repoOutput, err := cmd.Output()
752+
if err != nil {
753+
return fmt.Errorf("failed to get current repository info: %w", err)
754+
}
755+
756+
var repoInfo struct {
757+
Owner struct {
758+
Login string `json:"login"`
759+
} `json:"owner"`
760+
Name string `json:"name"`
761+
}
762+
763+
if err := json.Unmarshal(repoOutput, &repoInfo); err != nil {
764+
return fmt.Errorf("failed to parse repository info: %w", err)
765+
}
766+
767+
repoSpec := fmt.Sprintf("%s/%s", repoInfo.Owner.Login, repoInfo.Name)
768+
769+
// Explicitly specify the repository to ensure PR is created in the current repo (not upstream)
770+
cmd = exec.Command("gh", "pr", "create", "--repo", repoSpec, "--title", title, "--body", body, "--head", branchName)
771+
output, err := cmd.Output()
772+
if err != nil {
773+
// Try to get stderr for better error reporting
774+
if exitError, ok := err.(*exec.ExitError); ok {
775+
return fmt.Errorf("failed to create PR: %w\nOutput: %s\nError: %s", err, string(output), string(exitError.Stderr))
776+
}
777+
return fmt.Errorf("failed to create PR: %w", err)
778+
}
779+
780+
prURL := strings.TrimSpace(string(output))
781+
fmt.Printf("📢 Pull Request created: %s\n", prURL)
782+
783+
return nil
784+
}

0 commit comments

Comments
 (0)