courgette/internal/workflow/models.go

96 lines
2 KiB
Go

package workflow
import (
"errors"
)
type Job struct {
RunsOn string `yaml:"runs-on"`
Steps []Step `yaml:"steps"`
Needs []string `yaml:"needs"`
// Job name; this isn't guaranteed to be unique.
Name string `yaml:"name"`
}
func (j Job) Validate() []error {
validationErrors := []error{}
if j.RunsOn == "" {
validationErrors = append(validationErrors, errors.New("Missing \"runs-on\" field on job."))
}
if len(j.Steps) == 0 {
validationErrors = append(validationErrors, errors.New("Missing \"steps\" field on job."))
}
for _, step := range j.Steps {
validationErrors = append(validationErrors, step.Validate()...)
}
return validationErrors
}
type Step struct {
Run string `yaml:"run"`
}
func (s Step) Validate() []error {
validationErrors := []error{}
if s.Run == "" {
validationErrors = append(validationErrors, errors.New("Missing \"run\" field on step."))
}
return validationErrors
}
type Workflow struct {
SourcePath string
Jobs map[string]Job `yaml:"jobs"`
}
func (w Workflow) Validate() []error {
validationErrors := []error{}
if len(w.Jobs) == 0 {
validationErrors = append(validationErrors, errors.New("Missing \"jobs\" field on workflow."))
}
for _, job := range w.Jobs {
validationErrors = append(validationErrors, job.Validate()...)
}
return validationErrors
}
// Creates a deterministic, ordered collection of jobs that respects
// the jobs's dependencies.
func (w Workflow) GetJobsAsGroups() [][]Job {
dependenciesMap := map[string][]string{}
for jobLabel, job := range w.Jobs {
if len(job.Needs) == 0 {
dependenciesMap[""] = append(dependenciesMap[""], jobLabel)
}
for _, need := range job.Needs {
dependenciesMap[need] = append(dependenciesMap[need], jobLabel)
}
}
levels := SplitFlatTreeIntoGroups(dependenciesMap)
groups := [][]Job{}
for _, jobLabels := range levels {
jobs := []Job{}
for _, jobLabel := range jobLabels {
jobs = append(jobs, w.Jobs[jobLabel])
}
groups = append(groups, jobs)
}
return groups
}