diff --git a/pkg/container/docker_run.go b/pkg/container/docker_run.go index 63d8392..81a6464 100644 --- a/pkg/container/docker_run.go +++ b/pkg/container/docker_run.go @@ -70,7 +70,7 @@ func (cr *containerReference) Create() common.Executor { } func (cr *containerReference) Start(attach bool) common.Executor { return common. - NewDebugExecutor("%sdocker run image=%s entrypoint=%+q cmd=%+q", logPrefix, cr.input.Image, cr.input.Entrypoint, cr.input.Cmd). + NewInfoExecutor("%sdocker run image=%s entrypoint=%+q cmd=%+q", logPrefix, cr.input.Image, cr.input.Entrypoint, cr.input.Cmd). Then( common.NewPipelineExecutor( cr.connect(), @@ -173,9 +173,9 @@ func (cr *containerReference) remove() common.Executor { if err != nil { return errors.WithStack(err) } - cr.id = "" logger.Debugf("Removed container: %v", cr.id) + cr.id = "" return nil } } diff --git a/pkg/runner/run_context.go b/pkg/runner/run_context.go index 39b3737..8173725 100644 --- a/pkg/runner/run_context.go +++ b/pkg/runner/run_context.go @@ -98,6 +98,10 @@ func (rc *RunContext) startJobContainer() common.Executor { Name: "workflow/event.json", Mode: 644, Body: rc.EventJSON, + }, &container.FileEntry{ + Name: "home/.actions/.keep", + Mode: 644, + Body: "", }), )(ctx) } @@ -202,68 +206,14 @@ func mergeMaps(maps ...map[string]string) map[string]string { return rtnMap } -/* -func (rc *RunContext) runContainer(containerSpec *model.ContainerSpec) common.Executor { - return func(ctx context.Context) error { - ghReader, err := rc.createGithubTarball() - if err != nil { - return err - } - - envList := make([]string, 0) - for k, v := range containerSpec.Env { - envList = append(envList, fmt.Sprintf("%s=%s", k, v)) - } - var cmd, entrypoint []string - if containerSpec.Args != "" { - cmd = strings.Fields(rc.ExprEval.Interpolate(containerSpec.Args)) - } - if containerSpec.Entrypoint != "" { - entrypoint = strings.Fields(rc.ExprEval.Interpolate(containerSpec.Entrypoint)) - } - - rawLogger := common.Logger(ctx).WithField("raw_output", true) - logWriter := common.NewLineWriter(rc.commandHandler(ctx), func(s string) { - if rc.Config.LogOutput { - rawLogger.Infof(s) - } else { - rawLogger.Debugf(s) - } - }) - - c := container.NewContainer(&container.NewContainerInput{ - Cmd: cmd, - Entrypoint: entrypoint, - Image: containerSpec.Image, - WorkingDir: "/github/workspace", - Env: envList, - Name: containerSpec.Name, - Binds: []string{ - fmt.Sprintf("%s:%s", rc.Config.Workdir, "/github/workspace"), - fmt.Sprintf("%s:%s", rc.Tempdir, "/github/home"), - fmt.Sprintf("%s:%s", "/var/run/docker.sock", "/var/run/docker.sock"), - }, - Stdout: logWriter, - Stderr: logWriter, - }) - - return c.Create(). - Then(c.Copy("/github", ghReader)). - Then(c.Start()). - Finally(c.Remove().IfBool(!rc.Config.ReuseContainers))(ctx) - - } -} - -*/ - func createContainerName(parts ...string) string { name := make([]string, 0) pattern := regexp.MustCompile("[^a-zA-Z0-9]") + partLen := (30 / len(parts)) - 1 for _, part := range parts { - name = append(name, pattern.ReplaceAllString(part, "-")) + name = append(name, trimToLen(pattern.ReplaceAllString(part, "-"), partLen)) } - return trimToLen(strings.Join(name, "-"), 30) + return strings.Join(name, "-") } func trimToLen(s string, l int) string { diff --git a/pkg/runner/step_context.go b/pkg/runner/step_context.go index 0e4c493..2a252d0 100644 --- a/pkg/runner/step_context.go +++ b/pkg/runner/step_context.go @@ -3,6 +3,8 @@ package runner import ( "context" "fmt" + "os" + "path/filepath" "regexp" "strings" @@ -18,6 +20,7 @@ type StepContext struct { Step *model.Step Env map[string]string Cmd []string + Action *model.Action } func (sc *StepContext) execJobContainer() common.Executor { @@ -45,39 +48,37 @@ func (sc *StepContext) Executor() common.Executor { sc.runUsesContainer(), ) + case model.StepTypeUsesActionLocal: + return common.NewPipelineExecutor( + sc.setupEnv(), + sc.setupAction(), + sc.runAction(), + ) /* - case model.StepTypeUsesActionLocal: + case model.StepTypeUsesActionRemote: + remoteAction := newRemoteAction(step.Uses) + if remoteAction.Org == "actions" && remoteAction.Repo == "checkout" { + return func(ctx context.Context) error { + common.Logger(ctx).Debugf("Skipping actions/checkout") + return nil + } + } + cloneDir, err := ioutil.TempDir(rc.Tempdir, remoteAction.Repo) + if err != nil { + return common.NewErrorExecutor(err) + } return common.NewPipelineExecutor( + common.NewGitCloneExecutor(common.NewGitCloneExecutorInput{ + URL: remoteAction.CloneURL(), + Ref: remoteAction.Ref, + Dir: cloneDir, + }), sc.setupEnv(), sc.setupAction(), applyWith(containerSpec, step), rc.pullImage(containerSpec), rc.runContainer(containerSpec), ) - case model.StepTypeUsesActionRemote: - remoteAction := newRemoteAction(step.Uses) - if remoteAction.Org == "actions" && remoteAction.Repo == "checkout" { - return func(ctx context.Context) error { - common.Logger(ctx).Debugf("Skipping actions/checkout") - return nil - } - } - cloneDir, err := ioutil.TempDir(rc.Tempdir, remoteAction.Repo) - if err != nil { - return common.NewErrorExecutor(err) - } - return common.NewPipelineExecutor( - common.NewGitCloneExecutor(common.NewGitCloneExecutorInput{ - URL: remoteAction.CloneURL(), - Ref: remoteAction.Ref, - Dir: cloneDir, - }), - sc.setupEnv(), - sc.setupAction(), - applyWith(containerSpec, step), - rc.pullImage(containerSpec), - rc.runContainer(containerSpec), - ) */ } @@ -198,8 +199,6 @@ func (sc *StepContext) runUsesContainer() common.Executor { } } -/* - func (sc *StepContext) setupAction() common.Executor { rc := sc.RunContext step := sc.Step @@ -215,50 +214,94 @@ func (sc *StepContext) setupAction() common.Executor { return err } - action, err := model.ReadAction(f) - if err != nil { - return err - } + sc.Action, err = model.ReadAction(f) + log.Debugf("Read action %v from '%s'", sc.Action, f.Name()) + return err + } +} +func (sc *StepContext) runAction() common.Executor { + rc := sc.RunContext + step := sc.Step + return func(ctx context.Context) error { + action := sc.Action + log.Debugf("About to run action %v", action) for inputID, input := range action.Inputs { envKey := regexp.MustCompile("[^A-Z0-9-]").ReplaceAllString(strings.ToUpper(inputID), "_") envKey = fmt.Sprintf("INPUT_%s", envKey) - if _, ok := containerSpec.Env[envKey]; !ok { - containerSpec.Env[envKey] = input.Default + if _, ok := sc.Env[envKey]; !ok { + sc.Env[envKey] = input.Default } } switch action.Runs.Using { case model.ActionRunsUsingNode12: - if strings.HasPrefix(actionDir, rc.Config.Workdir) { - containerSpec.Entrypoint = fmt.Sprintf("node /github/workspace/%s/%s", strings.TrimPrefix(actionDir, rc.Config.Workdir), action.Runs.Main) - } else if strings.HasPrefix(actionDir, rc.Tempdir) { - containerSpec.Entrypoint = fmt.Sprintf("node /github/home/%s/%s", strings.TrimPrefix(actionDir, rc.Tempdir), action.Runs.Main) - } + return rc.execJobContainer([]string{"node", action.Runs.Main}, sc.Env)(ctx) case model.ActionRunsUsingDocker: - if strings.HasPrefix(actionDir, rc.Config.Workdir) { - containerSpec.Name = rc.createStepContainerName(strings.TrimPrefix(actionDir, rc.Config.Workdir)) - } else if strings.HasPrefix(actionDir, rc.Tempdir) { - containerSpec.Name = rc.createStepContainerName(strings.TrimPrefix(actionDir, rc.Tempdir)) - } - containerSpec.Reuse = rc.Config.ReuseContainers + var prepImage common.Executor + var image string if strings.HasPrefix(action.Runs.Image, "docker://") { - containerSpec.Image = strings.TrimPrefix(action.Runs.Image, "docker://") - containerSpec.Entrypoint = strings.Join(action.Runs.Entrypoint, " ") - containerSpec.Args = strings.Join(action.Runs.Args, " ") + image = strings.TrimPrefix(action.Runs.Image, "docker://") } else { - containerSpec.Image = fmt.Sprintf("%s:%s", containerSpec.Name, "latest") - contextDir := filepath.Join(actionDir, action.Runs.Main) - return container.NewDockerBuildExecutor(container.NewDockerBuildExecutorInput{ + image = fmt.Sprintf("%s:%s", regexp.MustCompile("[^a-zA-Z0-9]").ReplaceAllString(step.Uses, "-"), "latest") + image = strings.TrimLeft(image, "-") + contextDir := filepath.Join(rc.Config.Workdir, step.Uses, action.Runs.Main) + prepImage = container.NewDockerBuildExecutor(container.NewDockerBuildExecutorInput{ ContextDir: contextDir, - ImageTag: containerSpec.Image, - })(ctx) + ImageTag: image, + }) } + + cmd := strings.Fields(step.With["args"]) + if len(cmd) == 0 { + cmd = action.Runs.Args + } + entrypoint := strings.Fields(step.With["entrypoint"]) + if len(entrypoint) == 0 { + entrypoint = action.Runs.Entrypoint + } + stepContainer := sc.newStepContainer(ctx, image, cmd, entrypoint) + return common.NewPipelineExecutor( + prepImage, + stepContainer.Pull(rc.Config.ForcePull), + stepContainer.Remove().IfBool(!rc.Config.ReuseContainers), + stepContainer.Create(), + stepContainer.Start(true), + ).Finally( + stepContainer.Remove().IfBool(!rc.Config.ReuseContainers), + )(ctx) + + /* + case model.ActionRunsUsingNode12: + if strings.HasPrefix(actionDir, rc.Config.Workdir) { + containerSpec.Entrypoint = fmt.Sprintf("node /github/workspace/%s/%s", strings.TrimPrefix(actionDir, rc.Config.Workdir), action.Runs.Main) + } else if strings.HasPrefix(actionDir, rc.Tempdir) { + containerSpec.Entrypoint = fmt.Sprintf("node /github/home/%s/%s", strings.TrimPrefix(actionDir, rc.Tempdir), action.Runs.Main) + } + case model.ActionRunsUsingDocker: + if strings.HasPrefix(actionDir, rc.Config.Workdir) { + containerSpec.Name = rc.createStepContainerName(strings.TrimPrefix(actionDir, rc.Config.Workdir)) + } else if strings.HasPrefix(actionDir, rc.Tempdir) { + containerSpec.Name = rc.createStepContainerName(strings.TrimPrefix(actionDir, rc.Tempdir)) + } + containerSpec.Reuse = rc.Config.ReuseContainers + if strings.HasPrefix(action.Runs.Image, "docker://") { + containerSpec.Image = strings.TrimPrefix(action.Runs.Image, "docker://") + containerSpec.Entrypoint = strings.Join(action.Runs.Entrypoint, " ") + containerSpec.Args = strings.Join(action.Runs.Args, " ") + } else { + containerSpec.Image = fmt.Sprintf("%s:%s", containerSpec.Name, "latest") + contextDir := filepath.Join(actionDir, action.Runs.Main) + return container.NewDockerBuildExecutor(container.NewDockerBuildExecutorInput{ + ContextDir: contextDir, + ImageTag: containerSpec.Image, + })(ctx) + } + */ } return nil } } -*/ type remoteAction struct { Org string diff --git a/pkg/runner/testdata/basic/push.yml b/pkg/runner/testdata/basic/push.yml index 50c6553..30218ac 100644 --- a/pkg/runner/testdata/basic/push.yml +++ b/pkg/runner/testdata/basic/push.yml @@ -10,7 +10,6 @@ jobs: - run: cat /github/sha.txt | grep ${GITHUB_SHA} build: - if: false runs-on: ubuntu-latest needs: [check] steps: