Fix #2363. Add /pre- and /post-entrypoint handling (#2394)

* 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>
This commit is contained in:
Andrii Chyrva
2024-07-24 10:41:33 +03:00
committed by GitHub
parent 1d6a00c05c
commit 570ccf390e
2 changed files with 79 additions and 43 deletions

View File

@@ -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.

View File

@@ -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
@@ -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()
@@ -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
}
@@ -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 != "")
}
}
@@ -505,30 +518,33 @@ func runPreStep(step actionStep) common.Executor {
stepModel := step.getStepModel()
action := step.getActionModel()
// 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
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 = ""
}
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:
// 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 = ""
}
actionLocation := ""
if actionPath != "" {
actionLocation = path.Join(actionDir, actionPath)
} else {
actionLocation = actionDir
}
_, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc)
if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil {
return err
}
@@ -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)
@@ -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 != "")
}
}
@@ -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 = ""
@@ -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:
@@ -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