mirror of
https://gitea.com/gitea/act_runner.git
synced 2026-03-22 06:45:03 +01:00
feat: allow configuring gitea schema mode (#23)
* config entries for schema change * remove broken/unused syntetic nodejs action * specify desired schema in model struct that is read by unmarshal * replace params by config * allows gitea context + env names * act --gitea now parses a subset of gitea specific workflows Reviewed-on: https://gitea.com/actions-oss/act-cli/pulls/23 Co-authored-by: Christopher Homberger <christopher.homberger@web.de> Co-committed-by: Christopher Homberger <christopher.homberger@web.de>
This commit is contained in:
committed by
ChristopherHX
parent
faa252c8e9
commit
933c4a5bd5
@@ -2,14 +2,11 @@ package runner
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -33,23 +30,18 @@ type actionStep interface {
|
||||
maybeCopyToActionDir(ctx context.Context) error
|
||||
}
|
||||
|
||||
type readAction func(ctx context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error)
|
||||
type readAction func(ctx context.Context, step *model.Step, readFile actionYamlReader, config model.ActionConfig) (*model.Action, error)
|
||||
|
||||
type actionYamlReader func(filename string) (io.Reader, io.Closer, error)
|
||||
|
||||
type fileWriter func(filename string, data []byte, perm fs.FileMode) error
|
||||
|
||||
type runAction func(step actionStep) common.Executor
|
||||
|
||||
//go:embed res/trampoline.js
|
||||
var trampoline embed.FS
|
||||
|
||||
func readActionImpl(ctx context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error) {
|
||||
func readActionImpl(ctx context.Context, step *model.Step, readFile actionYamlReader, config model.ActionConfig) (*model.Action, error) {
|
||||
logger := common.Logger(ctx)
|
||||
allErrors := []error{}
|
||||
addError := func(fileName string, err error) {
|
||||
if err != nil {
|
||||
allErrors = append(allErrors, fmt.Errorf("failed to read '%s' from action '%s' with path '%s' of step %w", fileName, step.String(), actionPath, err))
|
||||
allErrors = append(allErrors, fmt.Errorf("failed to read '%s' from action '%s': %w", fileName, step.String(), err))
|
||||
} else {
|
||||
// One successful read, clear error state
|
||||
allErrors = nil
|
||||
@@ -75,39 +67,6 @@ func readActionImpl(ctx context.Context, step *model.Step, actionDir string, act
|
||||
logger.Debugf("Using synthetic action %v for Dockerfile", action)
|
||||
return action, nil
|
||||
}
|
||||
if step.With != nil {
|
||||
if val, ok := step.With["args"]; ok {
|
||||
var b []byte
|
||||
if b, err = trampoline.ReadFile("res/trampoline.js"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err2 := writeFile(filepath.Join(actionDir, actionPath, "trampoline.js"), b, 0o400)
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
action := &model.Action{
|
||||
Name: "(Synthetic)",
|
||||
Inputs: map[string]model.Input{
|
||||
"cwd": {
|
||||
Description: "(Actual working directory)",
|
||||
Required: false,
|
||||
Default: filepath.Join(actionDir, actionPath),
|
||||
},
|
||||
"command": {
|
||||
Description: "(Actual program)",
|
||||
Required: false,
|
||||
Default: val,
|
||||
},
|
||||
},
|
||||
Runs: model.ActionRuns{
|
||||
Using: "node12",
|
||||
Main: "trampoline.js",
|
||||
},
|
||||
}
|
||||
logger.Debugf("Using synthetic action %v", action)
|
||||
return action, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if allErrors != nil {
|
||||
@@ -115,8 +74,8 @@ func readActionImpl(ctx context.Context, step *model.Step, actionDir string, act
|
||||
}
|
||||
defer closer.Close()
|
||||
|
||||
action, err := model.ReadAction(reader)
|
||||
logger.Debugf("Read action %v from '%s'", action, "Unknown")
|
||||
action, err := model.ReadAction(reader, config)
|
||||
logger.Debugf("Read action %v", action)
|
||||
return action, err
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +38,8 @@ func evaluateCompositeInputAndEnv(ctx context.Context, parent *RunContext, step
|
||||
}
|
||||
}
|
||||
gh := step.getGithubContext(ctx)
|
||||
env["GITHUB_ACTION_REPOSITORY"] = gh.ActionRepository
|
||||
env["GITHUB_ACTION_REF"] = gh.ActionRef
|
||||
step.getRunContext().setMainCtxVars(env, "ACTION_REPOSITORY", gh.ActionRepository)
|
||||
step.getRunContext().setMainCtxVars(env, "ACTION_REF", gh.ActionRef)
|
||||
|
||||
return env
|
||||
}
|
||||
|
||||
@@ -79,33 +79,6 @@ runs:
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "readWithArgs",
|
||||
step: &model.Step{
|
||||
With: map[string]string{
|
||||
"args": "cmd",
|
||||
},
|
||||
},
|
||||
expected: &model.Action{
|
||||
Name: "(Synthetic)",
|
||||
Inputs: map[string]model.Input{
|
||||
"cwd": {
|
||||
Description: "(Actual working directory)",
|
||||
Required: false,
|
||||
Default: "actionDir/actionPath",
|
||||
},
|
||||
"command": {
|
||||
Description: "(Actual program)",
|
||||
Required: false,
|
||||
Default: "cmd",
|
||||
},
|
||||
},
|
||||
Runs: model.ActionRuns{
|
||||
Using: "node12",
|
||||
Main: "trampoline.js",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range table {
|
||||
@@ -120,17 +93,11 @@ runs:
|
||||
return strings.NewReader(tt.fileContent), closerMock, nil
|
||||
}
|
||||
|
||||
writeFile := func(filename string, _ []byte, perm fs.FileMode) error {
|
||||
assert.Equal(t, "actionDir/actionPath/trampoline.js", filename)
|
||||
assert.Equal(t, fs.FileMode(0400), perm)
|
||||
return nil
|
||||
}
|
||||
|
||||
if tt.filename != "" {
|
||||
closerMock.On("Close")
|
||||
}
|
||||
|
||||
action, err := readActionImpl(context.Background(), tt.step, "actionDir", "actionPath", readFile, writeFile)
|
||||
action, err := readActionImpl(context.Background(), tt.step, readFile, model.ActionConfig{})
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, tt.expected, action)
|
||||
|
||||
@@ -98,9 +98,10 @@ func (rc *RunContext) NewExpressionEvaluatorWithEnv(ctx context.Context, env map
|
||||
}
|
||||
return expressionEvaluator{
|
||||
interpreter: exprparser.NewInterpeter(ee, exprparser.Config{
|
||||
Run: rc.Run,
|
||||
WorkingDir: rc.Config.Workdir,
|
||||
Context: "job",
|
||||
Run: rc.Run,
|
||||
WorkingDir: rc.Config.Workdir,
|
||||
Context: "job",
|
||||
MainContextNames: rc.Config.MainContextNames,
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -164,9 +165,10 @@ func (rc *RunContext) newStepExpressionEvaluator(ctx context.Context, step step,
|
||||
}
|
||||
return expressionEvaluator{
|
||||
interpreter: exprparser.NewInterpeter(ee, exprparser.Config{
|
||||
Run: rc.Run,
|
||||
WorkingDir: rc.Config.Workdir,
|
||||
Context: "step",
|
||||
Run: rc.Run,
|
||||
WorkingDir: rc.Config.Workdir,
|
||||
Context: "step",
|
||||
MainContextNames: rc.Config.MainContextNames,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
const { spawnSync } = require('child_process')
|
||||
const spawnArguments = {
|
||||
cwd: process.env.INPUT_CWD,
|
||||
stdio: [
|
||||
process.stdin,
|
||||
process.stdout,
|
||||
process.stderr
|
||||
]
|
||||
}
|
||||
const child = spawnSync(
|
||||
'/bin/sh',
|
||||
['-c'].concat(process.env.INPUT_COMMAND),
|
||||
spawnArguments)
|
||||
process.exit(child.status)
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func newLocalReusableWorkflowExecutor(rc *RunContext) common.Executor {
|
||||
return newReusableWorkflowExecutor(rc, rc.Config.Workdir, rc.Run.Job().Uses)
|
||||
return newReusableWorkflowExecutor(rc, rc.Config.Workdir, rc.Run.Job().Uses, rc.Config.Planner)
|
||||
}
|
||||
|
||||
func newRemoteReusableWorkflowExecutor(rc *RunContext) common.Executor {
|
||||
@@ -28,10 +28,10 @@ func newRemoteReusableWorkflowExecutor(rc *RunContext) common.Executor {
|
||||
// multiple reusable workflows from the same repository and ref since for each workflow we won't have to clone it again
|
||||
filename := fmt.Sprintf("%s/%s@%s", remoteReusableWorkflow.Org, remoteReusableWorkflow.Repo, remoteReusableWorkflow.Ref)
|
||||
|
||||
return newActionCacheReusableWorkflowExecutor(rc, filename, remoteReusableWorkflow)
|
||||
return newActionCacheReusableWorkflowExecutor(rc, filename, remoteReusableWorkflow, rc.Config.Planner)
|
||||
}
|
||||
|
||||
func newActionCacheReusableWorkflowExecutor(rc *RunContext, filename string, remoteReusableWorkflow *remoteReusableWorkflow) common.Executor {
|
||||
func newActionCacheReusableWorkflowExecutor(rc *RunContext, filename string, remoteReusableWorkflow *remoteReusableWorkflow, config model.PlannerConfig) common.Executor {
|
||||
return func(ctx context.Context) error {
|
||||
ghctx := rc.getGithubContext(ctx)
|
||||
remoteReusableWorkflow.URL = ghctx.ServerURL
|
||||
@@ -49,7 +49,7 @@ func newActionCacheReusableWorkflowExecutor(rc *RunContext, filename string, rem
|
||||
if _, err = treader.Next(); err != nil {
|
||||
return err
|
||||
}
|
||||
planner, err := model.NewSingleWorkflowPlanner(remoteReusableWorkflow.Filename, treader)
|
||||
planner, err := model.NewSingleWorkflowPlanner(remoteReusableWorkflow.Filename, treader, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -67,9 +67,9 @@ func newActionCacheReusableWorkflowExecutor(rc *RunContext, filename string, rem
|
||||
}
|
||||
}
|
||||
|
||||
func newReusableWorkflowExecutor(rc *RunContext, directory string, workflow string) common.Executor {
|
||||
func newReusableWorkflowExecutor(rc *RunContext, directory string, workflow string, config model.PlannerConfig) common.Executor {
|
||||
return func(ctx context.Context) error {
|
||||
planner, err := model.NewWorkflowPlanner(path.Join(directory, workflow), true, false)
|
||||
planner, err := model.NewWorkflowPlanner(path.Join(directory, workflow), config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1109,36 +1109,47 @@ func nestedMapLookup(m map[string]interface{}, ks ...string) (rval interface{})
|
||||
return nestedMapLookup(m, ks[1:]...)
|
||||
}
|
||||
|
||||
func (rc *RunContext) setMainCtxVars(env map[string]string, name string, value string) {
|
||||
// Use this to set GITHUB_<name> and any additional main context names in env
|
||||
ctxNames := rc.Config.MainContextNames
|
||||
if len(ctxNames) == 0 {
|
||||
ctxNames = []string{"github"}
|
||||
}
|
||||
for _, ctxName := range ctxNames {
|
||||
env[strings.ToUpper(ctxName)+"_"+name] = value
|
||||
}
|
||||
}
|
||||
|
||||
func (rc *RunContext) withGithubEnv(ctx context.Context, github *model.GithubContext, env map[string]string) map[string]string {
|
||||
env["CI"] = "true"
|
||||
env["GITHUB_WORKFLOW"] = github.Workflow
|
||||
env["GITHUB_RUN_ATTEMPT"] = github.RunAttempt
|
||||
env["GITHUB_RUN_ID"] = github.RunID
|
||||
env["GITHUB_RUN_NUMBER"] = github.RunNumber
|
||||
env["GITHUB_ACTION"] = github.Action
|
||||
env["GITHUB_ACTION_PATH"] = github.ActionPath
|
||||
env["GITHUB_ACTION_REPOSITORY"] = github.ActionRepository
|
||||
env["GITHUB_ACTION_REF"] = github.ActionRef
|
||||
env["GITHUB_ACTIONS"] = "true"
|
||||
env["GITHUB_ACTOR"] = github.Actor
|
||||
env["GITHUB_REPOSITORY"] = github.Repository
|
||||
env["GITHUB_EVENT_NAME"] = github.EventName
|
||||
env["GITHUB_EVENT_PATH"] = github.EventPath
|
||||
env["GITHUB_WORKSPACE"] = github.Workspace
|
||||
env["GITHUB_SHA"] = github.Sha
|
||||
env["GITHUB_REF"] = github.Ref
|
||||
env["GITHUB_REF_NAME"] = github.RefName
|
||||
env["GITHUB_REF_TYPE"] = github.RefType
|
||||
env["GITHUB_JOB"] = github.Job
|
||||
env["GITHUB_REPOSITORY_OWNER"] = github.RepositoryOwner
|
||||
env["GITHUB_RETENTION_DAYS"] = github.RetentionDays
|
||||
rc.setMainCtxVars(env, "WORKFLOW", github.Workflow)
|
||||
rc.setMainCtxVars(env, "RUN_ATTEMPT", github.RunAttempt)
|
||||
rc.setMainCtxVars(env, "RUN_ID", github.RunID)
|
||||
rc.setMainCtxVars(env, "RUN_NUMBER", github.RunNumber)
|
||||
rc.setMainCtxVars(env, "ACTION", github.Action)
|
||||
rc.setMainCtxVars(env, "ACTION_PATH", github.ActionPath)
|
||||
rc.setMainCtxVars(env, "ACTION_REPOSITORY", github.ActionRepository)
|
||||
rc.setMainCtxVars(env, "ACTION_REF", github.ActionRef)
|
||||
rc.setMainCtxVars(env, "ACTIONS", "true")
|
||||
rc.setMainCtxVars(env, "ACTOR", github.Actor)
|
||||
rc.setMainCtxVars(env, "REPOSITORY", github.Repository)
|
||||
rc.setMainCtxVars(env, "EVENT_NAME", github.EventName)
|
||||
rc.setMainCtxVars(env, "EVENT_PATH", github.EventPath)
|
||||
rc.setMainCtxVars(env, "WORKSPACE", github.Workspace)
|
||||
rc.setMainCtxVars(env, "SHA", github.Sha)
|
||||
rc.setMainCtxVars(env, "REF", github.Ref)
|
||||
rc.setMainCtxVars(env, "REF_NAME", github.RefName)
|
||||
rc.setMainCtxVars(env, "REF_TYPE", github.RefType)
|
||||
rc.setMainCtxVars(env, "JOB", github.Job)
|
||||
rc.setMainCtxVars(env, "REPOSITORY_OWNER", github.RepositoryOwner)
|
||||
rc.setMainCtxVars(env, "RETENTION_DAYS", github.RetentionDays)
|
||||
env["RUNNER_PERFLOG"] = github.RunnerPerflog
|
||||
env["RUNNER_TRACKING_ID"] = github.RunnerTrackingID
|
||||
env["GITHUB_BASE_REF"] = github.BaseRef
|
||||
env["GITHUB_HEAD_REF"] = github.HeadRef
|
||||
env["GITHUB_SERVER_URL"] = github.ServerURL
|
||||
env["GITHUB_API_URL"] = github.APIURL
|
||||
env["GITHUB_GRAPHQL_URL"] = github.GraphQLURL
|
||||
rc.setMainCtxVars(env, "BASE_REF", github.BaseRef)
|
||||
rc.setMainCtxVars(env, "HEAD_REF", github.HeadRef)
|
||||
rc.setMainCtxVars(env, "SERVER_URL", github.ServerURL)
|
||||
rc.setMainCtxVars(env, "API_URL", github.APIURL)
|
||||
rc.setMainCtxVars(env, "GRAPHQL_URL", github.GraphQLURL)
|
||||
|
||||
if rc.Config.ArtifactServerPath != "" {
|
||||
setActionRuntimeVars(rc, env)
|
||||
|
||||
@@ -68,9 +68,12 @@ type Config struct {
|
||||
ActionCache ActionCache // Use a custom ActionCache Implementation
|
||||
HostEnvironmentDir string // Custom folder for host environment, parallel jobs must be 1
|
||||
|
||||
CustomExecutor map[model.JobType]func(*RunContext) common.Executor // Custom executor to run jobs
|
||||
semaphore *semaphore.Weighted
|
||||
Parallel int // Number of parallel jobs to run
|
||||
CustomExecutor map[model.JobType]func(*RunContext) common.Executor // Custom executor to run jobs
|
||||
semaphore *semaphore.Weighted
|
||||
Parallel int // Number of parallel jobs to run
|
||||
Planner model.PlannerConfig // Configuration for the workflow planner
|
||||
Action model.ActionConfig // Configuration for action reading
|
||||
MainContextNames []string // e.g. "github", "gitea", "forgejo"
|
||||
}
|
||||
|
||||
func (runnerConfig *Config) GetGitHubServerURL() string {
|
||||
|
||||
@@ -56,7 +56,7 @@ func init() {
|
||||
}
|
||||
|
||||
func TestNoWorkflowsFoundByPlanner(t *testing.T) {
|
||||
planner, err := model.NewWorkflowPlanner("res", true, false)
|
||||
planner, err := model.NewWorkflowPlanner("hashfiles", model.PlannerConfig{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
out := log.StandardLogger().Out
|
||||
@@ -76,7 +76,7 @@ func TestNoWorkflowsFoundByPlanner(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGraphMissingEvent(t *testing.T) {
|
||||
planner, err := model.NewWorkflowPlanner("testdata/issue-1595/no-event.yml", true, false)
|
||||
planner, err := model.NewWorkflowPlanner("testdata/issue-1595/no-event.yml", model.PlannerConfig{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
out := log.StandardLogger().Out
|
||||
@@ -94,7 +94,7 @@ func TestGraphMissingEvent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGraphMissingFirst(t *testing.T) {
|
||||
planner, err := model.NewWorkflowPlanner("testdata/issue-1595/no-first.yml", true, false)
|
||||
planner, err := model.NewWorkflowPlanner("testdata/issue-1595/no-first.yml", model.PlannerConfig{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
plan, err := planner.PlanEvent("push")
|
||||
@@ -104,7 +104,7 @@ func TestGraphMissingFirst(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGraphWithMissing(t *testing.T) {
|
||||
planner, err := model.NewWorkflowPlanner("testdata/issue-1595/missing.yml", true, false)
|
||||
planner, err := model.NewWorkflowPlanner("testdata/issue-1595/missing.yml", model.PlannerConfig{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
out := log.StandardLogger().Out
|
||||
@@ -123,7 +123,7 @@ func TestGraphWithMissing(t *testing.T) {
|
||||
func TestGraphWithSomeMissing(t *testing.T) {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
|
||||
planner, err := model.NewWorkflowPlanner("testdata/issue-1595/", true, false)
|
||||
planner, err := model.NewWorkflowPlanner("testdata/issue-1595/", model.PlannerConfig{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
out := log.StandardLogger().Out
|
||||
@@ -141,7 +141,7 @@ func TestGraphWithSomeMissing(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGraphEvent(t *testing.T) {
|
||||
planner, err := model.NewWorkflowPlanner("testdata/basic", true, false)
|
||||
planner, err := model.NewWorkflowPlanner("testdata/basic", model.PlannerConfig{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
plan, err := planner.PlanEvent("push")
|
||||
@@ -200,7 +200,7 @@ func (j *TestJobFileInfo) runTest(ctx context.Context, t *testing.T, cfg *Config
|
||||
runner, err := New(runnerConfig)
|
||||
assert.Nil(t, err, j.workflowPath)
|
||||
|
||||
planner, err := model.NewWorkflowPlanner(fullWorkflowPath, true, false)
|
||||
planner, err := model.NewWorkflowPlanner(fullWorkflowPath, model.PlannerConfig{})
|
||||
if j.errorMessage != "" && err != nil {
|
||||
assert.Error(t, err, j.errorMessage)
|
||||
} else if assert.Nil(t, err, fullWorkflowPath) {
|
||||
|
||||
@@ -141,19 +141,19 @@ func runStepExecutor(step step, stage stepStage, executor common.Executor) commo
|
||||
actPath := rc.JobContainer.GetActPath()
|
||||
|
||||
outputFileCommand := path.Join("workflow", "outputcmd.txt")
|
||||
(*step.getEnv())["GITHUB_OUTPUT"] = path.Join(actPath, outputFileCommand)
|
||||
rc.setMainCtxVars(*step.getEnv(), "OUTPUT", path.Join(actPath, outputFileCommand))
|
||||
|
||||
stateFileCommand := path.Join("workflow", "statecmd.txt")
|
||||
(*step.getEnv())["GITHUB_STATE"] = path.Join(actPath, stateFileCommand)
|
||||
rc.setMainCtxVars(*step.getEnv(), "STATE", path.Join(actPath, stateFileCommand))
|
||||
|
||||
pathFileCommand := path.Join("workflow", "pathcmd.txt")
|
||||
(*step.getEnv())["GITHUB_PATH"] = path.Join(actPath, pathFileCommand)
|
||||
rc.setMainCtxVars(*step.getEnv(), "PATH", path.Join(actPath, pathFileCommand))
|
||||
|
||||
envFileCommand := path.Join("workflow", "envs.txt")
|
||||
(*step.getEnv())["GITHUB_ENV"] = path.Join(actPath, envFileCommand)
|
||||
rc.setMainCtxVars(*step.getEnv(), "ENV", path.Join(actPath, envFileCommand))
|
||||
|
||||
summaryFileCommand := path.Join("workflow", "SUMMARY.md")
|
||||
(*step.getEnv())["GITHUB_STEP_SUMMARY"] = path.Join(actPath, summaryFileCommand)
|
||||
rc.setMainCtxVars(*step.getEnv(), "STEP_SUMMARY", path.Join(actPath, summaryFileCommand))
|
||||
|
||||
_ = rc.JobContainer.Copy(actPath, &container.FileEntry{
|
||||
Name: outputFileCommand,
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/actions-oss/act-cli/pkg/common"
|
||||
"github.com/actions-oss/act-cli/pkg/model"
|
||||
@@ -40,17 +39,7 @@ func (sal *stepActionLocal) main() common.Executor {
|
||||
return nil
|
||||
}
|
||||
|
||||
workdir := sal.getRunContext().Config.Workdir
|
||||
actionDir := filepath.Join(workdir, sal.Step.Uses)
|
||||
|
||||
localReader := func(ctx context.Context) actionYamlReader {
|
||||
// In case we want to limit resolving symlinks, folders are resolved by archive function
|
||||
// _, cpath = sal.getContainerActionPathsExt(".")
|
||||
roots := []string{
|
||||
".", // Allow everything, other code permits it already
|
||||
// path.Dir(cpath), // Allow RUNNER_WORKSPACE e.g. GITHUB_WORKSPACE/../
|
||||
// sal.RunContext.JobContainer.GetActPath(), // Allow remote action folders
|
||||
}
|
||||
_, cpath := sal.getContainerActionPaths()
|
||||
return func(filename string) (io.Reader, io.Closer, error) {
|
||||
spath := path.Join(cpath, filename)
|
||||
@@ -69,7 +58,7 @@ func (sal *stepActionLocal) main() common.Executor {
|
||||
return nil, nil, err
|
||||
}
|
||||
if header.FileInfo().Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||
spath, err = symlinkJoin(spath, header.Linkname, roots...)
|
||||
spath, err = symlinkJoin(spath, header.Linkname, ".")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -81,7 +70,7 @@ func (sal *stepActionLocal) main() common.Executor {
|
||||
}
|
||||
}
|
||||
|
||||
actionModel, err := sal.readAction(ctx, sal.Step, actionDir, "", localReader(ctx), os.WriteFile)
|
||||
actionModel, err := sal.readAction(ctx, sal.Step, localReader(ctx), sal.RunContext.Config.Action)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -24,8 +23,8 @@ func (salm *stepActionLocalMocks) runAction(step actionStep) common.Executor {
|
||||
return args.Get(0).(func(context.Context) error)
|
||||
}
|
||||
|
||||
func (salm *stepActionLocalMocks) readAction(_ context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error) {
|
||||
args := salm.Called(step, actionDir, actionPath, readFile, writeFile)
|
||||
func (salm *stepActionLocalMocks) readAction(_ context.Context, step *model.Step, readFile actionYamlReader, config model.ActionConfig) (*model.Action, error) {
|
||||
args := salm.Called(step, readFile, config)
|
||||
return args.Get(0).(*model.Action), args.Error(1)
|
||||
}
|
||||
|
||||
@@ -66,7 +65,7 @@ func TestStepActionLocalTest(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
salm.On("readAction", sal.Step, filepath.Clean("/tmp/path/to/action"), "", mock.Anything, mock.Anything).
|
||||
salm.On("readAction", sal.Step, mock.Anything, sal.RunContext.Config.Action).
|
||||
Return(&model.Action{}, nil)
|
||||
|
||||
cm.On("Copy", "/var/run/act", mock.AnythingOfType("[]*container.FileEntry")).Return(func(_ context.Context) error {
|
||||
|
||||
@@ -92,7 +92,7 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
|
||||
}
|
||||
}
|
||||
|
||||
actionModel, err := sar.readAction(ctx, sar.Step, sar.resolvedSha, sar.remoteAction.Path, remoteReader(ctx), os.WriteFile)
|
||||
actionModel, err := sar.readAction(ctx, sar.Step, remoteReader(ctx), sar.RunContext.Config.Action)
|
||||
sar.action = actionModel
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ type stepActionRemoteMocks struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (sarm *stepActionRemoteMocks) readAction(_ context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error) {
|
||||
args := sarm.Called(step, actionDir, actionPath, readFile, writeFile)
|
||||
func (sarm *stepActionRemoteMocks) readAction(_ context.Context, step *model.Step, readFile actionYamlReader, config model.ActionConfig) (*model.Action, error) {
|
||||
args := sarm.Called(step, readFile, config)
|
||||
return args.Get(0).(*model.Action), args.Error(1)
|
||||
}
|
||||
|
||||
@@ -175,6 +175,9 @@ func TestStepActionRemote(t *testing.T) {
|
||||
GitHubServerURL: tt.gitHubServerURL,
|
||||
GitHubAPIServerURL: tt.gitHubAPIServerURL,
|
||||
GitHubGraphQlAPIServerURL: tt.gitHubGraphQlAPIServerURL,
|
||||
Action: model.ActionConfig{
|
||||
Definition: "action-root",
|
||||
},
|
||||
},
|
||||
Run: &model.Run{
|
||||
JobID: "1",
|
||||
@@ -201,7 +204,7 @@ func TestStepActionRemote(t *testing.T) {
|
||||
cacheMock.Mock.On("Fetch", ctx, mock.AnythingOfType("string"), serverURL+"/remote/action", "v1", "").Return("someval")
|
||||
|
||||
if tt.mocks.read {
|
||||
sarm.Mock.On("readAction", sar.Step, "someval", "", mock.Anything, mock.Anything).Return(&model.Action{}, nil)
|
||||
sarm.Mock.On("readAction", sar.Step, mock.Anything, sar.RunContext.Config.Action).Return(&model.Action{}, nil)
|
||||
}
|
||||
if tt.mocks.run {
|
||||
remoteAction := newRemoteAction(sar.Step.Uses)
|
||||
@@ -282,7 +285,7 @@ func TestStepActionRemotePre(t *testing.T) {
|
||||
readAction: sarm.readAction,
|
||||
}
|
||||
|
||||
sarm.Mock.On("readAction", sar.Step, "someval", "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil)
|
||||
sarm.Mock.On("readAction", sar.Step, mock.Anything, sar.RunContext.Config.Action).Return(&model.Action{}, nil)
|
||||
cacheMock.Mock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "").Return("someval")
|
||||
|
||||
err := sar.pre()(ctx)
|
||||
@@ -335,7 +338,7 @@ func TestStepActionRemotePreThroughAction(t *testing.T) {
|
||||
readAction: sarm.readAction,
|
||||
}
|
||||
|
||||
sarm.Mock.On("readAction", sar.Step, mock.AnythingOfType("string"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil)
|
||||
sarm.Mock.On("readAction", sar.Step, mock.Anything, sar.RunContext.Config.Action).Return(&model.Action{}, nil)
|
||||
cacheMock.Mock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "").Return("someval")
|
||||
|
||||
err := sar.pre()(ctx)
|
||||
@@ -389,7 +392,7 @@ func TestStepActionRemotePreThroughActionToken(t *testing.T) {
|
||||
readAction: sarm.readAction,
|
||||
}
|
||||
|
||||
sarm.Mock.On("readAction", sar.Step, mock.AnythingOfType("string"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil)
|
||||
sarm.Mock.On("readAction", sar.Step, mock.Anything, sar.RunContext.Config.Action).Return(&model.Action{}, nil)
|
||||
cacheMock.Mock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "PRIVATE_ACTIONS_TOKEN_ON_GITHUB").Return("someval")
|
||||
|
||||
err := sar.pre()(ctx)
|
||||
|
||||
Reference in New Issue
Block a user