Skip to content

Commit

Permalink
Fix #2363. Add /pre- and /post-entrypoint handling (#2394)
Browse files Browse the repository at this point in the history
* Fix #2363. Add /pre- and /post-entrypoint handling

* fix copy paste error

---------

Co-authored-by: Andrii Chyrva <achyrva@hotmail.com>
Co-authored-by: ChristopherHX <christopher.homberger@web.de>
  • Loading branch information
3 people committed Jul 24, 2024
1 parent 1d6a00c commit 570ccf3
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 42 deletions.
24 changes: 13 additions & 11 deletions pkg/model/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,19 @@ const (

// ActionRuns are a field in Action
type ActionRuns struct {
Using ActionRunsUsing `yaml:"using"`
Env map[string]string `yaml:"env"`
Main string `yaml:"main"`
Pre string `yaml:"pre"`
PreIf string `yaml:"pre-if"`
Post string `yaml:"post"`
PostIf string `yaml:"post-if"`
Image string `yaml:"image"`
Entrypoint string `yaml:"entrypoint"`
Args []string `yaml:"args"`
Steps []Step `yaml:"steps"`
Using ActionRunsUsing `yaml:"using"`
Env map[string]string `yaml:"env"`
Main string `yaml:"main"`
Pre string `yaml:"pre"`
PreIf string `yaml:"pre-if"`
Post string `yaml:"post"`
PostIf string `yaml:"post-if"`
Image string `yaml:"image"`
PreEntrypoint string `yaml:"pre-entrypoint"`
Entrypoint string `yaml:"entrypoint"`
PostEntrypoint string `yaml:"post-entrypoint"`
Args []string `yaml:"args"`
Steps []Step `yaml:"steps"`
}

// Action describes a metadata file for GitHub actions. The metadata filename must be either action.yml or action.yaml. The data in the metadata file defines the inputs, outputs and main entrypoint for your action.
Expand Down
96 changes: 65 additions & 31 deletions pkg/runner/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction
if remoteAction == nil {
location = containerActionDir
}
return execAsDocker(ctx, step, actionName, location, remoteAction == nil)
return execAsDocker(ctx, step, actionName, location, remoteAction == nil, "entrypoint")
case model.ActionRunsUsingComposite:
if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil {
return err
Expand Down Expand Up @@ -243,7 +243,7 @@ func removeGitIgnore(ctx context.Context, directory string) error {
// TODO: break out parts of function to reduce complexicity
//
//nolint:gocyclo
func execAsDocker(ctx context.Context, step actionStep, actionName string, basedir string, localAction bool) error {
func execAsDocker(ctx context.Context, step actionStep, actionName string, basedir string, localAction bool, entrypointType string) error {
logger := common.Logger(ctx)
rc := step.getRunContext()
action := step.getActionModel()
Expand Down Expand Up @@ -319,13 +319,24 @@ func execAsDocker(ctx context.Context, step actionStep, actionName string, based
cmd = action.Runs.Args
evalDockerArgs(ctx, step, action, &cmd)
}
entrypoint := strings.Fields(eval.Interpolate(ctx, step.getStepModel().With["entrypoint"]))

entrypoint := strings.Fields(eval.Interpolate(ctx, step.getStepModel().With[entrypointType]))
if len(entrypoint) == 0 {
if action.Runs.Entrypoint != "" {
if entrypointType == "pre-entrypoint" && action.Runs.PreEntrypoint != "" {
entrypoint, err = shellquote.Split(action.Runs.PreEntrypoint)
if err != nil {
return err
}
} else if entrypointType == "entrypoint" && action.Runs.Entrypoint != "" {
entrypoint, err = shellquote.Split(action.Runs.Entrypoint)
if err != nil {
return err
}
} else if entrypointType == "post-entrypoint" && action.Runs.PostEntrypoint != "" {
entrypoint, err = shellquote.Split(action.Runs.PostEntrypoint)
if err != nil {
return err
}
} else {
entrypoint = nil
}
Expand Down Expand Up @@ -488,11 +499,13 @@ func shouldRunPreStep(step actionStep) common.Conditional {
func hasPreStep(step actionStep) common.Conditional {
return func(ctx context.Context) bool {
action := step.getActionModel()
return action.Runs.Using == model.ActionRunsUsingComposite ||
return (action.Runs.Using == model.ActionRunsUsingComposite) ||
((action.Runs.Using == model.ActionRunsUsingNode12 ||
action.Runs.Using == model.ActionRunsUsingNode16 ||
action.Runs.Using == model.ActionRunsUsingNode20) &&
action.Runs.Pre != "")
action.Runs.Pre != "") ||
(action.Runs.Using == model.ActionRunsUsingDocker &&
action.Runs.PreEntrypoint != "")
}
}

Expand All @@ -505,30 +518,33 @@ func runPreStep(step actionStep) common.Executor {
stepModel := step.getStepModel()
action := step.getActionModel()

switch action.Runs.Using {
case model.ActionRunsUsingNode12, model.ActionRunsUsingNode16, model.ActionRunsUsingNode20:
// defaults in pre steps were missing, however provided inputs are available
populateEnvsFromInput(ctx, step.getEnv(), action, rc)
// todo: refactor into step
var actionDir string
var actionPath string
if _, ok := step.(*stepActionRemote); ok {
actionPath = newRemoteAction(stepModel.Uses).Path
actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(stepModel.Uses))
} else {
actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses)
actionPath = ""
}
// defaults in pre steps were missing, however provided inputs are available
populateEnvsFromInput(ctx, step.getEnv(), action, rc)

actionLocation := ""
if actionPath != "" {
actionLocation = path.Join(actionDir, actionPath)
} else {
actionLocation = actionDir
}
// todo: refactor into step
var actionDir string
var actionPath string
var remoteAction *stepActionRemote
if remote, ok := step.(*stepActionRemote); ok {
actionPath = newRemoteAction(stepModel.Uses).Path
actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(stepModel.Uses))
remoteAction = remote
} else {
actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses)
actionPath = ""
}

_, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc)
actionLocation := ""
if actionPath != "" {
actionLocation = path.Join(actionDir, actionPath)
} else {
actionLocation = actionDir
}

actionName, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc)

switch action.Runs.Using {
case model.ActionRunsUsingNode12, model.ActionRunsUsingNode16, model.ActionRunsUsingNode20:
if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil {
return err
}
Expand All @@ -540,6 +556,13 @@ func runPreStep(step actionStep) common.Executor {

return rc.execJobContainer(containerArgs, *step.getEnv(), "", "")(ctx)

case model.ActionRunsUsingDocker:
location := actionLocation
if remoteAction == nil {
location = containerActionDir
}
return execAsDocker(ctx, step, actionName, location, remoteAction == nil, "pre-entrypoint")

case model.ActionRunsUsingComposite:
if step.getCompositeSteps() == nil {
step.getCompositeRunContext(ctx)
Expand Down Expand Up @@ -584,11 +607,13 @@ func shouldRunPostStep(step actionStep) common.Conditional {
func hasPostStep(step actionStep) common.Conditional {
return func(ctx context.Context) bool {
action := step.getActionModel()
return action.Runs.Using == model.ActionRunsUsingComposite ||
return (action.Runs.Using == model.ActionRunsUsingComposite) ||
((action.Runs.Using == model.ActionRunsUsingNode12 ||
action.Runs.Using == model.ActionRunsUsingNode16 ||
action.Runs.Using == model.ActionRunsUsingNode20) &&
action.Runs.Post != "")
action.Runs.Post != "") ||
(action.Runs.Using == model.ActionRunsUsingDocker &&
action.Runs.PostEntrypoint != "")
}
}

Expand All @@ -604,9 +629,11 @@ func runPostStep(step actionStep) common.Executor {
// todo: refactor into step
var actionDir string
var actionPath string
if _, ok := step.(*stepActionRemote); ok {
var remoteAction *stepActionRemote
if remote, ok := step.(*stepActionRemote); ok {
actionPath = newRemoteAction(stepModel.Uses).Path
actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(stepModel.Uses))
remoteAction = remote
} else {
actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses)
actionPath = ""
Expand All @@ -619,7 +646,7 @@ func runPostStep(step actionStep) common.Executor {
actionLocation = actionDir
}

_, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc)
actionName, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc)

switch action.Runs.Using {
case model.ActionRunsUsingNode12, model.ActionRunsUsingNode16, model.ActionRunsUsingNode20:
Expand All @@ -634,6 +661,13 @@ func runPostStep(step actionStep) common.Executor {

return rc.execJobContainer(containerArgs, *step.getEnv(), "", "")(ctx)

case model.ActionRunsUsingDocker:
location := actionLocation
if remoteAction == nil {
location = containerActionDir
}
return execAsDocker(ctx, step, actionName, location, remoteAction == nil, "post-entrypoint")

case model.ActionRunsUsingComposite:
if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil {
return err
Expand Down

0 comments on commit 570ccf3

Please sign in to comment.