From e46ede1b174460d627db9ca68381d2fc3659b837 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 31 Jan 2023 15:49:55 +0800 Subject: [PATCH] parse raw on (#11) Reviewed-on: https://gitea.com/gitea/act/pulls/11 Reviewed-by: Jason Song Co-authored-by: Lunny Xiao Co-committed-by: Lunny Xiao --- pkg/jobparser/interpeter.go | 1 - pkg/jobparser/model.go | 84 ++++++++++++++++ pkg/jobparser/model_test.go | 184 ++++++++++++++++++++++++++++++++++++ 3 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 pkg/jobparser/model_test.go diff --git a/pkg/jobparser/interpeter.go b/pkg/jobparser/interpeter.go index 65e66eb..e6c5bf4 100644 --- a/pkg/jobparser/interpeter.go +++ b/pkg/jobparser/interpeter.go @@ -16,7 +16,6 @@ func NewInterpeter( gitCtx *model.GithubContext, results map[string]*JobResult, ) exprparser.Interpreter { - strategy := make(map[string]interface{}) if job.Strategy != nil { strategy["fail-fast"] = job.Strategy.FailFast diff --git a/pkg/jobparser/model.go b/pkg/jobparser/model.go index b6d8d56..9e9a97c 100644 --- a/pkg/jobparser/model.go +++ b/pkg/jobparser/model.go @@ -1,6 +1,8 @@ package jobparser import ( + "fmt" + "github.com/nektos/act/pkg/model" "gopkg.in/yaml.v3" ) @@ -121,3 +123,85 @@ type RunDefaults struct { Shell string `yaml:"shell,omitempty"` WorkingDirectory string `yaml:"working-directory,omitempty"` } + +type Event struct { + Name string + Acts map[string][]string +} + +func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) { + switch rawOn.Kind { + case yaml.ScalarNode: + var val string + err := rawOn.Decode(&val) + if err != nil { + return nil, err + } + return []*Event{ + {Name: val}, + }, nil + case yaml.SequenceNode: + var val []interface{} + err := rawOn.Decode(&val) + if err != nil { + return nil, err + } + res := make([]*Event, 0, len(val)) + for _, v := range val { + switch t := v.(type) { + case string: + res = append(res, &Event{Name: t}) + default: + return nil, fmt.Errorf("invalid type %T", t) + } + } + return res, nil + case yaml.MappingNode: + var val map[string]interface{} + err := rawOn.Decode(&val) + if err != nil { + return nil, err + } + res := make([]*Event, 0, len(val)) + for k, v := range val { + switch t := v.(type) { + case string: + res = append(res, &Event{ + Name: k, + Acts: map[string][]string{}, + }) + case []string: + res = append(res, &Event{ + Name: k, + Acts: map[string][]string{}, + }) + case map[string]interface{}: + acts := make(map[string][]string, len(t)) + for act, branches := range t { + switch b := branches.(type) { + case string: + acts[act] = []string{b} + case []string: + acts[act] = b + case []interface{}: + acts[act] = make([]string, len(b)) + for i, v := range b { + acts[act][i] = v.(string) + } + default: + return nil, fmt.Errorf("unknown on type: %#v", branches) + } + } + res = append(res, &Event{ + Name: k, + Acts: acts, + }) + default: + return nil, fmt.Errorf("unknown on type: %#v", v) + } + } + return res, nil + default: + return nil, fmt.Errorf("unknown on type: %v", rawOn.Kind) + } +} diff --git a/pkg/jobparser/model_test.go b/pkg/jobparser/model_test.go new file mode 100644 index 0000000..9293d25 --- /dev/null +++ b/pkg/jobparser/model_test.go @@ -0,0 +1,184 @@ +package jobparser + +import ( + "fmt" + "strings" + "testing" + + "github.com/nektos/act/pkg/model" + "github.com/stretchr/testify/assert" +) + +func TestParseRawOn(t *testing.T) { + kases := []struct { + input string + result []*Event + }{ + { + input: "on: issue_comment", + result: []*Event{ + { + Name: "issue_comment", + }, + }, + }, + { + input: "on:\n push", + result: []*Event{ + { + Name: "push", + }, + }, + }, + + { + input: "on:\n - push\n - pull_request", + result: []*Event{ + { + Name: "push", + }, + { + Name: "pull_request", + }, + }, + }, + { + input: "on:\n push:\n branches:\n - master", + result: []*Event{ + { + Name: "push", + Acts: map[string][]string{ + "branches": { + "master", + }, + }, + }, + }, + }, + { + input: "on:\n branch_protection_rule:\n types: [created, deleted]", + result: []*Event{ + { + Name: "branch_protection_rule", + Acts: map[string][]string{ + "types": { + "created", + "deleted", + }, + }, + }, + }, + }, + { + input: "on:\n project:\n types: [created, deleted]\n milestone:\n types: [opened, deleted]", + result: []*Event{ + { + Name: "project", + Acts: map[string][]string{ + "types": { + "created", + "deleted", + }, + }, + }, + { + Name: "milestone", + Acts: map[string][]string{ + "types": { + "opened", + "deleted", + }, + }, + }, + }, + }, + { + input: "on:\n pull_request:\n types:\n - opened\n branches:\n - 'releases/**'", + result: []*Event{ + { + Name: "pull_request", + Acts: map[string][]string{ + "types": { + "opened", + }, + "branches": { + "releases/**", + }, + }, + }, + }, + }, + { + input: "on:\n push:\n branches:\n - main\n pull_request:\n types:\n - opened\n branches:\n - '**'", + result: []*Event{ + { + Name: "push", + Acts: map[string][]string{ + "branches": { + "main", + }, + }, + }, + { + Name: "pull_request", + Acts: map[string][]string{ + "types": { + "opened", + }, + "branches": { + "**", + }, + }, + }, + }, + }, + { + input: "on:\n push:\n branches:\n - 'main'\n - 'releases/**'", + result: []*Event{ + { + Name: "push", + Acts: map[string][]string{ + "branches": { + "main", + "releases/**", + }, + }, + }, + }, + }, + { + input: "on:\n push:\n tags:\n - v1.**", + result: []*Event{ + { + Name: "push", + Acts: map[string][]string{ + "tags": { + "v1.**", + }, + }, + }, + }, + }, + { + input: "on: [pull_request, workflow_dispatch]", + result: []*Event{ + { + Name: "pull_request", + }, + { + Name: "workflow_dispatch", + }, + }, + }, + } + for _, kase := range kases { + t.Run(kase.input, func(t *testing.T) { + origin, err := model.ReadWorkflow(strings.NewReader(kase.input)) + assert.NoError(t, err) + + events, err := ParseRawOn(&origin.RawOn) + assert.NoError(t, err) + assert.EqualValues(t, kase.result, events, fmt.Sprintf("%#v", events)) + }) + } +}