feat: add working-directory and job-level default workdir to workflow

This commit is contained in:
Marc 2024-08-12 00:34:17 -04:00
parent a974c36c74
commit 6e0af0b058
Signed by: marc
GPG key ID: 048E042F22B5DC79
2 changed files with 109 additions and 2 deletions

View file

@ -9,7 +9,12 @@ type Job struct {
Steps []Step `yaml:"steps"` Steps []Step `yaml:"steps"`
Needs []string `yaml:"needs"` Needs []string `yaml:"needs"`
// Job name; this isn't guaranteed to be unique. // Job name; this isn't guaranteed to be unique.
Name string `yaml:"name"` Name string `yaml:"name"`
Defaults struct {
Run struct {
WorkingDirectory string `yaml:"working-directory"`
} `yaml:"run"`
} `yaml:"defaults"`
} }
func (j Job) Validate() []error { func (j Job) Validate() []error {
@ -31,7 +36,8 @@ func (j Job) Validate() []error {
} }
type Step struct { type Step struct {
Run string `yaml:"run"` Run string `yaml:"run"`
WorkingDirectory string `yaml:"working-directory"`
} }
func (s Step) Validate() []error { func (s Step) Validate() []error {
@ -49,6 +55,27 @@ type Workflow struct {
Jobs map[string]Job `yaml:"jobs"` Jobs map[string]Job `yaml:"jobs"`
} }
// Returns the given workflow's job+step working directory inside the container
// that runs the job.
//
// Values considered, in order:
// - Step working-directory;
// - Job default run working-directory
func (w Workflow) GetWorkingDirectory(jobName string, stepIndex int) string {
jobDefinition := w.Jobs[jobName]
stepDefinition := jobDefinition.Steps[stepIndex]
if stepDefinition.WorkingDirectory != "" {
return stepDefinition.WorkingDirectory
}
if jobDefinition.Defaults.Run.WorkingDirectory != "" {
return jobDefinition.Defaults.Run.WorkingDirectory
}
return "."
}
func (w Workflow) Validate() []error { func (w Workflow) Validate() []error {
validationErrors := []error{} validationErrors := []error{}

View file

@ -0,0 +1,80 @@
package workflow
import (
"testing"
)
func TestWorkingDirectoryDefaultsToCurrentDirectory(t *testing.T) {
sample := `
jobs:
jobA:
runs-on: default
steps:
- run: echo "test"
`
workflow, _ := FromYamlBytes([]byte(sample))
workDir := workflow.GetWorkingDirectory("jobA", 0)
if workDir != "." {
t.Errorf("Expected current directory as working directory, got %s", workDir)
}
}
func TestWorkingDirectoryUsesStepDefault(t *testing.T) {
sample := `
jobs:
jobA:
runs-on: default
steps:
- run: echo "test"
working-directory: ./test
`
workflow, _ := FromYamlBytes([]byte(sample))
workDir := workflow.GetWorkingDirectory("jobA", 0)
if workDir != "./test" {
t.Errorf("Expected current directory as ./test working directory, got %s", workDir)
}
}
func TestWorkingDirectoryUsesJobDefaultsIfNoStepDefault(t *testing.T) {
sample := `
jobs:
jobA:
runs-on: default
defaults:
run:
working-directory: ./test-job
steps:
- run: echo "test"
`
workflow, _ := FromYamlBytes([]byte(sample))
workDir := workflow.GetWorkingDirectory("jobA", 0)
if workDir != "./test-job" {
t.Errorf("Expected current directory as ./test working directory, got %s", workDir)
}
}
func TestWorkingDirectoryFromStepOverridesJobDefault(t *testing.T) {
sample := `
jobs:
jobA:
runs-on: default
defaults:
run:
working-directory: ./test-job
steps:
- run: echo "test"
working-directory: ./test-step
`
workflow, _ := FromYamlBytes([]byte(sample))
workDir := workflow.GetWorkingDirectory("jobA", 0)
if workDir != "./test-step" {
t.Errorf("Expected current directory as ./test working directory, got %s", workDir)
}
}