Skip to content

Commit ab38164

Browse files
committed
Add parsing for workflow dispatch (#118)
Reviewed-on: https://gitea.com/gitea/act/pulls/118
1 parent 38e7e9e commit ab38164

File tree

2 files changed

+127
-7
lines changed

2 files changed

+127
-7
lines changed

pkg/jobparser/model.go

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,20 @@ type RunDefaults struct {
172172
WorkingDirectory string `yaml:"working-directory,omitempty"`
173173
}
174174

175+
type WorkflowDispatchInput struct {
176+
Name string `yaml:"name"`
177+
Description string `yaml:"description"`
178+
Required bool `yaml:"required"`
179+
Default string `yaml:"default"`
180+
Type string `yaml:"type"`
181+
Options []string `yaml:"options"`
182+
}
183+
175184
type Event struct {
176185
Name string
177186
acts map[string][]string
178187
schedules []map[string]string
188+
inputs []WorkflowDispatchInput
179189
}
180190

181191
func (evt *Event) IsSchedule() bool {
@@ -190,6 +200,47 @@ func (evt *Event) Schedules() []map[string]string {
190200
return evt.schedules
191201
}
192202

203+
func (evt *Event) Inputs() []WorkflowDispatchInput {
204+
return evt.inputs
205+
}
206+
207+
func parseWorkflowDispatchInputs(inputs map[string]interface{}) ([]WorkflowDispatchInput, error) {
208+
var results []WorkflowDispatchInput
209+
for name, input := range inputs {
210+
inputMap, ok := input.(map[string]interface{})
211+
if !ok {
212+
return nil, fmt.Errorf("invalid input: %v", input)
213+
}
214+
input := WorkflowDispatchInput{
215+
Name: name,
216+
}
217+
if desc, ok := inputMap["description"].(string); ok {
218+
input.Description = desc
219+
}
220+
if required, ok := inputMap["required"].(bool); ok {
221+
input.Required = required
222+
}
223+
if defaultVal, ok := inputMap["default"].(string); ok {
224+
input.Default = defaultVal
225+
}
226+
if inputType, ok := inputMap["type"].(string); ok {
227+
input.Type = inputType
228+
}
229+
if options, ok := inputMap["options"].([]string); ok {
230+
input.Options = options
231+
} else if options, ok := inputMap["options"].([]interface{}); ok {
232+
for _, option := range options {
233+
if opt, ok := option.(string); ok {
234+
input.Options = append(input.Options, opt)
235+
}
236+
}
237+
}
238+
239+
results = append(results, input)
240+
}
241+
return results, nil
242+
}
243+
193244
func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
194245
switch rawOn.Kind {
195246
case yaml.ScalarNode:
@@ -228,23 +279,21 @@ func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
228279
if v == nil {
229280
res = append(res, &Event{
230281
Name: k,
231-
acts: map[string][]string{},
232282
})
233283
continue
234284
}
235285
switch t := v.(type) {
236286
case string:
237287
res = append(res, &Event{
238288
Name: k,
239-
acts: map[string][]string{},
240289
})
241290
case []string:
242291
res = append(res, &Event{
243292
Name: k,
244-
acts: map[string][]string{},
245293
})
246294
case map[string]interface{}:
247295
acts := make(map[string][]string, len(t))
296+
var inputs []WorkflowDispatchInput
248297
for act, branches := range t {
249298
switch b := branches.(type) {
250299
case string:
@@ -259,13 +308,28 @@ func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
259308
return nil, fmt.Errorf("unknown on type: %#v", branches)
260309
}
261310
}
311+
case map[string]interface{}:
312+
if k != "workflow_dispatch" && act != "inputs" {
313+
return nil, fmt.Errorf("unknown on type: %#v", branches)
314+
}
315+
inputs, err = parseWorkflowDispatchInputs(b)
316+
if err != nil {
317+
return nil, err
318+
}
262319
default:
263320
return nil, fmt.Errorf("unknown on type: %#v", branches)
264321
}
265322
}
323+
if len(inputs) == 0 {
324+
inputs = nil
325+
}
326+
if len(acts) == 0 {
327+
acts = nil
328+
}
266329
res = append(res, &Event{
267-
Name: k,
268-
acts: acts,
330+
Name: k,
331+
acts: acts,
332+
inputs: inputs,
269333
})
270334
case []interface{}:
271335
if k != "schedule" {
@@ -285,6 +349,9 @@ func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
285349
}
286350
}
287351
}
352+
if len(schedules) == 0 {
353+
schedules = nil
354+
}
288355
res = append(res, &Event{
289356
Name: k,
290357
schedules: schedules,

pkg/jobparser/model_test.go

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,60 @@ func TestParseRawOn(t *testing.T) {
186186
},
187187
},
188188
},
189+
{
190+
input: `on:
191+
workflow_dispatch:
192+
inputs:
193+
logLevel:
194+
description: 'Log level'
195+
required: true
196+
default: 'warning'
197+
type: choice
198+
options:
199+
- info
200+
- warning
201+
- debug
202+
tags:
203+
description: 'Test scenario tags'
204+
required: false
205+
type: boolean
206+
environment:
207+
description: 'Environment to run tests against'
208+
type: environment
209+
required: true
210+
push:
211+
`,
212+
result: []*Event{
213+
{
214+
Name: "workflow_dispatch",
215+
inputs: []WorkflowDispatchInput{
216+
{
217+
Name: "logLevel",
218+
Description: "Log level",
219+
Required: true,
220+
Default: "warning",
221+
Type: "choice",
222+
Options: []string{"info", "warning", "debug"},
223+
},
224+
{
225+
Name: "tags",
226+
Description: "Test scenario tags",
227+
Required: false,
228+
Type: "boolean",
229+
},
230+
{
231+
Name: "environment",
232+
Description: "Environment to run tests against",
233+
Type: "environment",
234+
Required: true,
235+
},
236+
},
237+
},
238+
{
239+
Name: "push",
240+
},
241+
},
242+
},
189243
}
190244
for _, kase := range kases {
191245
t.Run(kase.input, func(t *testing.T) {
@@ -230,8 +284,7 @@ func TestParseMappingNode(t *testing.T) {
230284
{
231285
input: "on:\n push:\n branches:\n - master",
232286
scalars: []string{"push"},
233-
datas: []interface {
234-
}{
287+
datas: []interface{}{
235288
map[string]interface{}{
236289
"branches": []interface{}{"master"},
237290
},

0 commit comments

Comments
 (0)