support list/map/scalar for on and needs

Signed-off-by: Casey Lee <cplee@nektos.com>
This commit is contained in:
Casey Lee
2020-02-10 16:35:00 -08:00
parent 0582306861
commit ac8258db4b
35 changed files with 2454 additions and 1696 deletions

View File

@@ -3,7 +3,7 @@ package model
import (
"io"
"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
)
// ActionRunsUsing is the type of runner for the action

View File

@@ -88,8 +88,10 @@ type workflowPlanner struct {
func (wp *workflowPlanner) PlanEvent(eventName string) *Plan {
plan := new(Plan)
for _, w := range wp.workflows {
if w.On == eventName {
plan.mergeStages(createStages(w, w.GetJobIDs()...))
for _, e := range w.On() {
if e == eventName {
plan.mergeStages(createStages(w, w.GetJobIDs()...))
}
}
}
return plan
@@ -110,14 +112,19 @@ func (wp *workflowPlanner) GetEvents() []string {
for _, w := range wp.workflows {
found := false
for _, e := range events {
if e == w.On {
found = true
for _, we := range w.On() {
if e == we {
found = true
break
}
}
if found {
break
}
}
if !found {
events = append(events, w.On)
events = append(events, w.On()...)
}
}
@@ -163,8 +170,8 @@ func createStages(w *Workflow, jobIDs ...string) []*Stage {
// make sure we haven't visited this job yet
if _, ok := jobDependencies[jID]; !ok {
if job := w.GetJob(jID); job != nil {
jobDependencies[jID] = job.Needs
newJobIDs = append(newJobIDs, job.Needs...)
jobDependencies[jID] = job.Needs()
newJobIDs = append(newJobIDs, job.Needs()...)
}
}
}

View File

@@ -6,21 +6,45 @@ import (
"regexp"
"strings"
"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
)
// Workflow is the structure of the files in .github/workflows
type Workflow struct {
Name string `yaml:"name"`
On string `yaml:"on"`
Env map[string]string `yaml:"env"`
Jobs map[string]*Job `yaml:"jobs"`
Name string `yaml:"name"`
RawOn yaml.Node `yaml:"on"`
Env map[string]string `yaml:"env"`
Jobs map[string]*Job `yaml:"jobs"`
}
// On events for the workflow
func (w *Workflow) On() []string {
switch w.RawOn.Kind {
case yaml.ScalarNode:
var val string
w.RawOn.Decode(&val)
return []string{val}
case yaml.SequenceNode:
var val []string
w.RawOn.Decode(&val)
return val
case yaml.MappingNode:
var val map[string]interface{}
w.RawOn.Decode(&val)
var keys []string
for k := range val {
keys = append(keys, k)
}
return keys
}
return nil
}
// Job is the structure of one job in a workflow
type Job struct {
Name string `yaml:"name"`
Needs []string `yaml:"needs"`
RawNeeds yaml.Node `yaml:"needs"`
RunsOn string `yaml:"runs-on"`
Env map[string]string `yaml:"env"`
If string `yaml:"if"`
@@ -30,6 +54,22 @@ type Job struct {
Services map[string]*ContainerSpec `yaml:"services"`
}
// Needs list for Job
func (j *Job) Needs() []string {
switch j.RawNeeds.Kind {
case yaml.ScalarNode:
var val string
j.RawNeeds.Decode(&val)
return []string{val}
case yaml.SequenceNode:
var val []string
j.RawNeeds.Decode(&val)
return val
}
return nil
}
// ContainerSpec is the specification of the container to use for the job
type ContainerSpec struct {
Image string `yaml:"image"`

View File

@@ -0,0 +1,68 @@
package model
import (
"strings"
"testing"
"gotest.tools/assert"
)
func TestReadWorkflow_StringEvent(t *testing.T) {
yaml := `
name: local-action-docker-url
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: ./actions/docker-url
`
workflow, err := ReadWorkflow(strings.NewReader(yaml))
assert.NilError(t, err, "read workflow should succeed")
assert.DeepEqual(t, workflow.On(), []string{"push"})
}
func TestReadWorkflow_ListEvent(t *testing.T) {
yaml := `
name: local-action-docker-url
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: ./actions/docker-url
`
workflow, err := ReadWorkflow(strings.NewReader(yaml))
assert.NilError(t, err, "read workflow should succeed")
assert.DeepEqual(t, workflow.On(), []string{"push", "pull_request"})
}
func TestReadWorkflow_MapEvent(t *testing.T) {
yaml := `
name: local-action-docker-url
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: ./actions/docker-url
`
workflow, err := ReadWorkflow(strings.NewReader(yaml))
assert.NilError(t, err, "read workflow should succeed")
assert.DeepEqual(t, workflow.On(), []string{"push", "pull_request"})
}