Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 58 additions & 6 deletions pkg/cli/run_input_validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,12 @@ jobs:

func TestValidateWorkflowInputs(t *testing.T) {
tests := []struct {
name string
lockContent string
providedInputs []string
expectError bool
errorContains []string // strings that should be in the error message
name string
lockContent string
providedInputs []string
expectError bool
errorContains []string // strings that should be in the error message
errorNotContains []string // strings that should NOT be in the error message
}{
{
name: "all required inputs provided",
Expand Down Expand Up @@ -159,7 +160,53 @@ jobs:
`,
providedInputs: []string{},
expectError: true,
errorContains: []string{"Missing required input(s)", "issue_url"},
errorContains: []string{"Missing required input(s)", "issue_url", "gh aw run test-workflow -F issue_url=<value>"},
},
{
name: "required input with default value - should not error when missing",
lockContent: `name: "Test Workflow"
on:
workflow_dispatch:
inputs:
release_type:
description: 'Release type'
required: true
default: patch
type: string
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo "test"
`,
providedInputs: []string{},
expectError: false,
},
{
name: "required input with default shown in valid inputs list",
lockContent: `name: "Test Workflow"
on:
workflow_dispatch:
inputs:
missing_required:
description: 'Must be set'
required: true
type: string
defaulted:
description: 'Has a default'
required: true
default: patch
type: string
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo "test"
`,
providedInputs: []string{},
expectError: true,
errorContains: []string{"Missing required input(s)", "missing_required", "default: patch"},
errorNotContains: []string{"gh aw run test-workflow -F defaulted=<value>"},
},
Comment on lines +185 to 210
{
name: "typo in input name",
Expand Down Expand Up @@ -290,6 +337,11 @@ jobs:
t.Errorf("Expected error to contain '%s', but got: %s", expected, errStr)
}
}
for _, notExpected := range tt.errorNotContains {
if strings.Contains(errStr, notExpected) {
t.Errorf("Expected error NOT to contain '%s', but got: %s", notExpected, errStr)
}
}
}
} else {
if err != nil {
Expand Down
33 changes: 27 additions & 6 deletions pkg/cli/run_workflow_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,10 @@ func validateWorkflowInputs(markdownPath string, providedInputs []string) error
}
}

// Check for required inputs that are missing
// Check for required inputs that are missing (ignore inputs with a default value)
var missingInputs []string
for inputName, inputDef := range workflowInputs {
if inputDef.Required {
if inputDef.Required && inputDef.Default == nil {
if _, exists := providedInputsMap[inputName]; !exists {
missingInputs = append(missingInputs, inputName)
}
Expand Down Expand Up @@ -231,18 +231,39 @@ func validateWorkflowInputs(markdownPath string, providedInputs []string) error
// Add helpful information about valid inputs
if len(workflowInputs) > 0 {
var inputDescriptions []string
for name, def := range workflowInputs {
sortedNames := slices.Sorted(maps.Keys(workflowInputs))
for _, name := range sortedNames {
def := workflowInputs[name]
required := ""
if def.Required {
if def.Required && def.Default == nil {
required = " (required)"
}
desc := ""
if def.Description != "" {
desc = ": " + def.Description
}
inputDescriptions = append(inputDescriptions, fmt.Sprintf(" %s%s%s", name, required, desc))
defaultStr := ""
if def.Default != nil {
defaultStr = fmt.Sprintf(" [default: %s]", def.GetDefaultAsString())
}
inputDescriptions = append(inputDescriptions, fmt.Sprintf(" %s%s%s%s", name, required, desc, defaultStr))
}

// Derive the workflow name for the syntax hint
workflowName := strings.TrimSuffix(filepath.Base(markdownPath), ".md")
var syntaxExamples []string
for _, name := range sortedNames {
def := workflowInputs[name]
if def.Required && def.Default == nil {
syntaxExamples = append(syntaxExamples, fmt.Sprintf(" gh aw run %s -F %s=<value>", workflowName, name))
}
}

validInputsMsg := "\nValid inputs:\n" + strings.Join(inputDescriptions, "\n")
if len(syntaxExamples) > 0 {
validInputsMsg += "\n\nTo set required inputs, use:\n" + strings.Join(syntaxExamples, "\n")
}
Comment on lines +252 to 265
errorParts = append(errorParts, "\nValid inputs:\n"+strings.Join(inputDescriptions, "\n"))
errorParts = append(errorParts, validInputsMsg)
}

return fmt.Errorf("%s", strings.Join(errorParts, "\n\n"))
Expand Down
Loading