From ddf9159a8f2b9896a6ee2094262e568caae22170 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 22 Feb 2026 19:04:16 +0000 Subject: [PATCH] Remove jobparser because of moving to Gitea main project (#155) Reviewed-on: https://gitea.com/gitea/act/pulls/155 Reviewed-by: silverwind Reviewed-by: ChristopherHX --- .gitea/workflows/test.yml | 3 - pkg/jobparser/evaluator.go | 185 ------ pkg/jobparser/interpeter.go | 84 --- pkg/jobparser/jobparser.go | 175 ------ pkg/jobparser/jobparser_test.go | 86 --- pkg/jobparser/model.go | 528 ------------------ pkg/jobparser/model_test.go | 372 ------------ pkg/jobparser/testdata/empty_step.in.yaml | 8 - pkg/jobparser/testdata/empty_step.out.yaml | 7 - pkg/jobparser/testdata/erase_needs.in.yaml | 16 - pkg/jobparser/testdata/erase_needs.out.yaml | 23 - pkg/jobparser/testdata/has_needs.in.yaml | 16 - pkg/jobparser/testdata/has_needs.out.yaml | 25 - pkg/jobparser/testdata/has_secrets.in.yaml | 14 - pkg/jobparser/testdata/has_secrets.out.yaml | 16 - pkg/jobparser/testdata/has_with.in.yaml | 15 - pkg/jobparser/testdata/has_with.out.yaml | 17 - .../testdata/job_name_with_matrix.in.yaml | 14 - .../testdata/job_name_with_matrix.out.yaml | 101 ---- pkg/jobparser/testdata/multiple_jobs.in.yaml | 22 - pkg/jobparser/testdata/multiple_jobs.out.yaml | 39 -- .../testdata/multiple_matrix.in.yaml | 13 - .../testdata/multiple_matrix.out.yaml | 101 ---- .../testdata/prefixed_newline.in.yaml | 14 - .../testdata/prefixed_newline.out.yaml | 15 - pkg/jobparser/testdata_test.go | 18 - 26 files changed, 1927 deletions(-) delete mode 100644 pkg/jobparser/evaluator.go delete mode 100644 pkg/jobparser/interpeter.go delete mode 100644 pkg/jobparser/jobparser.go delete mode 100644 pkg/jobparser/jobparser_test.go delete mode 100644 pkg/jobparser/model.go delete mode 100644 pkg/jobparser/model_test.go delete mode 100644 pkg/jobparser/testdata/empty_step.in.yaml delete mode 100644 pkg/jobparser/testdata/empty_step.out.yaml delete mode 100644 pkg/jobparser/testdata/erase_needs.in.yaml delete mode 100644 pkg/jobparser/testdata/erase_needs.out.yaml delete mode 100644 pkg/jobparser/testdata/has_needs.in.yaml delete mode 100644 pkg/jobparser/testdata/has_needs.out.yaml delete mode 100644 pkg/jobparser/testdata/has_secrets.in.yaml delete mode 100644 pkg/jobparser/testdata/has_secrets.out.yaml delete mode 100644 pkg/jobparser/testdata/has_with.in.yaml delete mode 100644 pkg/jobparser/testdata/has_with.out.yaml delete mode 100644 pkg/jobparser/testdata/job_name_with_matrix.in.yaml delete mode 100644 pkg/jobparser/testdata/job_name_with_matrix.out.yaml delete mode 100644 pkg/jobparser/testdata/multiple_jobs.in.yaml delete mode 100644 pkg/jobparser/testdata/multiple_jobs.out.yaml delete mode 100644 pkg/jobparser/testdata/multiple_matrix.in.yaml delete mode 100644 pkg/jobparser/testdata/multiple_matrix.out.yaml delete mode 100644 pkg/jobparser/testdata/prefixed_newline.in.yaml delete mode 100644 pkg/jobparser/testdata/prefixed_newline.out.yaml delete mode 100644 pkg/jobparser/testdata_test.go diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index 7d354572..8d66a90e 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -16,6 +16,3 @@ jobs: run: go vet -v ./... - name: build run: go build -v ./... - - name: test - run: | # Test only the new packages in this fork. Add more packages as needed. - go test -v ./pkg/jobparser diff --git a/pkg/jobparser/evaluator.go b/pkg/jobparser/evaluator.go deleted file mode 100644 index 2a950085..00000000 --- a/pkg/jobparser/evaluator.go +++ /dev/null @@ -1,185 +0,0 @@ -package jobparser - -import ( - "fmt" - "regexp" - "strings" - - "github.com/nektos/act/pkg/exprparser" - "go.yaml.in/yaml/v4" -) - -// ExpressionEvaluator is copied from runner.expressionEvaluator, -// to avoid unnecessary dependencies -type ExpressionEvaluator struct { - interpreter exprparser.Interpreter -} - -func NewExpressionEvaluator(interpreter exprparser.Interpreter) *ExpressionEvaluator { - return &ExpressionEvaluator{interpreter: interpreter} -} - -func (ee ExpressionEvaluator) evaluate(in string, defaultStatusCheck exprparser.DefaultStatusCheck) (interface{}, error) { - evaluated, err := ee.interpreter.Evaluate(in, defaultStatusCheck) - - return evaluated, err -} - -func (ee ExpressionEvaluator) evaluateScalarYamlNode(node *yaml.Node) error { - var in string - if err := node.Decode(&in); err != nil { - return err - } - if !strings.Contains(in, "${{") || !strings.Contains(in, "}}") { - return nil - } - expr, _ := rewriteSubExpression(in, false) - res, err := ee.evaluate(expr, exprparser.DefaultStatusCheckNone) - if err != nil { - return err - } - return node.Encode(res) -} - -func (ee ExpressionEvaluator) evaluateMappingYamlNode(node *yaml.Node) error { - // GitHub has this undocumented feature to merge maps, called insert directive - insertDirective := regexp.MustCompile(`\${{\s*insert\s*}}`) - for i := 0; i < len(node.Content)/2; { - k := node.Content[i*2] - v := node.Content[i*2+1] - if err := ee.EvaluateYamlNode(v); err != nil { - return err - } - var sk string - // Merge the nested map of the insert directive - if k.Decode(&sk) == nil && insertDirective.MatchString(sk) { - node.Content = append(append(node.Content[:i*2], v.Content...), node.Content[(i+1)*2:]...) - i += len(v.Content) / 2 - } else { - if err := ee.EvaluateYamlNode(k); err != nil { - return err - } - i++ - } - } - return nil -} - -func (ee ExpressionEvaluator) evaluateSequenceYamlNode(node *yaml.Node) error { - for i := 0; i < len(node.Content); { - v := node.Content[i] - // Preserve nested sequences - wasseq := v.Kind == yaml.SequenceNode - if err := ee.EvaluateYamlNode(v); err != nil { - return err - } - // GitHub has this undocumented feature to merge sequences / arrays - // We have a nested sequence via evaluation, merge the arrays - if v.Kind == yaml.SequenceNode && !wasseq { - node.Content = append(append(node.Content[:i], v.Content...), node.Content[i+1:]...) - i += len(v.Content) - } else { - i++ - } - } - return nil -} - -func (ee ExpressionEvaluator) EvaluateYamlNode(node *yaml.Node) error { - switch node.Kind { - case yaml.ScalarNode: - return ee.evaluateScalarYamlNode(node) - case yaml.MappingNode: - return ee.evaluateMappingYamlNode(node) - case yaml.SequenceNode: - return ee.evaluateSequenceYamlNode(node) - default: - return nil - } -} - -func (ee ExpressionEvaluator) Interpolate(in string) string { - if !strings.Contains(in, "${{") || !strings.Contains(in, "}}") { - return in - } - - expr, _ := rewriteSubExpression(in, true) - evaluated, err := ee.evaluate(expr, exprparser.DefaultStatusCheckNone) - if err != nil { - return "" - } - - value, ok := evaluated.(string) - if !ok { - panic(fmt.Sprintf("Expression %s did not evaluate to a string", expr)) - } - - return value -} - -func escapeFormatString(in string) string { - return strings.ReplaceAll(strings.ReplaceAll(in, "{", "{{"), "}", "}}") -} - -func rewriteSubExpression(in string, forceFormat bool) (string, error) { - if !strings.Contains(in, "${{") || !strings.Contains(in, "}}") { - return in, nil - } - - strPattern := regexp.MustCompile("(?:''|[^'])*'") - pos := 0 - exprStart := -1 - strStart := -1 - var results []string - formatOut := "" - for pos < len(in) { - if strStart > -1 { - matches := strPattern.FindStringIndex(in[pos:]) - if matches == nil { - panic("unclosed string.") - } - - strStart = -1 - pos += matches[1] - } else if exprStart > -1 { - exprEnd := strings.Index(in[pos:], "}}") - strStart = strings.Index(in[pos:], "'") - - if exprEnd > -1 && strStart > -1 { - if exprEnd < strStart { - strStart = -1 - } else { - exprEnd = -1 - } - } - - if exprEnd > -1 { - formatOut += fmt.Sprintf("{%d}", len(results)) - results = append(results, strings.TrimSpace(in[exprStart:pos+exprEnd])) - pos += exprEnd + 2 - exprStart = -1 - } else if strStart > -1 { - pos += strStart + 1 - } else { - panic("unclosed expression.") - } - } else { - exprStart = strings.Index(in[pos:], "${{") - if exprStart != -1 { - formatOut += escapeFormatString(in[pos : pos+exprStart]) - exprStart = pos + exprStart + 3 - pos = exprStart - } else { - formatOut += escapeFormatString(in[pos:]) - pos = len(in) - } - } - } - - if len(results) == 1 && formatOut == "{0}" && !forceFormat { - return in, nil - } - - out := fmt.Sprintf("format('%s', %s)", strings.ReplaceAll(formatOut, "'", "''"), strings.Join(results, ", ")) - return out, nil -} diff --git a/pkg/jobparser/interpeter.go b/pkg/jobparser/interpeter.go deleted file mode 100644 index e5657813..00000000 --- a/pkg/jobparser/interpeter.go +++ /dev/null @@ -1,84 +0,0 @@ -package jobparser - -import ( - "github.com/nektos/act/pkg/exprparser" - "github.com/nektos/act/pkg/model" - "go.yaml.in/yaml/v4" -) - -// NewInterpeter returns an interpeter used in the server, -// need github, needs, strategy, matrix, inputs context only, -// see https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability -func NewInterpeter( - jobID string, - job *model.Job, - matrix map[string]interface{}, - gitCtx *model.GithubContext, - results map[string]*JobResult, - vars map[string]string, - inputs map[string]interface{}, -) exprparser.Interpreter { - strategy := make(map[string]interface{}) - if job.Strategy != nil { - strategy["fail-fast"] = job.Strategy.FailFast - strategy["max-parallel"] = job.Strategy.MaxParallel - } - - run := &model.Run{ - Workflow: &model.Workflow{ - Jobs: map[string]*model.Job{}, - }, - JobID: jobID, - } - for id, result := range results { - need := yaml.Node{} - _ = need.Encode(result.Needs) - run.Workflow.Jobs[id] = &model.Job{ - RawNeeds: need, - Result: result.Result, - Outputs: result.Outputs, - } - } - - jobs := run.Workflow.Jobs - jobNeeds := run.Job().Needs() - - using := map[string]exprparser.Needs{} - for _, need := range jobNeeds { - if v, ok := jobs[need]; ok { - using[need] = exprparser.Needs{ - Outputs: v.Outputs, - Result: v.Result, - } - } - } - - ee := &exprparser.EvaluationEnvironment{ - Github: gitCtx, - Env: nil, // no need - Job: nil, // no need - Steps: nil, // no need - Runner: nil, // no need - Secrets: nil, // no need - Strategy: strategy, - Matrix: matrix, - Needs: using, - Inputs: inputs, - Vars: vars, - } - - config := exprparser.Config{ - Run: run, - WorkingDir: "", // WorkingDir is used for the function hashFiles, but it's not needed in the server - Context: "job", - } - - return exprparser.NewInterpeter(ee, config) -} - -// JobResult is the minimum requirement of job results for Interpeter -type JobResult struct { - Needs []string - Result string - Outputs map[string]string -} diff --git a/pkg/jobparser/jobparser.go b/pkg/jobparser/jobparser.go deleted file mode 100644 index 962a26bc..00000000 --- a/pkg/jobparser/jobparser.go +++ /dev/null @@ -1,175 +0,0 @@ -package jobparser - -import ( - "bytes" - "fmt" - "sort" - "strings" - - "go.yaml.in/yaml/v4" - - "github.com/nektos/act/pkg/exprparser" - "github.com/nektos/act/pkg/model" -) - -func Parse(content []byte, options ...ParseOption) ([]*SingleWorkflow, error) { - origin, err := model.ReadWorkflow(bytes.NewReader(content)) - if err != nil { - return nil, fmt.Errorf("model.ReadWorkflow: %w", err) - } - - workflow := &SingleWorkflow{} - if err := yaml.Unmarshal(content, workflow); err != nil { - return nil, fmt.Errorf("yaml.Unmarshal: %w", err) - } - - pc := &parseContext{} - for _, o := range options { - o(pc) - } - results := map[string]*JobResult{} - for id, job := range origin.Jobs { - results[id] = &JobResult{ - Needs: job.Needs(), - Result: pc.jobResults[id], - Outputs: nil, // not supported yet - } - } - - var ret []*SingleWorkflow - ids, jobs, err := workflow.jobs() - if err != nil { - return nil, fmt.Errorf("invalid jobs: %w", err) - } - - evaluator := NewExpressionEvaluator(exprparser.NewInterpeter(&exprparser.EvaluationEnvironment{Github: pc.gitContext, Vars: pc.vars, Inputs: pc.inputs}, exprparser.Config{})) - workflow.RunName = evaluator.Interpolate(workflow.RunName) - - for i, id := range ids { - job := jobs[i] - matricxes, err := getMatrixes(origin.GetJob(id)) - if err != nil { - return nil, fmt.Errorf("getMatrixes: %w", err) - } - for _, matrix := range matricxes { - job := job.Clone() - if job.Name == "" { - job.Name = id - } - job.Strategy.RawMatrix = encodeMatrix(matrix) - evaluator := NewExpressionEvaluator(NewInterpeter(id, origin.GetJob(id), matrix, pc.gitContext, results, pc.vars, pc.inputs)) - job.Name = nameWithMatrix(job.Name, matrix, evaluator) - runsOn := origin.GetJob(id).RunsOn() - for i, v := range runsOn { - runsOn[i] = evaluator.Interpolate(v) - } - job.RawRunsOn = encodeRunsOn(runsOn) - swf := &SingleWorkflow{ - Name: workflow.Name, - RawOn: workflow.RawOn, - Env: workflow.Env, - Defaults: workflow.Defaults, - RawPermissions: workflow.RawPermissions, - RunName: workflow.RunName, - } - if err := swf.SetJob(id, job); err != nil { - return nil, fmt.Errorf("SetJob: %w", err) - } - ret = append(ret, swf) - } - } - return ret, nil -} - -func WithJobResults(results map[string]string) ParseOption { - return func(c *parseContext) { - c.jobResults = results - } -} - -func WithGitContext(context *model.GithubContext) ParseOption { - return func(c *parseContext) { - c.gitContext = context - } -} - -func WithVars(vars map[string]string) ParseOption { - return func(c *parseContext) { - c.vars = vars - } -} - -func WithInputs(inputs map[string]any) ParseOption { - return func(c *parseContext) { - c.inputs = inputs - } -} - -type parseContext struct { - jobResults map[string]string - gitContext *model.GithubContext - vars map[string]string - inputs map[string]any -} - -type ParseOption func(c *parseContext) - -func getMatrixes(job *model.Job) ([]map[string]interface{}, error) { - ret, err := job.GetMatrixes() - if err != nil { - return nil, fmt.Errorf("GetMatrixes: %w", err) - } - sort.Slice(ret, func(i, j int) bool { - return matrixName(ret[i]) < matrixName(ret[j]) - }) - return ret, nil -} - -func encodeMatrix(matrix map[string]interface{}) yaml.Node { - if len(matrix) == 0 { - return yaml.Node{} - } - value := map[string][]interface{}{} - for k, v := range matrix { - value[k] = []interface{}{v} - } - node := yaml.Node{} - _ = node.Encode(value) - return node -} - -func encodeRunsOn(runsOn []string) yaml.Node { - node := yaml.Node{} - if len(runsOn) == 1 { - _ = node.Encode(runsOn[0]) - } else { - _ = node.Encode(runsOn) - } - return node -} - -func nameWithMatrix(name string, m map[string]interface{}, evaluator *ExpressionEvaluator) string { - if len(m) == 0 { - return name - } - - if !strings.Contains(name, "${{") || !strings.Contains(name, "}}") { - return name + " " + matrixName(m) - } - - return evaluator.Interpolate(name) -} - -func matrixName(m map[string]interface{}) string { - ks := make([]string, 0, len(m)) - for k := range m { - ks = append(ks, k) - } - sort.Strings(ks) - vs := make([]string, 0, len(m)) - for _, v := range ks { - vs = append(vs, fmt.Sprint(m[v])) - } - - return fmt.Sprintf("(%s)", strings.Join(vs, ", ")) -} diff --git a/pkg/jobparser/jobparser_test.go b/pkg/jobparser/jobparser_test.go deleted file mode 100644 index ed918760..00000000 --- a/pkg/jobparser/jobparser_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package jobparser - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/stretchr/testify/require" - - "go.yaml.in/yaml/v4" -) - -func TestParse(t *testing.T) { - tests := []struct { - name string - options []ParseOption - wantErr bool - }{ - { - name: "multiple_jobs", - options: nil, - wantErr: false, - }, - { - name: "multiple_matrix", - options: nil, - wantErr: false, - }, - { - name: "has_needs", - options: nil, - wantErr: false, - }, - { - name: "has_with", - options: nil, - wantErr: false, - }, - { - name: "has_secrets", - options: nil, - wantErr: false, - }, - { - name: "empty_step", - options: nil, - wantErr: false, - }, - { - name: "job_name_with_matrix", - options: nil, - wantErr: false, - }, - { - name: "prefixed_newline", - options: nil, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - content := ReadTestdata(t, tt.name+".in.yaml") - want := ReadTestdata(t, tt.name+".out.yaml") - got, err := Parse(content, tt.options...) - if tt.wantErr { - require.Error(t, err) - } - require.NoError(t, err) - - builder := &strings.Builder{} - for _, v := range got { - if builder.Len() > 0 { - builder.WriteString("---\n") - } - encoder := yaml.NewEncoder(builder) - encoder.SetIndent(2) - require.NoError(t, encoder.Encode(v)) - id, job := v.Job() - assert.NotEmpty(t, id) - assert.NotNil(t, job) - } - assert.Equal(t, string(want), builder.String()) - }) - } -} diff --git a/pkg/jobparser/model.go b/pkg/jobparser/model.go deleted file mode 100644 index 3360a72b..00000000 --- a/pkg/jobparser/model.go +++ /dev/null @@ -1,528 +0,0 @@ -package jobparser - -import ( - "bytes" - "fmt" - - "github.com/nektos/act/pkg/model" - "go.yaml.in/yaml/v4" -) - -// SingleWorkflow is a workflow with single job and single matrix -type SingleWorkflow struct { - Name string `yaml:"name,omitempty"` - RawOn yaml.Node `yaml:"on,omitempty"` - Env map[string]string `yaml:"env,omitempty"` - RawJobs yaml.Node `yaml:"jobs,omitempty"` - Defaults Defaults `yaml:"defaults,omitempty"` - RawPermissions yaml.Node `yaml:"permissions,omitempty"` - RunName string `yaml:"run-name,omitempty"` -} - -func (w *SingleWorkflow) Job() (string, *Job) { - ids, jobs, _ := w.jobs() - if len(ids) >= 1 { - return ids[0], jobs[0] - } - return "", nil -} - -func (w *SingleWorkflow) jobs() ([]string, []*Job, error) { - ids, jobs, err := parseMappingNode[*Job](&w.RawJobs) - if err != nil { - return nil, nil, err - } - - for _, job := range jobs { - steps := make([]*Step, 0, len(job.Steps)) - for _, s := range job.Steps { - if s != nil { - steps = append(steps, s) - } - } - job.Steps = steps - } - - return ids, jobs, nil -} - -func (w *SingleWorkflow) SetJob(id string, job *Job) error { - m := map[string]*Job{ - id: job, - } - var buf bytes.Buffer - encoder := yaml.NewEncoder(&buf) - encoder.SetIndent(2) - encoder.Encode(m) - encoder.Close() - - node := yaml.Node{} - if err := yaml.Unmarshal(buf.Bytes(), &node); err != nil { - return err - } - if len(node.Content) != 1 || node.Content[0].Kind != yaml.MappingNode { - return fmt.Errorf("can not set job: %s", buf.String()) - } - w.RawJobs = *node.Content[0] - return nil -} - -func (w *SingleWorkflow) Marshal() ([]byte, error) { - return yaml.Marshal(w) -} - -type Job struct { - Name string `yaml:"name,omitempty"` - RawNeeds yaml.Node `yaml:"needs,omitempty"` - RawRunsOn yaml.Node `yaml:"runs-on,omitempty"` - Env yaml.Node `yaml:"env,omitempty"` - If yaml.Node `yaml:"if,omitempty"` - Steps []*Step `yaml:"steps,omitempty"` - TimeoutMinutes string `yaml:"timeout-minutes,omitempty"` - Services map[string]*ContainerSpec `yaml:"services,omitempty"` - Strategy Strategy `yaml:"strategy,omitempty"` - RawContainer yaml.Node `yaml:"container,omitempty"` - Defaults Defaults `yaml:"defaults,omitempty"` - Outputs map[string]string `yaml:"outputs,omitempty"` - Uses string `yaml:"uses,omitempty"` - With map[string]interface{} `yaml:"with,omitempty"` - RawSecrets yaml.Node `yaml:"secrets,omitempty"` - RawConcurrency *model.RawConcurrency `yaml:"concurrency,omitempty"` - RawPermissions yaml.Node `yaml:"permissions,omitempty"` -} - -func (j *Job) Clone() *Job { - if j == nil { - return nil - } - return &Job{ - Name: j.Name, - RawNeeds: j.RawNeeds, - RawRunsOn: j.RawRunsOn, - Env: j.Env, - If: j.If, - Steps: j.Steps, - TimeoutMinutes: j.TimeoutMinutes, - Services: j.Services, - Strategy: j.Strategy, - RawContainer: j.RawContainer, - Defaults: j.Defaults, - Outputs: j.Outputs, - Uses: j.Uses, - With: j.With, - RawSecrets: j.RawSecrets, - RawConcurrency: j.RawConcurrency, - RawPermissions: j.RawPermissions, - } -} - -func (j *Job) Needs() []string { - return (&model.Job{RawNeeds: j.RawNeeds}).Needs() -} - -func (j *Job) EraseNeeds() *Job { - j.RawNeeds = yaml.Node{} - return j -} - -func (j *Job) RunsOn() []string { - return (&model.Job{RawRunsOn: j.RawRunsOn}).RunsOn() -} - -type Step struct { - ID string `yaml:"id,omitempty"` - If yaml.Node `yaml:"if,omitempty"` - Name string `yaml:"name,omitempty"` - Uses string `yaml:"uses,omitempty"` - Run string `yaml:"run,omitempty"` - WorkingDirectory string `yaml:"working-directory,omitempty"` - Shell string `yaml:"shell,omitempty"` - Env yaml.Node `yaml:"env,omitempty"` - With map[string]string `yaml:"with,omitempty"` - ContinueOnError bool `yaml:"continue-on-error,omitempty"` - TimeoutMinutes string `yaml:"timeout-minutes,omitempty"` -} - -// String gets the name of step -func (s *Step) String() string { - if s == nil { - return "" - } - return (&model.Step{ - ID: s.ID, - Name: s.Name, - Uses: s.Uses, - Run: s.Run, - }).String() -} - -type ContainerSpec struct { - Image string `yaml:"image,omitempty"` - Env map[string]string `yaml:"env,omitempty"` - Ports []string `yaml:"ports,omitempty"` - Volumes []string `yaml:"volumes,omitempty"` - Options string `yaml:"options,omitempty"` - Credentials map[string]string `yaml:"credentials,omitempty"` - Cmd []string `yaml:"cmd,omitempty"` -} - -type Strategy struct { - FailFastString string `yaml:"fail-fast,omitempty"` - MaxParallelString string `yaml:"max-parallel,omitempty"` - RawMatrix yaml.Node `yaml:"matrix,omitempty"` -} - -type Defaults struct { - Run RunDefaults `yaml:"run,omitempty"` -} - -type RunDefaults struct { - Shell string `yaml:"shell,omitempty"` - WorkingDirectory string `yaml:"working-directory,omitempty"` -} - -type WorkflowDispatchInput struct { - Name string `yaml:"name"` - Description string `yaml:"description"` - Required bool `yaml:"required"` - Default string `yaml:"default"` - Type string `yaml:"type"` - Options []string `yaml:"options"` -} - -type Event struct { - Name string - acts map[string][]string - schedules []map[string]string - inputs []WorkflowDispatchInput -} - -func (evt *Event) IsSchedule() bool { - return evt.schedules != nil -} - -func (evt *Event) Acts() map[string][]string { - return evt.acts -} - -func (evt *Event) Schedules() []map[string]string { - return evt.schedules -} - -func (evt *Event) Inputs() []WorkflowDispatchInput { - return evt.inputs -} - -func parseWorkflowDispatchInputs(inputs map[string]interface{}) ([]WorkflowDispatchInput, error) { - var results []WorkflowDispatchInput - for name, input := range inputs { - inputMap, ok := input.(map[string]interface{}) - if !ok { - return nil, fmt.Errorf("invalid input: %v", input) - } - input := WorkflowDispatchInput{ - Name: name, - } - if desc, ok := inputMap["description"].(string); ok { - input.Description = desc - } - if required, ok := inputMap["required"].(bool); ok { - input.Required = required - } - if defaultVal, ok := inputMap["default"].(string); ok { - input.Default = defaultVal - } - if inputType, ok := inputMap["type"].(string); ok { - input.Type = inputType - } - if options, ok := inputMap["options"].([]string); ok { - input.Options = options - } else if options, ok := inputMap["options"].([]interface{}); ok { - for _, option := range options { - if opt, ok := option.(string); ok { - input.Options = append(input.Options, opt) - } - } - } - - results = append(results, input) - } - return results, nil -} - -func ReadWorkflowRawConcurrency(content []byte) (*model.RawConcurrency, error) { - w := new(model.Workflow) - err := yaml.NewDecoder(bytes.NewReader(content)).Decode(w) - return w.RawConcurrency, err -} - -func EvaluateConcurrency(rc *model.RawConcurrency, jobID string, job *Job, gitCtx map[string]any, results map[string]*JobResult, vars map[string]string, inputs map[string]any) (string, bool, error) { - actJob := &model.Job{} - if job != nil { - actJob.Strategy = &model.Strategy{ - FailFastString: job.Strategy.FailFastString, - MaxParallelString: job.Strategy.MaxParallelString, - RawMatrix: job.Strategy.RawMatrix, - } - actJob.Strategy.FailFast = actJob.Strategy.GetFailFast() - actJob.Strategy.MaxParallel = actJob.Strategy.GetMaxParallel() - } - - matrix := make(map[string]any) - matrixes, err := actJob.GetMatrixes() - if err != nil { - return "", false, err - } - if len(matrixes) > 0 { - matrix = matrixes[0] - } - - evaluator := NewExpressionEvaluator(NewInterpeter(jobID, actJob, matrix, toGitContext(gitCtx), results, vars, inputs)) - var node yaml.Node - if err := node.Encode(rc); err != nil { - return "", false, fmt.Errorf("failed to encode concurrency: %w", err) - } - if err := evaluator.EvaluateYamlNode(&node); err != nil { - return "", false, fmt.Errorf("failed to evaluate concurrency: %w", err) - } - var evaluated model.RawConcurrency - if err := node.Decode(&evaluated); err != nil { - return "", false, fmt.Errorf("failed to unmarshal evaluated concurrency: %w", err) - } - if evaluated.RawExpression != "" { - return evaluated.RawExpression, false, nil - } - return evaluated.Group, evaluated.CancelInProgress == "true", nil -} - -func toGitContext(input map[string]any) *model.GithubContext { - gitContext := &model.GithubContext{ - EventPath: asString(input["event_path"]), - Workflow: asString(input["workflow"]), - RunID: asString(input["run_id"]), - RunNumber: asString(input["run_number"]), - Actor: asString(input["actor"]), - Repository: asString(input["repository"]), - EventName: asString(input["event_name"]), - Sha: asString(input["sha"]), - Ref: asString(input["ref"]), - RefName: asString(input["ref_name"]), - RefType: asString(input["ref_type"]), - HeadRef: asString(input["head_ref"]), - BaseRef: asString(input["base_ref"]), - Token: asString(input["token"]), - Workspace: asString(input["workspace"]), - Action: asString(input["action"]), - ActionPath: asString(input["action_path"]), - ActionRef: asString(input["action_ref"]), - ActionRepository: asString(input["action_repository"]), - Job: asString(input["job"]), - RepositoryOwner: asString(input["repository_owner"]), - RetentionDays: asString(input["retention_days"]), - } - - event, ok := input["event"].(map[string]any) - if ok { - gitContext.Event = event - } - - return gitContext -} - -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: - events, triggers, err := parseMappingNode[yaml.Node](rawOn) - if err != nil { - return nil, err - } - res := make([]*Event, 0, len(events)) - for i, k := range events { - v := triggers[i] - switch v.Kind { - case yaml.ScalarNode: - res = append(res, &Event{ - Name: k, - }) - case yaml.SequenceNode: - var t []interface{} - err := v.Decode(&t) - if err != nil { - return nil, err - } - schedules := make([]map[string]string, len(t)) - if k == "schedule" { - for i, tt := range t { - vv, ok := tt.(map[string]interface{}) - if !ok { - return nil, fmt.Errorf("unknown on type(schedule): %#v", v) - } - schedules[i] = make(map[string]string, len(vv)) - for k, vvv := range vv { - var ok bool - if schedules[i][k], ok = vvv.(string); !ok { - return nil, fmt.Errorf("unknown on type(schedule): %#v", v) - } - } - } - } - - if len(schedules) == 0 { - schedules = nil - } - res = append(res, &Event{ - Name: k, - schedules: schedules, - }) - case yaml.MappingNode: - acts := make(map[string][]string, len(v.Content)/2) - var inputs []WorkflowDispatchInput - expectedKey := true - var act string - for _, content := range v.Content { - if expectedKey { - if content.Kind != yaml.ScalarNode { - return nil, fmt.Errorf("key type not string: %#v", content) - } - act = "" - err := content.Decode(&act) - if err != nil { - return nil, err - } - } else { - switch content.Kind { - case yaml.SequenceNode: - var t []string - err := content.Decode(&t) - if err != nil { - return nil, err - } - acts[act] = t - case yaml.ScalarNode: - var t string - err := content.Decode(&t) - if err != nil { - return nil, err - } - acts[act] = []string{t} - case yaml.MappingNode: - if k != "workflow_dispatch" || act != "inputs" { - return nil, fmt.Errorf("map should only for workflow_dispatch but %s: %#v", act, content) - } - - var key string - for i, vv := range content.Content { - if i%2 == 0 { - if vv.Kind != yaml.ScalarNode { - return nil, fmt.Errorf("key type not string: %#v", vv) - } - key = "" - if err := vv.Decode(&key); err != nil { - return nil, err - } - } else { - if vv.Kind != yaml.MappingNode { - return nil, fmt.Errorf("key type not map(%s): %#v", key, vv) - } - - input := WorkflowDispatchInput{} - if err := vv.Decode(&input); err != nil { - return nil, err - } - input.Name = key - inputs = append(inputs, input) - } - } - default: - return nil, fmt.Errorf("unknown on type: %#v", content) - } - } - expectedKey = !expectedKey - } - if len(inputs) == 0 { - inputs = nil - } - if len(acts) == 0 { - acts = nil - } - res = append(res, &Event{ - Name: k, - acts: acts, - inputs: inputs, - }) - default: - return nil, fmt.Errorf("unknown on type: %v", v.Kind) - } - } - return res, nil - default: - return nil, fmt.Errorf("unknown on type: %v", rawOn.Kind) - } -} - -// parseMappingNode parse a mapping node and preserve order. -func parseMappingNode[T any](node *yaml.Node) ([]string, []T, error) { - if node.Kind != yaml.MappingNode { - return nil, nil, fmt.Errorf("input node is not a mapping node") - } - - var scalars []string - var datas []T - expectKey := true - for _, item := range node.Content { - if expectKey { - if item.Kind != yaml.ScalarNode { - return nil, nil, fmt.Errorf("not a valid scalar node: %v", item.Value) - } - scalars = append(scalars, item.Value) - expectKey = false - } else { - var val T - if err := item.Decode(&val); err != nil { - return nil, nil, err - } - datas = append(datas, val) - expectKey = true - } - } - - if len(scalars) != len(datas) { - return nil, nil, fmt.Errorf("invalid definition of on: %v", node.Value) - } - - return scalars, datas, nil -} - -func asString(v interface{}) string { - if v == nil { - return "" - } else if s, ok := v.(string); ok { - return s - } - return "" -} diff --git a/pkg/jobparser/model_test.go b/pkg/jobparser/model_test.go deleted file mode 100644 index 833756be..00000000 --- a/pkg/jobparser/model_test.go +++ /dev/null @@ -1,372 +0,0 @@ -package jobparser - -import ( - "fmt" - "strings" - "testing" - - "github.com/nektos/act/pkg/model" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.yaml.in/yaml/v4" -) - -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 push:\n branches: main", - result: []*Event{ - { - Name: "push", - acts: map[string][]string{ - "branches": { - "main", - }, - }, - }, - }, - }, - { - 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", - }, - }, - }, - { - input: "on:\n schedule:\n - cron: '20 6 * * *'", - result: []*Event{ - { - Name: "schedule", - schedules: []map[string]string{ - { - "cron": "20 6 * * *", - }, - }, - }, - }, - }, - { - input: `on: - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'warning' - type: choice - options: - - info - - warning - - debug - tags: - description: 'Test scenario tags' - required: false - type: boolean - environment: - description: 'Environment to run tests against' - type: environment - required: true - push: -`, - result: []*Event{ - { - Name: "workflow_dispatch", - inputs: []WorkflowDispatchInput{ - { - Name: "logLevel", - Description: "Log level", - Required: true, - Default: "warning", - Type: "choice", - Options: []string{"info", "warning", "debug"}, - }, - { - Name: "tags", - Description: "Test scenario tags", - Required: false, - Type: "boolean", - }, - { - Name: "environment", - Description: "Environment to run tests against", - Type: "environment", - Required: true, - }, - }, - }, - { - Name: "push", - }, - }, - }, - } - 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)) - }) - } -} - -func TestSingleWorkflow_SetJob(t *testing.T) { - t.Run("erase needs", func(t *testing.T) { - content := ReadTestdata(t, "erase_needs.in.yaml") - want := ReadTestdata(t, "erase_needs.out.yaml") - swf, err := Parse(content) - require.NoError(t, err) - builder := &strings.Builder{} - for _, v := range swf { - id, job := v.Job() - require.NoError(t, v.SetJob(id, job.EraseNeeds())) - - if builder.Len() > 0 { - builder.WriteString("---\n") - } - encoder := yaml.NewEncoder(builder) - encoder.SetIndent(2) - require.NoError(t, encoder.Encode(v)) - } - assert.Equal(t, string(want), builder.String()) - }) -} - -func TestParseMappingNode(t *testing.T) { - tests := []struct { - input string - scalars []string - datas []interface{} - }{ - { - input: "on:\n push:\n branches:\n - master", - scalars: []string{"push"}, - datas: []interface{}{ - map[string]interface{}{ - "branches": []interface{}{"master"}, - }, - }, - }, - { - input: "on:\n branch_protection_rule:\n types: [created, deleted]", - scalars: []string{"branch_protection_rule"}, - datas: []interface{}{ - map[string]interface{}{ - "types": []interface{}{"created", "deleted"}, - }, - }, - }, - { - input: "on:\n project:\n types: [created, deleted]\n milestone:\n types: [opened, deleted]", - scalars: []string{"project", "milestone"}, - datas: []interface{}{ - map[string]interface{}{ - "types": []interface{}{"created", "deleted"}, - }, - map[string]interface{}{ - "types": []interface{}{"opened", "deleted"}, - }, - }, - }, - { - input: "on:\n pull_request:\n types:\n - opened\n branches:\n - 'releases/**'", - scalars: []string{"pull_request"}, - datas: []interface{}{ - map[string]interface{}{ - "types": []interface{}{"opened"}, - "branches": []interface{}{"releases/**"}, - }, - }, - }, - { - input: "on:\n push:\n branches:\n - main\n pull_request:\n types:\n - opened\n branches:\n - '**'", - scalars: []string{"push", "pull_request"}, - datas: []interface{}{ - map[string]interface{}{ - "branches": []interface{}{"main"}, - }, - map[string]interface{}{ - "types": []interface{}{"opened"}, - "branches": []interface{}{"**"}, - }, - }, - }, - { - input: "on:\n schedule:\n - cron: '20 6 * * *'", - scalars: []string{"schedule"}, - datas: []interface{}{ - []interface{}{map[string]interface{}{ - "cron": "20 6 * * *", - }}, - }, - }, - } - - for _, test := range tests { - t.Run(test.input, func(t *testing.T) { - workflow, err := model.ReadWorkflow(strings.NewReader(test.input)) - assert.NoError(t, err) - - scalars, datas, err := parseMappingNode[interface{}](&workflow.RawOn) - assert.NoError(t, err) - assert.EqualValues(t, test.scalars, scalars, fmt.Sprintf("%#v", scalars)) - assert.EqualValues(t, test.datas, datas, fmt.Sprintf("%#v", datas)) - }) - } -} diff --git a/pkg/jobparser/testdata/empty_step.in.yaml b/pkg/jobparser/testdata/empty_step.in.yaml deleted file mode 100644 index 737ac0b2..00000000 --- a/pkg/jobparser/testdata/empty_step.in.yaml +++ /dev/null @@ -1,8 +0,0 @@ -name: test -jobs: - job1: - name: job1 - runs-on: linux - steps: - - run: echo job-1 - - diff --git a/pkg/jobparser/testdata/empty_step.out.yaml b/pkg/jobparser/testdata/empty_step.out.yaml deleted file mode 100644 index 06828e0e..00000000 --- a/pkg/jobparser/testdata/empty_step.out.yaml +++ /dev/null @@ -1,7 +0,0 @@ -name: test -jobs: - job1: - name: job1 - runs-on: linux - steps: - - run: echo job-1 diff --git a/pkg/jobparser/testdata/erase_needs.in.yaml b/pkg/jobparser/testdata/erase_needs.in.yaml deleted file mode 100644 index a7d1f9b6..00000000 --- a/pkg/jobparser/testdata/erase_needs.in.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: test -jobs: - job1: - runs-on: linux - steps: - - run: uname -a - job2: - runs-on: linux - steps: - - run: uname -a - needs: job1 - job3: - runs-on: linux - steps: - - run: uname -a - needs: [job1, job2] diff --git a/pkg/jobparser/testdata/erase_needs.out.yaml b/pkg/jobparser/testdata/erase_needs.out.yaml deleted file mode 100644 index 959960d6..00000000 --- a/pkg/jobparser/testdata/erase_needs.out.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: test -jobs: - job1: - name: job1 - runs-on: linux - steps: - - run: uname -a ---- -name: test -jobs: - job2: - name: job2 - runs-on: linux - steps: - - run: uname -a ---- -name: test -jobs: - job3: - name: job3 - runs-on: linux - steps: - - run: uname -a diff --git a/pkg/jobparser/testdata/has_needs.in.yaml b/pkg/jobparser/testdata/has_needs.in.yaml deleted file mode 100644 index a7d1f9b6..00000000 --- a/pkg/jobparser/testdata/has_needs.in.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: test -jobs: - job1: - runs-on: linux - steps: - - run: uname -a - job2: - runs-on: linux - steps: - - run: uname -a - needs: job1 - job3: - runs-on: linux - steps: - - run: uname -a - needs: [job1, job2] diff --git a/pkg/jobparser/testdata/has_needs.out.yaml b/pkg/jobparser/testdata/has_needs.out.yaml deleted file mode 100644 index a544aa22..00000000 --- a/pkg/jobparser/testdata/has_needs.out.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: test -jobs: - job1: - name: job1 - runs-on: linux - steps: - - run: uname -a ---- -name: test -jobs: - job2: - name: job2 - needs: job1 - runs-on: linux - steps: - - run: uname -a ---- -name: test -jobs: - job3: - name: job3 - needs: [job1, job2] - runs-on: linux - steps: - - run: uname -a diff --git a/pkg/jobparser/testdata/has_secrets.in.yaml b/pkg/jobparser/testdata/has_secrets.in.yaml deleted file mode 100644 index 64b9f69f..00000000 --- a/pkg/jobparser/testdata/has_secrets.in.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: test -jobs: - job1: - name: job1 - runs-on: linux - uses: .gitea/workflows/build.yml - secrets: - secret: hideme - - job2: - name: job2 - runs-on: linux - uses: .gitea/workflows/build.yml - secrets: inherit diff --git a/pkg/jobparser/testdata/has_secrets.out.yaml b/pkg/jobparser/testdata/has_secrets.out.yaml deleted file mode 100644 index 23dfb803..00000000 --- a/pkg/jobparser/testdata/has_secrets.out.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: test -jobs: - job1: - name: job1 - runs-on: linux - uses: .gitea/workflows/build.yml - secrets: - secret: hideme ---- -name: test -jobs: - job2: - name: job2 - runs-on: linux - uses: .gitea/workflows/build.yml - secrets: inherit diff --git a/pkg/jobparser/testdata/has_with.in.yaml b/pkg/jobparser/testdata/has_with.in.yaml deleted file mode 100644 index 4e3dc745..00000000 --- a/pkg/jobparser/testdata/has_with.in.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: test -jobs: - job1: - name: job1 - runs-on: linux - uses: .gitea/workflows/build.yml - with: - package: service - - job2: - name: job2 - runs-on: linux - uses: .gitea/workflows/build.yml - with: - package: module diff --git a/pkg/jobparser/testdata/has_with.out.yaml b/pkg/jobparser/testdata/has_with.out.yaml deleted file mode 100644 index de79b803..00000000 --- a/pkg/jobparser/testdata/has_with.out.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: test -jobs: - job1: - name: job1 - runs-on: linux - uses: .gitea/workflows/build.yml - with: - package: service ---- -name: test -jobs: - job2: - name: job2 - runs-on: linux - uses: .gitea/workflows/build.yml - with: - package: module diff --git a/pkg/jobparser/testdata/job_name_with_matrix.in.yaml b/pkg/jobparser/testdata/job_name_with_matrix.in.yaml deleted file mode 100644 index 7b5edf74..00000000 --- a/pkg/jobparser/testdata/job_name_with_matrix.in.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: test -jobs: - job1: - strategy: - matrix: - os: [ubuntu-22.04, ubuntu-20.04] - version: [1.17, 1.18, 1.19] - runs-on: ${{ matrix.os }} - name: test_version_${{ matrix.version }}_on_${{ matrix.os }} - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version \ No newline at end of file diff --git a/pkg/jobparser/testdata/job_name_with_matrix.out.yaml b/pkg/jobparser/testdata/job_name_with_matrix.out.yaml deleted file mode 100644 index 081e8d4a..00000000 --- a/pkg/jobparser/testdata/job_name_with_matrix.out.yaml +++ /dev/null @@ -1,101 +0,0 @@ -name: test -jobs: - job1: - name: test_version_1.17_on_ubuntu-20.04 - runs-on: ubuntu-20.04 - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version - strategy: - matrix: - os: - - ubuntu-20.04 - version: - - 1.17 ---- -name: test -jobs: - job1: - name: test_version_1.18_on_ubuntu-20.04 - runs-on: ubuntu-20.04 - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version - strategy: - matrix: - os: - - ubuntu-20.04 - version: - - 1.18 ---- -name: test -jobs: - job1: - name: test_version_1.19_on_ubuntu-20.04 - runs-on: ubuntu-20.04 - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version - strategy: - matrix: - os: - - ubuntu-20.04 - version: - - 1.19 ---- -name: test -jobs: - job1: - name: test_version_1.17_on_ubuntu-22.04 - runs-on: ubuntu-22.04 - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version - strategy: - matrix: - os: - - ubuntu-22.04 - version: - - 1.17 ---- -name: test -jobs: - job1: - name: test_version_1.18_on_ubuntu-22.04 - runs-on: ubuntu-22.04 - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version - strategy: - matrix: - os: - - ubuntu-22.04 - version: - - 1.18 ---- -name: test -jobs: - job1: - name: test_version_1.19_on_ubuntu-22.04 - runs-on: ubuntu-22.04 - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version - strategy: - matrix: - os: - - ubuntu-22.04 - version: - - 1.19 diff --git a/pkg/jobparser/testdata/multiple_jobs.in.yaml b/pkg/jobparser/testdata/multiple_jobs.in.yaml deleted file mode 100644 index 266ede84..00000000 --- a/pkg/jobparser/testdata/multiple_jobs.in.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: test -jobs: - zzz: - runs-on: linux - steps: - - run: echo zzz - job1: - runs-on: linux - steps: - - run: uname -a && go version - job2: - runs-on: linux - steps: - - run: uname -a && go version - job3: - runs-on: linux - steps: - - run: uname -a && go version - aaa: - runs-on: linux - steps: - - run: uname -a && go version diff --git a/pkg/jobparser/testdata/multiple_jobs.out.yaml b/pkg/jobparser/testdata/multiple_jobs.out.yaml deleted file mode 100644 index ea223500..00000000 --- a/pkg/jobparser/testdata/multiple_jobs.out.yaml +++ /dev/null @@ -1,39 +0,0 @@ -name: test -jobs: - zzz: - name: zzz - runs-on: linux - steps: - - run: echo zzz ---- -name: test -jobs: - job1: - name: job1 - runs-on: linux - steps: - - run: uname -a && go version ---- -name: test -jobs: - job2: - name: job2 - runs-on: linux - steps: - - run: uname -a && go version ---- -name: test -jobs: - job3: - name: job3 - runs-on: linux - steps: - - run: uname -a && go version ---- -name: test -jobs: - aaa: - name: aaa - runs-on: linux - steps: - - run: uname -a && go version diff --git a/pkg/jobparser/testdata/multiple_matrix.in.yaml b/pkg/jobparser/testdata/multiple_matrix.in.yaml deleted file mode 100644 index 99985f3c..00000000 --- a/pkg/jobparser/testdata/multiple_matrix.in.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: test -jobs: - job1: - strategy: - matrix: - os: [ubuntu-22.04, ubuntu-20.04] - version: [1.17, 1.18, 1.19] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version \ No newline at end of file diff --git a/pkg/jobparser/testdata/multiple_matrix.out.yaml b/pkg/jobparser/testdata/multiple_matrix.out.yaml deleted file mode 100644 index e277cdd0..00000000 --- a/pkg/jobparser/testdata/multiple_matrix.out.yaml +++ /dev/null @@ -1,101 +0,0 @@ -name: test -jobs: - job1: - name: job1 (ubuntu-20.04, 1.17) - runs-on: ubuntu-20.04 - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version - strategy: - matrix: - os: - - ubuntu-20.04 - version: - - 1.17 ---- -name: test -jobs: - job1: - name: job1 (ubuntu-20.04, 1.18) - runs-on: ubuntu-20.04 - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version - strategy: - matrix: - os: - - ubuntu-20.04 - version: - - 1.18 ---- -name: test -jobs: - job1: - name: job1 (ubuntu-20.04, 1.19) - runs-on: ubuntu-20.04 - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version - strategy: - matrix: - os: - - ubuntu-20.04 - version: - - 1.19 ---- -name: test -jobs: - job1: - name: job1 (ubuntu-22.04, 1.17) - runs-on: ubuntu-22.04 - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version - strategy: - matrix: - os: - - ubuntu-22.04 - version: - - 1.17 ---- -name: test -jobs: - job1: - name: job1 (ubuntu-22.04, 1.18) - runs-on: ubuntu-22.04 - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version - strategy: - matrix: - os: - - ubuntu-22.04 - version: - - 1.18 ---- -name: test -jobs: - job1: - name: job1 (ubuntu-22.04, 1.19) - runs-on: ubuntu-22.04 - steps: - - uses: actions/setup-go@v3 - with: - go-version: ${{ matrix.version }} - - run: uname -a && go version - strategy: - matrix: - os: - - ubuntu-22.04 - version: - - 1.19 diff --git a/pkg/jobparser/testdata/prefixed_newline.in.yaml b/pkg/jobparser/testdata/prefixed_newline.in.yaml deleted file mode 100644 index 91f85302..00000000 --- a/pkg/jobparser/testdata/prefixed_newline.in.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: Step with leading new line - -on: - push: - -jobs: - test: - runs-on: ubuntu-latest - steps: - - name: "\nExtract tag for variant" - id: extract_tag - run: | - - echo Test diff --git a/pkg/jobparser/testdata/prefixed_newline.out.yaml b/pkg/jobparser/testdata/prefixed_newline.out.yaml deleted file mode 100644 index 027e9dfa..00000000 --- a/pkg/jobparser/testdata/prefixed_newline.out.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: Step with leading new line -"on": - push: -jobs: - test: - name: test - runs-on: ubuntu-latest - steps: - - id: extract_tag - name: |2- - - Extract tag for variant - run: |2 - - echo Test diff --git a/pkg/jobparser/testdata_test.go b/pkg/jobparser/testdata_test.go deleted file mode 100644 index fb75a501..00000000 --- a/pkg/jobparser/testdata_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package jobparser - -import ( - "embed" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" -) - -//go:embed testdata -var testdata embed.FS - -func ReadTestdata(t *testing.T, name string) []byte { - content, err := testdata.ReadFile(filepath.Join("testdata", name)) - require.NoError(t, err) - return content -}