fix: make node tool non volatile (#2372)

* fix: make node tool non volatile

Currently downgrading node via setup-node can break later actions

* fix it and lookup on startup

* fix problems

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
ChristopherHX
2024-07-10 17:58:37 +02:00
committed by GitHub
parent 2ad5ff74f8
commit 6de25a53bc
9 changed files with 67 additions and 16 deletions

View File

@@ -179,7 +179,7 @@ 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)}
containerArgs := []string{rc.GetNodeToolFullPath(ctx), path.Join(containerActionDir, action.Runs.Main)}
logger.Debugf("executing remote job container: %s", containerArgs)
rc.ApplyExtraPath(ctx, step.getEnv())
@@ -533,7 +533,7 @@ func runPreStep(step actionStep) common.Executor {
return err
}
containerArgs := []string{"node", path.Join(containerActionDir, action.Runs.Pre)}
containerArgs := []string{rc.GetNodeToolFullPath(ctx), path.Join(containerActionDir, action.Runs.Pre)}
logger.Debugf("executing remote job container: %s", containerArgs)
rc.ApplyExtraPath(ctx, step.getEnv())
@@ -627,7 +627,7 @@ func runPostStep(step actionStep) common.Executor {
populateEnvsFromSavedState(step.getEnv(), step, rc)
populateEnvsFromInput(ctx, step.getEnv(), step.getActionModel(), rc)
containerArgs := []string{"node", path.Join(containerActionDir, action.Runs.Post)}
containerArgs := []string{rc.GetNodeToolFullPath(ctx), path.Join(containerActionDir, action.Runs.Post)}
logger.Debugf("executing remote job container: %s", containerArgs)
rc.ApplyExtraPath(ctx, step.getEnv())

View File

@@ -74,6 +74,7 @@ func newCompositeRunContext(ctx context.Context, parent *RunContext, step action
ExtraPath: parent.ExtraPath,
Parent: parent,
EventJSON: parent.EventJSON,
nodeToolFullPath: parent.nodeToolFullPath,
}
compositerc.ExprEval = compositerc.NewExpressionEvaluator(ctx)

View File

@@ -164,6 +164,7 @@ func TestActionRunner(t *testing.T) {
},
},
},
nodeToolFullPath: "node",
},
action: &model.Action{
Inputs: map[string]model.Input{
@@ -208,6 +209,7 @@ func TestActionRunner(t *testing.T) {
"name": "state value",
},
},
nodeToolFullPath: "node",
},
action: &model.Action{
Runs: model.ActionRuns{

View File

@@ -196,7 +196,7 @@ func getHashFilesFunction(ctx context.Context, rc *RunContext) func(v []reflect.
Mode: 0o644,
Body: hashfiles,
}).
Then(rc.execJobContainer([]string{"node", path.Join(rc.JobContainer.GetActPath(), name)},
Then(rc.execJobContainer([]string{rc.GetNodeToolFullPath(ctx), path.Join(rc.JobContainer.GetActPath(), name)},
env, "", "")).
Finally(func(context.Context) error {
rc.JobContainer.ReplaceLogWriter(stdout, stderr)

View File

@@ -116,6 +116,7 @@ func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executo
})
pipeline := make([]common.Executor, 0)
pipeline = append(pipeline, rc.InitializeNodeTool())
pipeline = append(pipeline, preSteps...)
pipeline = append(pipeline, steps...)

View File

@@ -258,6 +258,7 @@ func TestNewJobExecutor(t *testing.T) {
},
},
Config: &Config{},
nodeToolFullPath: "node",
}
rc.ExprEval = rc.NewExpressionEvaluator(ctx)
executorOrder := make([]string, 0)

View File

@@ -3,6 +3,7 @@ package runner
import (
"archive/tar"
"bufio"
"bytes"
"context"
"crypto/rand"
"crypto/sha256"
@@ -50,6 +51,7 @@ type RunContext struct {
Masks []string
cleanUpJobContainer common.Executor
caller *caller // job calling this RunContext (reusable workflows)
nodeToolFullPath string
}
func (rc *RunContext) AddMask(mask string) {
@@ -432,6 +434,48 @@ func (rc *RunContext) execJobContainer(cmd []string, env map[string]string, user
}
}
func (rc *RunContext) InitializeNodeTool() common.Executor {
return func(ctx context.Context) error {
rc.GetNodeToolFullPath(ctx)
return nil
}
}
func (rc *RunContext) GetNodeToolFullPath(ctx context.Context) string {
if rc.nodeToolFullPath == "" {
timeed, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel()
path := rc.JobContainer.GetPathVariableName()
cenv := map[string]string{}
var cpath string
if err := rc.JobContainer.UpdateFromImageEnv(&cenv)(ctx); err == nil {
if p, ok := cenv[path]; ok {
cpath = p
}
}
if len(cpath) == 0 {
cpath = rc.JobContainer.DefaultPathVariable()
}
cenv[path] = cpath
hout := &bytes.Buffer{}
herr := &bytes.Buffer{}
stdout, stderr := rc.JobContainer.ReplaceLogWriter(hout, herr)
err := rc.execJobContainer([]string{"node", "--no-warnings", "-e", "console.log(process.execPath)"},
cenv, "", "").
Finally(func(context.Context) error {
rc.JobContainer.ReplaceLogWriter(stdout, stderr)
return nil
})(timeed)
rawStr := strings.Trim(hout.String(), "\r\n")
if err == nil && !strings.ContainsAny(rawStr, "\r\n") {
rc.nodeToolFullPath = rawStr
} else {
rc.nodeToolFullPath = "node"
}
}
return rc.nodeToolFullPath
}
func (rc *RunContext) ApplyExtraPath(ctx context.Context, env *map[string]string) {
if rc.ExtraPath != nil && len(rc.ExtraPath) > 0 {
path := rc.JobContainer.GetPathVariableName()

View File

@@ -250,6 +250,7 @@ func TestStepActionLocalPost(t *testing.T) {
},
},
StepResults: tt.initialStepResults,
nodeToolFullPath: "node",
},
Step: tt.stepModel,
action: tt.actionModel,

View File

@@ -573,6 +573,7 @@ func TestStepActionRemotePost(t *testing.T) {
},
StepResults: tt.initialStepResults,
IntraActionState: tt.IntraActionState,
nodeToolFullPath: "node",
},
Step: tt.stepModel,
action: tt.actionModel,