feat: modified choice input to take option list opposed to blank text (#8180)

This commit is contained in:
Adarsh Jha 2023-10-31 22:18:49 +05:30 committed by GitHub
parent ede1705bf2
commit 351c5f1cd5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 151 additions and 2 deletions

View file

@ -217,7 +217,18 @@ func collectInputs(p iprompter, yamlContent []byte) (map[string]string, error) {
for _, input := range inputs {
var answer string
if input.Required {
if input.Type == "choice" {
name := input.Name
if input.Required {
name += " (required)"
}
selected, err := p.Select(name, input.Default, input.Options)
if err != nil {
return nil, err
}
answer = input.Options[selected]
} else if input.Required {
for answer == "" {
answer, err = p.Input(input.Name+" (required)", input.Default)
if err != nil {
@ -234,7 +245,6 @@ func collectInputs(p iprompter, yamlContent []byte) (map[string]string, error) {
providedInputs[input.Name] = answer
}
return providedInputs, nil
}
@ -331,6 +341,8 @@ type WorkflowInput struct {
Required bool
Default string
Description string
Type string
Options []string
}
func findInputs(yamlContent []byte) ([]WorkflowInput, error) {
@ -412,11 +424,16 @@ func findInputs(yamlContent []byte) ([]WorkflowInput, error) {
}
for name, input := range m {
if input.Type == "choice" && len(input.Options) == 0 {
return nil, fmt.Errorf("workflow input %q is of type choice, but has no options", name)
}
out = append(out, WorkflowInput{
Name: name,
Default: input.Default,
Description: input.Description,
Required: input.Required,
Options: input.Options,
Type: input.Type,
})
}

View file

@ -350,6 +350,50 @@ jobs:
encodedYAMLContent := base64.StdEncoding.EncodeToString(yamlContent)
yamlContentChoiceIp := []byte(`
name: choice inputs
on:
workflow_dispatch:
inputs:
name:
type: choice
description: Who to greet
default: monalisa
options:
- monalisa
- cschleiden
favourite-animal:
type: choice
description: What's your favourite animal
required: true
options:
- dog
- cat
jobs:
greet:
runs-on: ubuntu-latest
steps:
- name: Send greeting
run: echo "${{ github.event.inputs.message }} ${{ fromJSON('["", "🥳"]')[github.event.inputs.use-emoji == 'true'] }} ${{ github.event.inputs.name }}"`)
encodedYAMLContentChoiceIp := base64.StdEncoding.EncodeToString(yamlContentChoiceIp)
yamlContentMissingChoiceIp := []byte(`
name: choice missing inputs
on:
workflow_dispatch:
inputs:
name:
type: choice
description: Who to greet
options:
jobs:
greet:
runs-on: ubuntu-latest
steps:
- name: Send greeting
run: echo "${{ github.event.inputs.message }} ${{ fromJSON('["", "🥳"]')[github.event.inputs.use-emoji == 'true'] }} ${{ github.event.inputs.name }}"`)
encodedYAMLContentMissingChoiceIp := base64.StdEncoding.EncodeToString(yamlContentMissingChoiceIp)
stubs := func(reg *httpmock.Registry) {
reg.Register(
httpmock.REST("GET", "repos/OWNER/REPO/actions/workflows/workflow.yml"),
@ -640,6 +684,94 @@ jobs:
},
wantOut: "✓ Created workflow_dispatch event for workflow.yml at trunk\n\nTo see runs for this workflow, try: gh run list --workflow=workflow.yml\n",
},
{
name: "prompt, workflow choice input",
tty: true,
opts: &RunOptions{
Prompt: true,
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(
httpmock.REST("GET", "repos/OWNER/REPO/actions/workflows"),
httpmock.JSONResponse(shared.WorkflowsPayload{
Workflows: []shared.Workflow{
{
Name: "choice inputs",
ID: 12345,
State: shared.Active,
Path: ".github/workflows/workflow.yml",
},
},
}))
reg.Register(
httpmock.REST("GET", "repos/OWNER/REPO/contents/.github/workflows/workflow.yml"),
httpmock.JSONResponse(struct{ Content string }{
Content: encodedYAMLContentChoiceIp,
}))
reg.Register(
httpmock.REST("POST", "repos/OWNER/REPO/actions/workflows/12345/dispatches"),
httpmock.StatusStringResponse(204, "cool"))
},
promptStubs: func(pm *prompter.MockPrompter) {
pm.RegisterSelect("Select a workflow", []string{"choice inputs (workflow.yml)"}, func(_, _ string, opts []string) (int, error) {
return 0, nil
})
pm.RegisterSelect("favourite-animal (required)", []string{"dog", "cat"}, func(_, _ string, opts []string) (int, error) {
return 0, nil
})
pm.RegisterSelect("name", []string{"monalisa", "cschleiden"}, func(_, _ string, opts []string) (int, error) {
return 0, nil
})
},
wantBody: map[string]interface{}{
"inputs": map[string]interface{}{
"name": "monalisa",
"favourite-animal": "dog",
},
"ref": "trunk",
},
wantOut: "✓ Created workflow_dispatch event for workflow.yml at trunk\n\nTo see runs for this workflow, try: gh run list --workflow=workflow.yml\n",
},
{
name: "prompt, workflow choice missing input",
tty: true,
opts: &RunOptions{
Prompt: true,
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(
httpmock.REST("GET", "repos/OWNER/REPO/actions/workflows"),
httpmock.JSONResponse(shared.WorkflowsPayload{
Workflows: []shared.Workflow{
{
Name: "choice missing inputs",
ID: 12345,
State: shared.Active,
Path: ".github/workflows/workflow.yml",
},
},
}))
reg.Register(
httpmock.REST("GET", "repos/OWNER/REPO/contents/.github/workflows/workflow.yml"),
httpmock.JSONResponse(struct{ Content string }{
Content: encodedYAMLContentMissingChoiceIp,
}))
reg.Register(
httpmock.REST("POST", "repos/OWNER/REPO/actions/workflows/12345/dispatches"),
httpmock.StatusStringResponse(204, "cool"))
},
promptStubs: func(pm *prompter.MockPrompter) {
pm.RegisterSelect("Select a workflow", []string{"choice missing inputs (workflow.yml)"}, func(_, _ string, opts []string) (int, error) {
return 0, nil
})
pm.RegisterSelect("name", []string{}, func(_, _ string, opts []string) (int, error) {
return 0, nil
})
},
wantErr: true,
errOut: "workflow input \"name\" is of type choice, but has no options",
},
}
for _, tt := range tests {