feat: parse types of reusable workflows (#1414)
This change does parse the different types of workflow jobs. It is not much by itself but the start to implement reusable workflows. Relates to #826 Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
parent
a9298d936c
commit
9b95a728d8
|
@ -380,6 +380,42 @@ func commonKeysMatch2(a map[string]interface{}, b map[string]interface{}, m map[
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JobType describes what type of job we are about to run
|
||||||
|
type JobType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// StepTypeRun is all steps that have a `run` attribute
|
||||||
|
JobTypeDefault JobType = iota
|
||||||
|
|
||||||
|
// StepTypeReusableWorkflowLocal is all steps that have a `uses` that is a local workflow in the .github/workflows directory
|
||||||
|
JobTypeReusableWorkflowLocal
|
||||||
|
|
||||||
|
// JobTypeReusableWorkflowRemote is all steps that have a `uses` that references a workflow file in a github repo
|
||||||
|
JobTypeReusableWorkflowRemote
|
||||||
|
)
|
||||||
|
|
||||||
|
func (j JobType) String() string {
|
||||||
|
switch j {
|
||||||
|
case JobTypeDefault:
|
||||||
|
return "default"
|
||||||
|
case JobTypeReusableWorkflowLocal:
|
||||||
|
return "local-reusable-workflow"
|
||||||
|
case JobTypeReusableWorkflowRemote:
|
||||||
|
return "remote-reusable-workflow"
|
||||||
|
}
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type returns the type of the job
|
||||||
|
func (j *Job) Type() JobType {
|
||||||
|
if strings.HasPrefix(j.Uses, "./.github/workflows") && (strings.HasSuffix(j.Uses, ".yml") || strings.HasSuffix(j.Uses, ".yaml")) {
|
||||||
|
return JobTypeReusableWorkflowLocal
|
||||||
|
} else if !strings.HasPrefix(j.Uses, "./") && strings.Contains(j.Uses, ".github/workflows") && (strings.Contains(j.Uses, ".yml@") || strings.Contains(j.Uses, ".yaml@")) {
|
||||||
|
return JobTypeReusableWorkflowRemote
|
||||||
|
}
|
||||||
|
return JobTypeDefault
|
||||||
|
}
|
||||||
|
|
||||||
// ContainerSpec is the specification of the container to use for the job
|
// ContainerSpec is the specification of the container to use for the job
|
||||||
type ContainerSpec struct {
|
type ContainerSpec struct {
|
||||||
Image string `yaml:"image"`
|
Image string `yaml:"image"`
|
||||||
|
@ -486,6 +522,12 @@ const (
|
||||||
// StepTypeUsesActionRemote is all steps that have a `uses` that is a reference to a github repo
|
// StepTypeUsesActionRemote is all steps that have a `uses` that is a reference to a github repo
|
||||||
StepTypeUsesActionRemote
|
StepTypeUsesActionRemote
|
||||||
|
|
||||||
|
// StepTypeReusableWorkflowLocal is all steps that have a `uses` that is a local workflow in the .github/workflows directory
|
||||||
|
StepTypeReusableWorkflowLocal
|
||||||
|
|
||||||
|
// StepTypeReusableWorkflowRemote is all steps that have a `uses` that references a workflow file in a github repo
|
||||||
|
StepTypeReusableWorkflowRemote
|
||||||
|
|
||||||
// StepTypeInvalid is for steps that have invalid step action
|
// StepTypeInvalid is for steps that have invalid step action
|
||||||
StepTypeInvalid
|
StepTypeInvalid
|
||||||
)
|
)
|
||||||
|
@ -502,6 +544,10 @@ func (s StepType) String() string {
|
||||||
return "remote-action"
|
return "remote-action"
|
||||||
case StepTypeUsesDockerURL:
|
case StepTypeUsesDockerURL:
|
||||||
return "docker"
|
return "docker"
|
||||||
|
case StepTypeReusableWorkflowLocal:
|
||||||
|
return "local-reusable-workflow"
|
||||||
|
case StepTypeReusableWorkflowRemote:
|
||||||
|
return "remote-reusable-workflow"
|
||||||
}
|
}
|
||||||
return "unknown"
|
return "unknown"
|
||||||
}
|
}
|
||||||
|
@ -519,6 +565,10 @@ func (s *Step) Type() StepType {
|
||||||
return StepTypeRun
|
return StepTypeRun
|
||||||
} else if strings.HasPrefix(s.Uses, "docker://") {
|
} else if strings.HasPrefix(s.Uses, "docker://") {
|
||||||
return StepTypeUsesDockerURL
|
return StepTypeUsesDockerURL
|
||||||
|
} else if strings.HasPrefix(s.Uses, "./.github/workflows") && (strings.HasSuffix(s.Uses, ".yml") || strings.HasSuffix(s.Uses, ".yaml")) {
|
||||||
|
return StepTypeReusableWorkflowLocal
|
||||||
|
} else if !strings.HasPrefix(s.Uses, "./") && strings.Contains(s.Uses, ".github/workflows") && (strings.Contains(s.Uses, ".yml@") || strings.Contains(s.Uses, ".yaml@")) {
|
||||||
|
return StepTypeReusableWorkflowRemote
|
||||||
} else if strings.HasPrefix(s.Uses, "./") {
|
} else if strings.HasPrefix(s.Uses, "./") {
|
||||||
return StepTypeUsesActionLocal
|
return StepTypeUsesActionLocal
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,31 @@ jobs:
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReadWorkflow_JobTypes(t *testing.T) {
|
||||||
|
yaml := `
|
||||||
|
name: invalid job definition
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
default-job:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- run: echo
|
||||||
|
remote-reusable-workflow:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
uses: remote/repo/.github/workflows/workflow.yml@main
|
||||||
|
local-reusable-workflow:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
uses: ./.github/workflows/workflow.yml
|
||||||
|
`
|
||||||
|
|
||||||
|
workflow, err := ReadWorkflow(strings.NewReader(yaml))
|
||||||
|
assert.NoError(t, err, "read workflow should succeed")
|
||||||
|
assert.Len(t, workflow.Jobs, 3)
|
||||||
|
assert.Equal(t, workflow.Jobs["default-job"].Type(), JobTypeDefault)
|
||||||
|
assert.Equal(t, workflow.Jobs["remote-reusable-workflow"].Type(), JobTypeReusableWorkflowRemote)
|
||||||
|
assert.Equal(t, workflow.Jobs["local-reusable-workflow"].Type(), JobTypeReusableWorkflowLocal)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReadWorkflow_StepsTypes(t *testing.T) {
|
func TestReadWorkflow_StepsTypes(t *testing.T) {
|
||||||
yaml := `
|
yaml := `
|
||||||
name: invalid step definition
|
name: invalid step definition
|
||||||
|
|
Loading…
Reference in New Issue