initial support for expressons
Signed-off-by: Casey Lee <cplee@nektos.com>
This commit is contained in:
parent
09773f7c5c
commit
73559207c7
10 changed files with 286 additions and 108 deletions
|
@ -33,7 +33,8 @@ func TestNewDockerRunExecutor(t *testing.T) {
|
|||
ctx := common.WithLogger(context.Background(), logger)
|
||||
|
||||
runner := NewDockerRunExecutor(NewDockerRunExecutorInput{
|
||||
Image: "hello-world",
|
||||
Image: "hello-world",
|
||||
Stdout: buf,
|
||||
})
|
||||
|
||||
puller := NewDockerPullExecutor(NewDockerPullExecutorInput{
|
||||
|
@ -44,7 +45,8 @@ func TestNewDockerRunExecutor(t *testing.T) {
|
|||
err := pipeline(ctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
expected := `docker pull hello-worlddocker run image=hello-world entrypoint=[] cmd=[]Hello from Docker!`
|
||||
actual := buf.String()
|
||||
assert.Equal(t, expected, actual[:len(expected)])
|
||||
assert.Contains(t, actual, `docker pull hello-world`)
|
||||
assert.Contains(t, actual, `docker run image=hello-world entrypoint=[] cmd=[]`)
|
||||
assert.Contains(t, actual, `Hello from Docker!`)
|
||||
}
|
||||
|
|
|
@ -62,6 +62,14 @@ type Job struct {
|
|||
TimeoutMinutes int64 `yaml:"timeout-minutes"`
|
||||
Container *ContainerSpec `yaml:"container"`
|
||||
Services map[string]*ContainerSpec `yaml:"services"`
|
||||
Strategy *Strategy `yaml:"strategy"`
|
||||
}
|
||||
|
||||
// Strategy for the job
|
||||
type Strategy struct {
|
||||
FailFast bool `yaml:"fail-fast"`
|
||||
MaxParallel int `yaml:"max-parallel"`
|
||||
Matrix map[string][]interface{} `yaml:"matrix"`
|
||||
}
|
||||
|
||||
// Needs list for Job
|
||||
|
|
|
@ -64,10 +64,7 @@ func (rc *RunContext) setEnv(ctx context.Context, kvPairs map[string]string, arg
|
|||
}
|
||||
func (rc *RunContext) setOutput(ctx context.Context, kvPairs map[string]string, arg string) {
|
||||
common.Logger(ctx).Infof(" \U00002699 ::set-output:: %s=%s", kvPairs["name"], arg)
|
||||
if rc.Outputs == nil {
|
||||
rc.Outputs = make(map[string]string)
|
||||
}
|
||||
rc.Outputs[kvPairs["name"]] = arg
|
||||
rc.StepResults[rc.CurrentStep].Outputs[kvPairs["name"]] = arg
|
||||
}
|
||||
func (rc *RunContext) addPath(ctx context.Context, arg string) {
|
||||
common.Logger(ctx).Infof(" \U00002699 ::add-path:: %s", arg)
|
||||
|
|
|
@ -21,10 +21,15 @@ func TestSetOutput(t *testing.T) {
|
|||
assert := assert.New(t)
|
||||
ctx := context.Background()
|
||||
rc := new(RunContext)
|
||||
rc.StepResults = make(map[string]*stepResult)
|
||||
handler := rc.commandHandler(ctx)
|
||||
|
||||
rc.CurrentStep = "my-step"
|
||||
rc.StepResults[rc.CurrentStep] = &stepResult{
|
||||
Outputs: make(map[string]string),
|
||||
}
|
||||
handler("::set-output name=x::valz\n")
|
||||
assert.Equal("valz", rc.Outputs["x"])
|
||||
assert.Equal("valz", rc.StepResults["my-step"].Outputs["x"])
|
||||
}
|
||||
|
||||
func TestAddpath(t *testing.T) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/nektos/act/pkg/model"
|
||||
"github.com/robertkrimen/otto"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/godo.v2/glob"
|
||||
|
@ -33,10 +34,25 @@ func (rc *RunContext) NewExpressionEvaluator() ExpressionEvaluator {
|
|||
}
|
||||
}
|
||||
|
||||
// NewStepExpressionEvaluator creates a new evaluator
|
||||
func (rc *RunContext) NewStepExpressionEvaluator(step *model.Step) ExpressionEvaluator {
|
||||
vm := rc.newVM()
|
||||
configers := []func(*otto.Otto){
|
||||
rc.vmEnv(step),
|
||||
}
|
||||
for _, configer := range configers {
|
||||
configer(vm)
|
||||
}
|
||||
|
||||
return &expressionEvaluator{
|
||||
vm,
|
||||
}
|
||||
}
|
||||
|
||||
// ExpressionEvaluator is the interface for evaluating expressions
|
||||
type ExpressionEvaluator interface {
|
||||
Evaluate(string) (string, error)
|
||||
Interpolate(string) (string, error)
|
||||
Interpolate(string) string
|
||||
}
|
||||
|
||||
type expressionEvaluator struct {
|
||||
|
@ -51,7 +67,7 @@ func (ee *expressionEvaluator) Evaluate(in string) (string, error) {
|
|||
return val.ToString()
|
||||
}
|
||||
|
||||
func (ee *expressionEvaluator) Interpolate(in string) (string, error) {
|
||||
func (ee *expressionEvaluator) Interpolate(in string) string {
|
||||
errList := make([]error, 0)
|
||||
out := pattern.ReplaceAllStringFunc(in, func(match string) string {
|
||||
expression := strings.TrimPrefix(strings.TrimSuffix(match, suffix), prefix)
|
||||
|
@ -62,9 +78,10 @@ func (ee *expressionEvaluator) Interpolate(in string) (string, error) {
|
|||
return evaluated
|
||||
})
|
||||
if len(errList) > 0 {
|
||||
return "", fmt.Errorf("Unable to interpolate string '%s' - %v", in, errList)
|
||||
logrus.Errorf("Unable to interpolate string '%s' - %v", in, errList)
|
||||
return in
|
||||
}
|
||||
return out, nil
|
||||
return out
|
||||
}
|
||||
|
||||
func (rc *RunContext) newVM() *otto.Otto {
|
||||
|
@ -76,16 +93,19 @@ func (rc *RunContext) newVM() *otto.Otto {
|
|||
vmJoin,
|
||||
vmToJSON,
|
||||
vmAlways,
|
||||
vmCancelled,
|
||||
rc.vmHashFiles(),
|
||||
rc.vmCancelled(),
|
||||
rc.vmSuccess(),
|
||||
rc.vmFailure(),
|
||||
rc.vmHashFiles(),
|
||||
|
||||
rc.vmGithub(),
|
||||
rc.vmEnv(),
|
||||
rc.vmJob(),
|
||||
rc.vmSteps(),
|
||||
rc.vmRunner(),
|
||||
|
||||
rc.vmSecrets(),
|
||||
rc.vmStrategy(),
|
||||
rc.vmMatrix(),
|
||||
}
|
||||
vm := otto.New()
|
||||
for _, configer := range configers {
|
||||
|
@ -183,14 +203,14 @@ func (rc *RunContext) vmHashFiles() func(*otto.Otto) {
|
|||
func (rc *RunContext) vmSuccess() func(*otto.Otto) {
|
||||
return func(vm *otto.Otto) {
|
||||
_ = vm.Set("success", func() bool {
|
||||
return !rc.PriorStepFailed
|
||||
return rc.getJobContext().Status == "success"
|
||||
})
|
||||
}
|
||||
}
|
||||
func (rc *RunContext) vmFailure() func(*otto.Otto) {
|
||||
return func(vm *otto.Otto) {
|
||||
_ = vm.Set("failure", func() bool {
|
||||
return rc.PriorStepFailed
|
||||
return rc.getJobContext().Status == "failure"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -200,55 +220,31 @@ func vmAlways(vm *otto.Otto) {
|
|||
return true
|
||||
})
|
||||
}
|
||||
func vmCancelled(vm *otto.Otto) {
|
||||
_ = vm.Set("cancelled", func() bool {
|
||||
return false
|
||||
})
|
||||
func (rc *RunContext) vmCancelled() func(vm *otto.Otto) {
|
||||
return func(vm *otto.Otto) {
|
||||
_ = vm.Set("cancelled", func() bool {
|
||||
return rc.getJobContext().Status == "cancelled"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (rc *RunContext) vmGithub() func(*otto.Otto) {
|
||||
github := map[string]interface{}{
|
||||
"event": make(map[string]interface{}),
|
||||
"event_path": "/github/workflow/event.json",
|
||||
"workflow": rc.Run.Workflow.Name,
|
||||
"run_id": "1",
|
||||
"run_number": "1",
|
||||
"actor": "nektos/act",
|
||||
|
||||
// TODO
|
||||
"repository": "",
|
||||
"event_name": "",
|
||||
"sha": "",
|
||||
"ref": "",
|
||||
"head_ref": "",
|
||||
"base_ref": "",
|
||||
"token": "",
|
||||
"workspace": rc.Config.Workdir,
|
||||
"action": "",
|
||||
}
|
||||
|
||||
err := json.Unmarshal([]byte(rc.EventJSON), github["event"])
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
github := rc.getGithubContext()
|
||||
|
||||
return func(vm *otto.Otto) {
|
||||
_ = vm.Set("github", github)
|
||||
}
|
||||
}
|
||||
|
||||
func (rc *RunContext) vmEnv() func(*otto.Otto) {
|
||||
env := map[string]interface{}{}
|
||||
// TODO
|
||||
|
||||
func (rc *RunContext) vmEnv(step *model.Step) func(*otto.Otto) {
|
||||
return func(vm *otto.Otto) {
|
||||
env := rc.StepEnv(step)
|
||||
_ = vm.Set("env", env)
|
||||
}
|
||||
}
|
||||
|
||||
func (rc *RunContext) vmJob() func(*otto.Otto) {
|
||||
job := map[string]interface{}{}
|
||||
// TODO
|
||||
job := rc.getJobContext()
|
||||
|
||||
return func(vm *otto.Otto) {
|
||||
_ = vm.Set("job", job)
|
||||
|
@ -256,8 +252,7 @@ func (rc *RunContext) vmJob() func(*otto.Otto) {
|
|||
}
|
||||
|
||||
func (rc *RunContext) vmSteps() func(*otto.Otto) {
|
||||
steps := map[string]interface{}{}
|
||||
// TODO
|
||||
steps := rc.getStepsContext()
|
||||
|
||||
return func(vm *otto.Otto) {
|
||||
_ = vm.Set("steps", steps)
|
||||
|
@ -275,3 +270,28 @@ func (rc *RunContext) vmRunner() func(*otto.Otto) {
|
|||
_ = vm.Set("runner", runner)
|
||||
}
|
||||
}
|
||||
|
||||
func (rc *RunContext) vmSecrets() func(*otto.Otto) {
|
||||
secrets := make(map[string]string)
|
||||
return func(vm *otto.Otto) {
|
||||
_ = vm.Set("secrets", secrets)
|
||||
}
|
||||
}
|
||||
|
||||
func (rc *RunContext) vmStrategy() func(*otto.Otto) {
|
||||
job := rc.Run.Job()
|
||||
strategy := make(map[string]interface{})
|
||||
if job.Strategy != nil {
|
||||
strategy["fail-fast"] = job.Strategy.FailFast
|
||||
strategy["max-parallel"] = job.Strategy.MaxParallel
|
||||
}
|
||||
return func(vm *otto.Otto) {
|
||||
_ = vm.Set("strategy", strategy)
|
||||
}
|
||||
}
|
||||
|
||||
func (rc *RunContext) vmMatrix() func(*otto.Otto) {
|
||||
return func(vm *otto.Otto) {
|
||||
_ = vm.Set("matrix", rc.Matrix)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,28 @@ func TestEvaluate(t *testing.T) {
|
|||
JobID: "job1",
|
||||
Workflow: &model.Workflow{
|
||||
Name: "test-workflow",
|
||||
Jobs: map[string]*model.Job{
|
||||
"job1": &model.Job{
|
||||
Strategy: &model.Strategy{
|
||||
Matrix: map[string][]interface{}{
|
||||
"os": []interface{}{"Linux", "Windows"},
|
||||
"foo": []interface{}{"bar", "baz"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Matrix: map[string]interface{}{
|
||||
"os": "Linux",
|
||||
"foo": "bar",
|
||||
},
|
||||
StepResults: map[string]*stepResult{
|
||||
"id1": &stepResult{
|
||||
Outputs: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
Success: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -51,7 +73,11 @@ func TestEvaluate(t *testing.T) {
|
|||
{"github.actor", "nektos/act", ""},
|
||||
{"github.run_id", "1", ""},
|
||||
{"github.run_number", "1", ""},
|
||||
{"job.status", "success", ""},
|
||||
{"steps.id1.outputs.foo", "bar", ""},
|
||||
{"runner.os", "Linux", ""},
|
||||
{"matrix.os", "Linux", ""},
|
||||
{"matrix.foo", "bar", ""},
|
||||
}
|
||||
|
||||
for _, table := range tables {
|
||||
|
@ -60,10 +86,10 @@ func TestEvaluate(t *testing.T) {
|
|||
out, err := ee.Evaluate(table.in)
|
||||
if table.errMesg == "" {
|
||||
assert.NoError(err, table.in)
|
||||
assert.Equal(table.out, out)
|
||||
assert.Equal(table.out, out, table.in)
|
||||
} else {
|
||||
assert.Error(err)
|
||||
assert.Equal(table.errMesg, err.Error())
|
||||
assert.Error(err, table.in)
|
||||
assert.Equal(table.errMesg, err.Error(), table.in)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -79,13 +105,15 @@ func TestInterpolate(t *testing.T) {
|
|||
JobID: "job1",
|
||||
Workflow: &model.Workflow{
|
||||
Name: "test-workflow",
|
||||
Jobs: map[string]*model.Job{
|
||||
"job1": &model.Job{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
ee := rc.NewExpressionEvaluator()
|
||||
|
||||
out, err := ee.Interpolate(" ${{1}} to ${{2}} ")
|
||||
out := ee.Interpolate(" ${{1}} to ${{2}} ")
|
||||
|
||||
assert.NoError(err)
|
||||
assert.Equal(" 1 to 2 ", out)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"archive/tar"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -17,19 +18,26 @@ import (
|
|||
|
||||
"github.com/nektos/act/pkg/common"
|
||||
"github.com/nektos/act/pkg/model"
|
||||
"github.com/sirupsen/logrus"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// RunContext contains info about current job
|
||||
type RunContext struct {
|
||||
Config *Config
|
||||
Run *model.Run
|
||||
EventJSON string
|
||||
Env map[string]string
|
||||
Outputs map[string]string
|
||||
Tempdir string
|
||||
PriorStepFailed bool
|
||||
ExtraPath []string
|
||||
Config *Config
|
||||
Matrix map[string]interface{}
|
||||
Run *model.Run
|
||||
EventJSON string
|
||||
Env map[string]string
|
||||
Tempdir string
|
||||
ExtraPath []string
|
||||
CurrentStep string
|
||||
StepResults map[string]*stepResult
|
||||
}
|
||||
|
||||
type stepResult struct {
|
||||
Success bool `json:"success"`
|
||||
Outputs map[string]string `json:"outputs"`
|
||||
}
|
||||
|
||||
// GetEnv returns the env for the context
|
||||
|
@ -59,14 +67,18 @@ func (rc *RunContext) Executor() common.Executor {
|
|||
}
|
||||
s := step
|
||||
steps = append(steps, func(ctx context.Context) error {
|
||||
rc.CurrentStep = s.ID
|
||||
rc.StepResults[rc.CurrentStep] = &stepResult{
|
||||
Success: true,
|
||||
Outputs: make(map[string]string),
|
||||
}
|
||||
common.Logger(ctx).Infof("\u2B50 Run %s", s)
|
||||
err := rc.newStepExecutor(s)(ctx)
|
||||
if err == nil {
|
||||
common.Logger(ctx).Infof(" \u2705 Success - %s", s)
|
||||
rc.PriorStepFailed = false
|
||||
} else {
|
||||
common.Logger(ctx).Errorf(" \u274C Failure - %s", s)
|
||||
rc.PriorStepFailed = true
|
||||
rc.StepResults[rc.CurrentStep].Success = false
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
@ -207,3 +219,110 @@ func trimToLen(s string, l int) string {
|
|||
}
|
||||
return s
|
||||
}
|
||||
|
||||
type jobContext struct {
|
||||
Status string `json:"status"`
|
||||
Container struct {
|
||||
ID string `json:"id"`
|
||||
Network string `json:"network"`
|
||||
} `json:"container"`
|
||||
Services map[string]struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"services"`
|
||||
}
|
||||
|
||||
func (rc *RunContext) getJobContext() *jobContext {
|
||||
jobStatus := "success"
|
||||
for _, stepStatus := range rc.StepResults {
|
||||
if !stepStatus.Success {
|
||||
jobStatus = "failure"
|
||||
break
|
||||
}
|
||||
}
|
||||
return &jobContext{
|
||||
Status: jobStatus,
|
||||
}
|
||||
}
|
||||
|
||||
func (rc *RunContext) getStepsContext() map[string]*stepResult {
|
||||
return rc.StepResults
|
||||
}
|
||||
|
||||
type githubContext struct {
|
||||
Event map[string]interface{} `json:"event"`
|
||||
EventPath string `json:"event_path"`
|
||||
Workflow string `json:"workflow"`
|
||||
RunID string `json:"run_id"`
|
||||
RunNumber string `json:"run_number"`
|
||||
Actor string `json:"actor"`
|
||||
Repository string `json:"repository"`
|
||||
EventName string `json:"event_name"`
|
||||
Sha string `json:"sha"`
|
||||
Ref string `json:"ref"`
|
||||
HeadRef string `json:"head_ref"`
|
||||
BaseRef string `json:"base_ref"`
|
||||
Token string `json:"token"`
|
||||
Workspace string `json:"workspace"`
|
||||
Action string `json:"action"`
|
||||
}
|
||||
|
||||
func (rc *RunContext) getGithubContext() *githubContext {
|
||||
ghc := &githubContext{
|
||||
Event: make(map[string]interface{}),
|
||||
EventPath: "/github/workflow/event.json",
|
||||
Workflow: rc.Run.Workflow.Name,
|
||||
RunID: "1",
|
||||
RunNumber: "1",
|
||||
Actor: "nektos/act",
|
||||
|
||||
EventName: rc.Config.EventName,
|
||||
Token: os.Getenv("GITHUB_TOKEN"),
|
||||
Workspace: "/github/workspace",
|
||||
Action: rc.CurrentStep,
|
||||
}
|
||||
|
||||
repoPath := rc.Config.Workdir
|
||||
repo, err := common.FindGithubRepo(repoPath)
|
||||
if err != nil {
|
||||
log.Warningf("unable to get git repo: %v", err)
|
||||
} else {
|
||||
ghc.Repository = repo
|
||||
}
|
||||
|
||||
_, sha, err := common.FindGitRevision(repoPath)
|
||||
if err != nil {
|
||||
log.Warningf("unable to get git revision: %v", err)
|
||||
} else {
|
||||
ghc.Sha = sha
|
||||
}
|
||||
|
||||
ref, err := common.FindGitRef(repoPath)
|
||||
if err != nil {
|
||||
log.Warningf("unable to get git ref: %v", err)
|
||||
} else {
|
||||
log.Debugf("using github ref: %s", ref)
|
||||
ghc.Ref = ref
|
||||
}
|
||||
err = json.Unmarshal([]byte(rc.EventJSON), &ghc.Event)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
return ghc
|
||||
}
|
||||
|
||||
func (rc *RunContext) withGithubEnv(env map[string]string) map[string]string {
|
||||
github := rc.getGithubContext()
|
||||
env["HOME"] = "/github/home"
|
||||
env["GITHUB_WORKFLOW"] = github.Workflow
|
||||
env["GITHUB_RUN_ID"] = github.RunID
|
||||
env["GITHUB_RUN_NUMBER"] = github.RunNumber
|
||||
env["GITHUB_ACTION"] = github.Action
|
||||
env["GITHUB_ACTOR"] = github.Actor
|
||||
env["GITHUB_REPOSITORY"] = github.Repository
|
||||
env["GITHUB_EVENT_NAME"] = github.EventName
|
||||
env["GITHUB_EVENT_PATH"] = github.EventPath
|
||||
env["GITHUB_WORKSPACE"] = github.Workspace
|
||||
env["GITHUB_SHA"] = github.Sha
|
||||
env["GITHUB_REF"] = github.Ref
|
||||
return env
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
// Runner provides capabilities to run GitHub actions
|
||||
type Runner interface {
|
||||
NewPlanExecutor(plan *model.Plan) common.Executor
|
||||
NewRunExecutor(run *model.Run) common.Executor
|
||||
NewRunExecutor(run *model.Run, matrix map[string]interface{}) common.Executor
|
||||
}
|
||||
|
||||
// Config contains the config for a new runner
|
||||
|
@ -53,7 +53,18 @@ func (runner *runnerImpl) NewPlanExecutor(plan *model.Plan) common.Executor {
|
|||
for _, stage := range plan.Stages {
|
||||
stageExecutor := make([]common.Executor, 0)
|
||||
for _, run := range stage.Runs {
|
||||
stageExecutor = append(stageExecutor, runner.NewRunExecutor(run))
|
||||
// TODO - don't just grab first index of each dimension
|
||||
matrix := make(map[string]interface{})
|
||||
if run.Job().Strategy != nil {
|
||||
for mkey, mvals := range run.Job().Strategy.Matrix {
|
||||
if mkey == "include" || mkey == "exclude" {
|
||||
continue
|
||||
}
|
||||
matrix[mkey] = mvals[0]
|
||||
}
|
||||
}
|
||||
|
||||
stageExecutor = append(stageExecutor, runner.NewRunExecutor(run, matrix))
|
||||
}
|
||||
pipeline = append(pipeline, common.NewParallelExecutor(stageExecutor...))
|
||||
}
|
||||
|
@ -61,11 +72,13 @@ func (runner *runnerImpl) NewPlanExecutor(plan *model.Plan) common.Executor {
|
|||
return common.NewPipelineExecutor(pipeline...)
|
||||
}
|
||||
|
||||
func (runner *runnerImpl) NewRunExecutor(run *model.Run) common.Executor {
|
||||
func (runner *runnerImpl) NewRunExecutor(run *model.Run, matrix map[string]interface{}) common.Executor {
|
||||
rc := new(RunContext)
|
||||
rc.Config = runner.config
|
||||
rc.Run = run
|
||||
rc.EventJSON = runner.eventJSON
|
||||
rc.StepResults = make(map[string]*stepResult)
|
||||
rc.Matrix = matrix
|
||||
return func(ctx context.Context) error {
|
||||
ctx = WithJobLogger(ctx, rc.Run.String())
|
||||
return rc.Executor()(ctx)
|
||||
|
|
|
@ -16,11 +16,16 @@ import (
|
|||
)
|
||||
|
||||
func (rc *RunContext) newStepExecutor(step *model.Step) common.Executor {
|
||||
ee := rc.NewStepExpressionEvaluator(step)
|
||||
job := rc.Run.Job()
|
||||
containerSpec := new(model.ContainerSpec)
|
||||
containerSpec.Env = rc.StepEnv(step)
|
||||
containerSpec.Env = rc.withGithubEnv(rc.StepEnv(step))
|
||||
containerSpec.Name = rc.createContainerName(step.ID)
|
||||
|
||||
for k, v := range containerSpec.Env {
|
||||
containerSpec.Env[k] = ee.Interpolate(v)
|
||||
}
|
||||
|
||||
switch step.Type() {
|
||||
case model.StepTypeRun:
|
||||
if job.Container != nil {
|
||||
|
@ -29,7 +34,7 @@ func (rc *RunContext) newStepExecutor(step *model.Step) common.Executor {
|
|||
containerSpec.Volumes = job.Container.Volumes
|
||||
containerSpec.Options = job.Container.Options
|
||||
} else {
|
||||
containerSpec.Image = platformImage(job.RunsOn)
|
||||
containerSpec.Image = platformImage(ee.Interpolate(job.RunsOn))
|
||||
}
|
||||
return common.NewPipelineExecutor(
|
||||
rc.setupShellCommand(containerSpec, step.Shell, step.Run),
|
||||
|
@ -97,44 +102,11 @@ func applyWith(containerSpec *model.ContainerSpec, step *model.Step) common.Exec
|
|||
|
||||
// StepEnv returns the env for a step
|
||||
func (rc *RunContext) StepEnv(step *model.Step) map[string]string {
|
||||
env := make(map[string]string)
|
||||
env["HOME"] = "/github/home"
|
||||
env["GITHUB_WORKFLOW"] = rc.Run.Workflow.Name
|
||||
env["GITHUB_RUN_ID"] = "1"
|
||||
env["GITHUB_RUN_NUMBER"] = "1"
|
||||
env["GITHUB_ACTION"] = step.ID
|
||||
env["GITHUB_ACTOR"] = "nektos/act"
|
||||
|
||||
repoPath := rc.Config.Workdir
|
||||
repo, err := common.FindGithubRepo(repoPath)
|
||||
if err != nil {
|
||||
log.Warningf("unable to get git repo: %v", err)
|
||||
} else {
|
||||
env["GITHUB_REPOSITORY"] = repo
|
||||
}
|
||||
env["GITHUB_EVENT_NAME"] = rc.Config.EventName
|
||||
env["GITHUB_EVENT_PATH"] = "/github/workflow/event.json"
|
||||
env["GITHUB_WORKSPACE"] = "/github/workspace"
|
||||
|
||||
_, rev, err := common.FindGitRevision(repoPath)
|
||||
if err != nil {
|
||||
log.Warningf("unable to get git revision: %v", err)
|
||||
} else {
|
||||
env["GITHUB_SHA"] = rev
|
||||
}
|
||||
|
||||
ref, err := common.FindGitRef(repoPath)
|
||||
if err != nil {
|
||||
log.Warningf("unable to get git ref: %v", err)
|
||||
} else {
|
||||
log.Debugf("using github ref: %s", ref)
|
||||
env["GITHUB_REF"] = ref
|
||||
}
|
||||
job := rc.Run.Job()
|
||||
if job.Container != nil {
|
||||
return mergeMaps(rc.GetEnv(), job.Container.Env, step.GetEnv(), env)
|
||||
return mergeMaps(rc.GetEnv(), job.Container.Env, step.GetEnv())
|
||||
}
|
||||
return mergeMaps(rc.GetEnv(), step.GetEnv(), env)
|
||||
return mergeMaps(rc.GetEnv(), step.GetEnv())
|
||||
}
|
||||
|
||||
func (rc *RunContext) setupShellCommand(containerSpec *model.ContainerSpec, shell string, run string) common.Executor {
|
||||
|
|
14
pkg/runner/testdata/matrix/push.yml
vendored
Normal file
14
pkg/runner/testdata/matrix/push.yml
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
name: matrix
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- run: echo ${NODE_VERSION} | grep 4
|
||||
env:
|
||||
NODE_VERSION: ${{ matrix.node }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-18.04, macos-latest]
|
||||
node: [4, 6, 8, 10]
|
Loading…
Reference in a new issue