-
Notifications
You must be signed in to change notification settings - Fork 29
List workflows when only repo name provided to add command #3373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| package cli | ||
|
|
||
| import ( | ||
| "os" | ||
| "testing" | ||
| ) | ||
|
|
||
| func TestIsRepoOnlySpec(t *testing.T) { | ||
| tests := []struct { | ||
| name string | ||
| spec string | ||
| expected bool | ||
| }{ | ||
| { | ||
| name: "repo only without version", | ||
| spec: "githubnext/agentics", | ||
| expected: true, | ||
| }, | ||
| { | ||
| name: "repo only with version", | ||
| spec: "githubnext/agentics@v1.0.0", | ||
| expected: true, | ||
| }, | ||
| { | ||
| name: "full spec with workflow", | ||
| spec: "githubnext/agentics/ci-doctor", | ||
| expected: false, | ||
| }, | ||
| { | ||
| name: "full spec with workflow and version", | ||
| spec: "githubnext/agentics/ci-doctor@main", | ||
| expected: false, | ||
| }, | ||
| { | ||
| name: "full spec with path", | ||
| spec: "githubnext/agentics/workflows/ci-doctor.md", | ||
| expected: false, | ||
| }, | ||
| { | ||
| name: "GitHub URL", | ||
| spec: "https://github.com/githubnext/agentics/blob/main/workflows/ci-doctor.md", | ||
| expected: false, | ||
| }, | ||
| { | ||
| name: "local path", | ||
| spec: "./workflows/my-workflow.md", | ||
| expected: false, | ||
| }, | ||
| } | ||
|
|
||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| result := isRepoOnlySpec(tt.spec) | ||
| if result != tt.expected { | ||
| t.Errorf("isRepoOnlySpec(%q) = %v, want %v", tt.spec, result, tt.expected) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| func TestListWorkflowsInPackage(t *testing.T) { | ||
| // Since we can't easily mock getPackagesDir, we'll just verify the function | ||
| // handles missing packages correctly | ||
| workflows, err := listWorkflowsInPackage("absolutely-nonexistent-repo-xyz123/test-repo-abc456", false) | ||
| if err == nil { | ||
| t.Errorf("Expected error for nonexistent package, got nil. Workflows: %v", workflows) | ||
| } | ||
| } | ||
|
|
||
| func TestHandleRepoOnlySpecIntegration(t *testing.T) { | ||
| // This is more of an integration test that would require GitHub authentication | ||
| // We'll skip it in normal test runs | ||
| if os.Getenv("GITHUB_TOKEN") == "" && os.Getenv("GH_TOKEN") == "" { | ||
| t.Skip("Skipping integration test: no GitHub token available") | ||
| } | ||
|
|
||
| // Test with verbose output to see the workflow listing | ||
| // Note: This will actually try to install the package | ||
| // err := handleRepoOnlySpec("githubnext/agentics", true) | ||
| // For now, we'll just verify the function exists and can be called | ||
| // without testing the actual GitHub interaction | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -243,6 +243,67 @@ type WorkflowSourceInfo struct { | |||||||||||||||||||||||||||
| CommitSHA string // The actual commit SHA used when the package was installed | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // listWorkflowsInPackage lists all available workflows in an installed package | ||||||||||||||||||||||||||||
| func listWorkflowsInPackage(repoSlug string, verbose bool) ([]string, error) { | ||||||||||||||||||||||||||||
| packagesLog.Printf("Listing workflows in package: %s", repoSlug) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| packagesDir, err := getPackagesDir() | ||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||
| return nil, fmt.Errorf("failed to get packages directory: %w", err) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| packagePath := filepath.Join(packagesDir, repoSlug) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Check if package exists | ||||||||||||||||||||||||||||
| if _, err := os.Stat(packagePath); os.IsNotExist(err) { | ||||||||||||||||||||||||||||
| return nil, fmt.Errorf("package not found: %s", repoSlug) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| var workflows []string | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Walk through the package directory to find all .md files | ||||||||||||||||||||||||||||
| err = filepath.Walk(packagePath, func(path string, info os.FileInfo, err error) error { | ||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||
| return err | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Skip directories and non-markdown files | ||||||||||||||||||||||||||||
| if info.IsDir() || !strings.HasSuffix(info.Name(), ".md") { | ||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Skip metadata files | ||||||||||||||||||||||||||||
| if info.Name() == ".commit-sha" { | ||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
Comment on lines
+275
to
+279
|
||||||||||||||||||||||||||||
| // Skip metadata files | |
| if info.Name() == ".commit-sha" { | |
| return nil | |
| } |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable workflowName is computed but never used in a meaningful way. It's only printed in verbose mode (line 293) but doesn't contribute to the function's output. Consider removing this variable or documenting why it's kept for debugging purposes only.
| // Extract workflow name (remove .md extension) | |
| workflowName := strings.TrimSuffix(filepath.Base(path), ".md") | |
| // Add to list with relative path information | |
| workflows = append(workflows, relPath) | |
| if verbose { | |
| fmt.Printf("Found workflow: %s (name: %s)\n", relPath, workflowName) | |
| // Add to list with relative path information | |
| workflows = append(workflows, relPath) | |
| if verbose { | |
| fmt.Printf("Found workflow: %s\n", relPath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The label should be plural 'Examples:' to match the pattern used elsewhere in the codebase (see line 28), or keep it singular but add a colon for consistency.