Skip to content

Commit

Permalink
Switch to interface{} instead of map[string]... (#700)
Browse files Browse the repository at this point in the history
* fix: change `env` to be an interface

allows to use GitHub functions like `fromJson()`

* fix: change matrix to an interface instead of map

This allows to use GitHub functions like `fromJson()` to create dynamic
matrixes

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
Ryan (hackercat) and mergify[bot] authored Jun 6, 2021
1 parent fa93f4d commit 33ccfa6
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 20 deletions.
88 changes: 71 additions & 17 deletions pkg/model/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ type Job struct {
Name string `yaml:"name"`
RawNeeds yaml.Node `yaml:"needs"`
RawRunsOn yaml.Node `yaml:"runs-on"`
Env map[string]string `yaml:"env"`
Env interface{} `yaml:"env"`
If yaml.Node `yaml:"if"`
Steps []*Step `yaml:"steps"`
TimeoutMinutes int64 `yaml:"timeout-minutes"`
Expand All @@ -70,9 +70,9 @@ type Job struct {

// Strategy for the job
type Strategy struct {
FailFast bool `yaml:"fail-fast"`
MaxParallel int `yaml:"max-parallel"`
Matrix map[string][]interface{} `yaml:"matrix"`
FailFast bool `yaml:"fail-fast"`
MaxParallel int `yaml:"max-parallel"`
Matrix interface{} `yaml:"matrix"`
}

// Default settings that will apply to all steps in the job or workflow
Expand Down Expand Up @@ -148,23 +148,75 @@ func (j *Job) RunsOn() []string {
return nil
}

func environment(e interface{}) map[string]string {
env := make(map[string]string)
switch t := e.(type) {
case map[string]interface{}:
for k, v := range t {
switch t := v.(type) {
case string:
env[k] = t
case interface{}:
env[k] = ""
}
}
case map[string]string:
for k, v := range e.(map[string]string) {
env[k] = v
}
}
return env
}

func (j *Job) Environment() map[string]string {
return environment(j.Env)
}

func (j *Job) Matrix() map[string][]interface{} {
a := reflect.ValueOf(j.Strategy.Matrix)
if a.Type().Kind() == reflect.Map {
output := make(map[string][]interface{})
for _, e := range a.MapKeys() {
v := a.MapIndex(e)
switch t := v.Interface().(type) {
case []interface{}:
output[e.String()] = t
case interface{}:
var in []interface{}
in = append(in, t)
output[e.String()] = in
}
}
return output
}
return nil
}

// GetMatrixes returns the matrix cross product
func (j *Job) GetMatrixes() []map[string]interface{} {
matrixes := make([]map[string]interface{}, 0)
if j.Strategy != nil {
m := j.Matrix()
includes := make([]map[string]interface{}, 0)
for _, v := range j.Strategy.Matrix["include"] {
includes = append(includes, v.(map[string]interface{}))
for _, v := range m["include"] {
switch t := v.(type) {
case []interface{}:
for _, i := range t {
includes = append(includes, i.(map[string]interface{}))
}
case interface{}:
includes = append(includes, v.(map[string]interface{}))
}
}
delete(j.Strategy.Matrix, "include")
delete(m, "include")

excludes := make([]map[string]interface{}, 0)
for _, v := range j.Strategy.Matrix["exclude"] {
for _, v := range m["exclude"] {
excludes = append(excludes, v.(map[string]interface{}))
}
delete(j.Strategy.Matrix, "exclude")
delete(m, "exclude")

matrixProduct := common.CartesianProduct(j.Strategy.Matrix)
matrixProduct := common.CartesianProduct(m)

MATRIX:
for _, matrix := range matrixProduct {
Expand Down Expand Up @@ -217,7 +269,7 @@ type Step struct {
Run string `yaml:"run"`
WorkingDirectory string `yaml:"working-directory"`
Shell string `yaml:"shell"`
Env map[string]string `yaml:"env"`
Env interface{} `yaml:"env"`
With map[string]string `yaml:"with"`
ContinueOnError bool `yaml:"continue-on-error"`
TimeoutMinutes int64 `yaml:"timeout-minutes"`
Expand All @@ -235,18 +287,20 @@ func (s *Step) String() string {
return s.ID
}

func (s *Step) Environment() map[string]string {
return environment(s.Env)
}

// GetEnv gets the env for a step
func (s *Step) GetEnv() map[string]string {
rtnEnv := make(map[string]string)
for k, v := range s.Env {
rtnEnv[k] = v
}
env := s.Environment()

for k, v := range s.With {
envKey := regexp.MustCompile("[^A-Z0-9-]").ReplaceAllString(strings.ToUpper(k), "_")
envKey = fmt.Sprintf("INPUT_%s", strings.ToUpper(envKey))
rtnEnv[envKey] = v
env[envKey] = v
}
return rtnEnv
return env
}

// ShellCommand returns the command for the shell
Expand Down
2 changes: 1 addition & 1 deletion pkg/runner/run_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ type stepResult struct {
// GetEnv returns the env for the context
func (rc *RunContext) GetEnv() map[string]string {
if rc.Env == nil {
rc.Env = mergeMaps(rc.Config.Env, rc.Run.Workflow.Env, rc.Run.Job().Env)
rc.Env = mergeMaps(rc.Config.Env, rc.Run.Workflow.Env, rc.Run.Job().Environment())
}
rc.Env["ACT"] = "true"
return rc.Env
Expand Down
6 changes: 4 additions & 2 deletions pkg/runner/step_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -574,13 +574,15 @@ func (sc *StepContext) execAsComposite(ctx context.Context, step *model.Step, _
stepClone.Env = make(map[string]string)
}
actionPath := filepath.Join(containerActionDir, actionName)
stepClone.Env["GITHUB_ACTION_PATH"] = actionPath

env := stepClone.Environment()
env["GITHUB_ACTION_PATH"] = actionPath
stepClone.Run = strings.ReplaceAll(stepClone.Run, "${{ github.action_path }}", actionPath)

stepContext := StepContext{
RunContext: rcClone,
Step: &stepClone,
Env: mergeMaps(sc.Env, stepClone.Env),
Env: mergeMaps(sc.Env, env),
}

// Interpolate the outer inputs into the composite step with items
Expand Down

0 comments on commit 33ccfa6

Please sign in to comment.