1
0
Fork 0
mirror of https://code.forgejo.org/forgejo/runner.git synced 2025-09-15 18:57:01 +00:00

Feature: Added an action type for the action.yaml that uses sh (#141)

Currently the only way to get pre and post actions is to go through the nodejs mechanism, which is quite wasteful when all one wants to do is run a couple of shell commands, I'm trying to get around this with this patch.

It works similar to the node* actions in that it supports `pre`, `main` and `post`.

It is different in that these strings are passed to the system shell using `sh -c` and execute similar to the composite run action with the shell set to `sh`.

Example action to make use of this patch: https://codeberg.org/slatian/test-action/src/branch/main/action.yaml

Reviewed-on: https://code.forgejo.org/forgejo/act/pulls/141
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: Slatian <baschdel@disroot.org>
Co-committed-by: Slatian <baschdel@disroot.org>
This commit is contained in:
Slatian 2025-06-14 15:31:32 +00:00 committed by earl-warren
parent ab012fec87
commit 5cf8d53087
7 changed files with 87 additions and 8 deletions

View file

@ -20,7 +20,7 @@ func (a *ActionRunsUsing) UnmarshalYAML(unmarshal func(interface{}) error) error
// Force input to lowercase for case insensitive comparison
format := ActionRunsUsing(strings.ToLower(using))
switch format {
case ActionRunsUsingNode20, ActionRunsUsingNode16, ActionRunsUsingNode12, ActionRunsUsingDocker, ActionRunsUsingComposite, ActionRunsUsingGo:
case ActionRunsUsingNode20, ActionRunsUsingNode16, ActionRunsUsingNode12, ActionRunsUsingDocker, ActionRunsUsingComposite, ActionRunsUsingGo, ActionRunsUsingSh:
*a = format
default:
return fmt.Errorf("The runs.using key in action.yml must be one of: %v, got %s", []string{
@ -30,6 +30,7 @@ func (a *ActionRunsUsing) UnmarshalYAML(unmarshal func(interface{}) error) error
ActionRunsUsingNode16,
ActionRunsUsingNode20,
ActionRunsUsingGo,
ActionRunsUsingSh,
}, format)
}
return nil
@ -48,6 +49,8 @@ const (
ActionRunsUsingComposite = "composite"
// ActionRunsUsingGo for running with go
ActionRunsUsingGo = "go"
// ActionRunsUsingSh for running with sh
ActionRunsUsingSh = "sh"
)
// ActionRuns are a field in Action

View file

@ -164,14 +164,18 @@ func runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction
action := step.getActionModel()
logger.Debugf("About to run action %v", action)
actionLocation := path.Join(actionDir, actionPath)
actionName, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc)
if action.Runs.Using == model.ActionRunsUsingSh {
rc.ActionPath = containerActionDir
}
err := setupActionEnv(ctx, step, remoteAction)
if err != nil {
return err
}
actionLocation := path.Join(actionDir, actionPath)
actionName, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc)
logger.Debugf("type=%v actionDir=%s actionPath=%s workdir=%s actionCacheDir=%s actionName=%s containerActionDir=%s", stepModel.Type(), actionDir, actionPath, rc.Config.Workdir, rc.ActionCacheDir(), actionName, containerActionDir)
switch action.Runs.Using {
@ -179,11 +183,23 @@ func runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction
if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil {
return err
}
containerArgs := []string{"node", path.Join(containerActionDir, action.Runs.Main)}
logger.Debugf("executing remote job container: %s", containerArgs)
rc.ApplyExtraPath(ctx, step.getEnv())
return rc.execJobContainer(containerArgs, *step.getEnv(), "", "")(ctx)
case model.ActionRunsUsingSh:
if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil {
return err
}
containerArgs := []string{"sh", "-c", action.Runs.Main}
logger.Debugf("executing remote job container: %s", containerArgs)
rc.ApplyExtraPath(ctx, step.getEnv())
return rc.execJobContainer(containerArgs, *step.getEnv(), "", "")(ctx)
case model.ActionRunsUsingDocker:
location := actionLocation
@ -220,6 +236,7 @@ func runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction
model.ActionRunsUsingNode20,
model.ActionRunsUsingComposite,
model.ActionRunsUsingGo,
model.ActionRunsUsingSh,
}, action.Runs.Using)
}
}
@ -509,7 +526,8 @@ func hasPreStep(step actionStep) common.Conditional {
((action.Runs.Using == model.ActionRunsUsingNode12 ||
action.Runs.Using == model.ActionRunsUsingNode16 ||
action.Runs.Using == model.ActionRunsUsingNode20 ||
action.Runs.Using == model.ActionRunsUsingGo) &&
action.Runs.Using == model.ActionRunsUsingGo ||
action.Runs.Using == model.ActionRunsUsingSh) &&
action.Runs.Pre != "")
}
}
@ -524,7 +542,7 @@ func runPreStep(step actionStep) common.Executor {
action := step.getActionModel()
switch action.Runs.Using {
case model.ActionRunsUsingNode12, model.ActionRunsUsingNode16, model.ActionRunsUsingNode20:
case model.ActionRunsUsingNode12, model.ActionRunsUsingNode16, model.ActionRunsUsingNode20, model.ActionRunsUsingSh:
// defaults in pre steps were missing, however provided inputs are available
populateEnvsFromInput(ctx, step.getEnv(), action, rc)
// todo: refactor into step
@ -551,7 +569,14 @@ func runPreStep(step actionStep) common.Executor {
return err
}
containerArgs := []string{"node", path.Join(containerActionDir, action.Runs.Pre)}
var containerArgs []string
if action.Runs.Using == model.ActionRunsUsingSh {
rc.ActionPath = containerActionDir
containerArgs = []string{"sh", "-c", action.Runs.Pre}
} else {
containerArgs = []string{"node", path.Join(containerActionDir, action.Runs.Pre)}
}
logger.Debugf("executing remote job container: %s", containerArgs)
rc.ApplyExtraPath(ctx, step.getEnv())
@ -643,7 +668,8 @@ func hasPostStep(step actionStep) common.Conditional {
((action.Runs.Using == model.ActionRunsUsingNode12 ||
action.Runs.Using == model.ActionRunsUsingNode16 ||
action.Runs.Using == model.ActionRunsUsingNode20 ||
action.Runs.Using == model.ActionRunsUsingGo) &&
action.Runs.Using == model.ActionRunsUsingGo ||
action.Runs.Using == model.ActionRunsUsingSh) &&
action.Runs.Post != "")
}
}
@ -689,6 +715,18 @@ func runPostStep(step actionStep) common.Executor {
return rc.execJobContainer(containerArgs, *step.getEnv(), "", "")(ctx)
case model.ActionRunsUsingSh:
populateEnvsFromSavedState(step.getEnv(), step, rc)
rc.ActionPath = containerActionDir
containerArgs := []string{"sh", "-c", action.Runs.Post}
logger.Debugf("executing remote job container: %s", containerArgs)
rc.ApplyExtraPath(ctx, step.getEnv())
return rc.execJobContainer(containerArgs, *step.getEnv(), "", "")(ctx)
case model.ActionRunsUsingComposite:
if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil {
return err

View file

@ -382,6 +382,8 @@ func TestRunEventHostEnvironment(t *testing.T) {
{workdir, "uses-composite-with-error", "push", "Job 'failing-composite-action' failed", platforms, secrets},
{workdir, "uses-nested-composite", "push", "", platforms, secrets},
{workdir, "act-composite-env-test", "push", "", platforms, secrets},
{workdir, "uses-sh", "push", "", platforms, secrets},
{workdir, "uses-sh-test-action-path", "push", "", platforms, secrets},
// Eval
{workdir, "evalmatrix", "push", "", platforms, secrets},

View file

@ -0,0 +1,10 @@
---
name: uses-sh-test-action-path
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./uses-sh-test-action-path/sh_test_action_path

View file

@ -0,0 +1,8 @@
---
name: Test for the action path being a valid directory using the sh action type
runs:
using: sh
pre: 'echo "testing pre"; if [ -d "$GITHUB_ACTION_PATH" ] ; then echo "Everything okay" ; ls "$GITHUB_ACTION_PATH" ; else echo "No directory at action path: $GITHUB_ACTION_PATH" ; exit 1; fi'
main: 'echo "testing main"; if [ -d "$GITHUB_ACTION_PATH" ] ; then echo "Everything okay" ; ls "$GITHUB_ACTION_PATH" ; else echo "No directory at action path: $GITHUB_ACTION_PATH" ; exit 1; fi'
post: 'echo "testing post"; if [ -d "$GITHUB_ACTION_PATH" ] ; then echo "Everything okay" ; ls "$GITHUB_ACTION_PATH" ; else echo "No directory at action path: $GITHUB_ACTION_PATH" ; exit 1; fi'

10
act/runner/testdata/uses-sh/push.yaml vendored Normal file
View file

@ -0,0 +1,10 @@
---
name: uses-sh
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./uses-sh/sh_action

View file

@ -0,0 +1,8 @@
---
name: Basic test using the sh type
runs:
using: sh
pre: 'echo "testing pre"'
main: 'echo "testing main"'
post: 'echo "testing post"'