diff --git a/cmd/gh-aw/main.go b/cmd/gh-aw/main.go index cc5873f038..c27834153a 100644 --- a/cmd/gh-aw/main.go +++ b/cmd/gh-aw/main.go @@ -49,7 +49,7 @@ For detailed help on any command, use: } var newCmd = &cobra.Command{ - Use: "new [workflow-base-name]", + Use: "new [workflow-id]", Short: "Create a new workflow Markdown file with example configuration", Long: `Create a new workflow Markdown file with commented examples and explanations of all available options. @@ -63,10 +63,14 @@ When called with a workflow name, creates a template file with comprehensive exa - Tools configuration (github, claude, mcps) - All frontmatter options with explanations +The workflow-id is the basename of the markdown file without the .md extension. +You can provide either the workflow-id (e.g., 'my-workflow') or the full filename (e.g., 'my-workflow.md'). + Examples: ` + constants.CLIExtensionPrefix + ` new # Interactive mode ` + constants.CLIExtensionPrefix + ` new --interactive # Interactive mode (explicit) ` + constants.CLIExtensionPrefix + ` new my-workflow # Create template file + ` + constants.CLIExtensionPrefix + ` new my-workflow.md # Create template file (alternative format) ` + constants.CLIExtensionPrefix + ` new issue-handler --force`, Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { @@ -105,8 +109,16 @@ Examples: } var removeCmd = &cobra.Command{ - Use: "remove [pattern]", + Use: "remove [workflow-id-pattern]", Short: "Remove workflow files matching the given name prefix", + Long: `Remove workflow files matching the given workflow-id pattern. + +The workflow-id is the basename of the markdown file without the .md extension. +You can provide a workflow-id prefix to remove multiple workflows, or a specific workflow-id. + +Examples: + ` + constants.CLIExtensionPrefix + ` remove my-workflow # Remove specific workflow + ` + constants.CLIExtensionPrefix + ` remove test- # Remove all workflows starting with 'test-'`, Run: func(cmd *cobra.Command, args []string) { var pattern string if len(args) > 0 { @@ -125,9 +137,13 @@ var enableCmd = &cobra.Command{ Short: "Enable agentic workflows", Long: `Enable one or more workflows by ID, or all workflows if no IDs are provided. +The workflow-id is the basename of the markdown file without the .md extension. +You can provide either the workflow-id (e.g., 'ci-doctor') or the full filename (e.g., 'ci-doctor.md'). + Examples: ` + constants.CLIExtensionPrefix + ` enable # Enable all workflows ` + constants.CLIExtensionPrefix + ` enable ci-doctor # Enable specific workflow + ` + constants.CLIExtensionPrefix + ` enable ci-doctor.md # Enable specific workflow (alternative format) ` + constants.CLIExtensionPrefix + ` enable ci-doctor daily # Enable multiple workflows ` + constants.CLIExtensionPrefix + ` enable ci-doctor --repo owner/repo # Enable workflow in specific repository`, Run: func(cmd *cobra.Command, args []string) { @@ -144,9 +160,13 @@ var disableCmd = &cobra.Command{ Short: "Disable agentic workflows and cancel any in-progress runs", Long: `Disable one or more workflows by ID, or all workflows if no IDs are provided. +The workflow-id is the basename of the markdown file without the .md extension. +You can provide either the workflow-id (e.g., 'ci-doctor') or the full filename (e.g., 'ci-doctor.md'). + Examples: ` + constants.CLIExtensionPrefix + ` disable # Disable all workflows ` + constants.CLIExtensionPrefix + ` disable ci-doctor # Disable specific workflow + ` + constants.CLIExtensionPrefix + ` disable ci-doctor.md # Disable specific workflow (alternative format) ` + constants.CLIExtensionPrefix + ` disable ci-doctor daily # Disable multiple workflows ` + constants.CLIExtensionPrefix + ` disable ci-doctor --repo owner/repo # Disable workflow in specific repository`, Run: func(cmd *cobra.Command, args []string) { @@ -262,8 +282,12 @@ The workflows must have been added as actions and compiled. This command only works with workflows that have workflow_dispatch triggers. It executes 'gh workflow run ' to trigger each workflow on GitHub Actions. +The workflow-id is the basename of the markdown file without the .md extension. +You can provide either the workflow-id (e.g., 'daily-perf-improver') or the full filename (e.g., 'daily-perf-improver.md'). + Examples: gh aw run daily-perf-improver + gh aw run daily-perf-improver.md # Alternative format gh aw run daily-perf-improver --repeat 3 # Run 3 times total gh aw run daily-perf-improver --enable-if-needed # Enable if disabled, run, then restore state gh aw run daily-perf-improver --auto-merge-prs # Auto-merge any PRs created during execution`, diff --git a/pkg/cli/commands.go b/pkg/cli/commands.go index c7c3cc1256..5912f7d6d3 100644 --- a/pkg/cli/commands.go +++ b/pkg/cli/commands.go @@ -106,6 +106,11 @@ func resolveWorkflowFile(fileOrWorkflowName string, verbose bool) (string, error func NewWorkflow(workflowName string, verbose bool, force bool) error { commandsLog.Printf("Creating new workflow: name=%s, force=%v", workflowName, force) + // Normalize the workflow name by removing .md extension if present + // This ensures consistent behavior whether user provides "my-workflow" or "my-workflow.md" + workflowName = strings.TrimSuffix(workflowName, ".md") + commandsLog.Printf("Normalized workflow name: %s", workflowName) + if verbose { fmt.Printf("Creating new workflow: %s\n", workflowName) } diff --git a/pkg/cli/commands_test.go b/pkg/cli/commands_test.go index 029e8c2b10..4ad1be30d5 100644 --- a/pkg/cli/commands_test.go +++ b/pkg/cli/commands_test.go @@ -569,6 +569,12 @@ func TestNewWorkflow(t *testing.T) { } }, }, + { + name: "create workflow with .md extension (should normalize)", + workflowName: "test-with-ext.md", + force: false, + expectedError: false, + }, } for _, test := range tests { @@ -590,7 +596,9 @@ func TestNewWorkflow(t *testing.T) { // If no error expected, verify the file was created if !test.expectedError { - filePath := ".github/workflows/" + test.workflowName + ".md" + // Normalize the workflow name for file path (remove .md if present) + normalizedName := strings.TrimSuffix(test.workflowName, ".md") + filePath := ".github/workflows/" + normalizedName + ".md" if _, err := os.Stat(filePath); os.IsNotExist(err) { t.Errorf("Expected workflow file was not created: %s", filePath) } @@ -607,7 +615,7 @@ func TestNewWorkflow(t *testing.T) { "on:", "permissions:", "safe-outputs:", - "# " + test.workflowName, + "# " + normalizedName, "workflow_dispatch:", } for _, element := range expectedElements { diff --git a/pkg/cli/logs.go b/pkg/cli/logs.go index 52ff64d572..027193272c 100644 --- a/pkg/cli/logs.go +++ b/pkg/cli/logs.go @@ -312,11 +312,12 @@ Downloaded artifacts include: - workflow-logs/: GitHub Actions workflow run logs (job logs organized in subdirectory) The workflow-id is the basename of the markdown file without the .md extension. -For example, for 'weekly-research.md', use 'weekly-research' as the workflow ID. +You can provide either the workflow-id (e.g., 'weekly-research') or the full filename (e.g., 'weekly-research.md'). Examples: ` + constants.CLIExtensionPrefix + ` logs # Download logs for all workflows ` + constants.CLIExtensionPrefix + ` logs weekly-research # Download logs for specific workflow + ` + constants.CLIExtensionPrefix + ` logs weekly-research.md # Download logs (alternative format) ` + constants.CLIExtensionPrefix + ` logs -c 10 # Download last 10 matching runs ` + constants.CLIExtensionPrefix + ` logs --start-date 2024-01-01 # Download all runs after date ` + constants.CLIExtensionPrefix + ` logs --end-date 2024-01-31 # Download all runs before date diff --git a/pkg/cli/update_command.go b/pkg/cli/update_command.go index a899dc67c5..0c1d25ab35 100644 --- a/pkg/cli/update_command.go +++ b/pkg/cli/update_command.go @@ -35,9 +35,13 @@ For workflow updates, it fetches the latest version based on the current ref: - If the ref is a branch, it fetches the latest commit from that branch - Otherwise, it fetches the latest commit from the default branch +The workflow-id is the basename of the markdown file without the .md extension. +You can provide either the workflow-id (e.g., 'ci-doctor') or the full filename (e.g., 'ci-doctor.md'). + Examples: ` + constants.CLIExtensionPrefix + ` update # Check gh-aw updates and update all workflows ` + constants.CLIExtensionPrefix + ` update ci-doctor # Check gh-aw updates and update specific workflow + ` + constants.CLIExtensionPrefix + ` update ci-doctor.md # Check gh-aw updates and update specific workflow (alternative format) ` + constants.CLIExtensionPrefix + ` update ci-doctor --major # Allow major version updates ` + constants.CLIExtensionPrefix + ` update --pr # Create PR with changes ` + constants.CLIExtensionPrefix + ` update --force # Force update even if no changes