summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopherHX <christopher.homberger@web.de>2021-08-03 19:39:56 +0200
committerGitHub <noreply@github.com>2021-08-03 19:39:56 +0200
commit0ff204b61523b0137d41c4479a132fde87211327 (patch)
tree16c4f31055d4d44718db4c05870aa0474b11fcd8
parentFix `ImageOS` format (#761) (diff)
downloadforgejo-act-0ff204b61523b0137d41c4479a132fde87211327.tar.xz
forgejo-act-0ff204b61523b0137d41c4479a132fde87211327.zip
Read localaction's from container (#719)v0.2.24
Fix localaction tests (missing checkout) Co-authored-by: Ryan (hackercat) <me@hackerc.at> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
-rw-r--r--pkg/container/docker_build.go9
-rw-r--r--pkg/container/docker_run.go6
-rw-r--r--pkg/runner/step_context.go63
-rw-r--r--pkg/runner/testdata/basic/push.yml1
-rw-r--r--pkg/runner/testdata/parallel/push.yml1
-rwxr-xr-xpkg/runner/testdata/uses-composite/push.yml1
6 files changed, 65 insertions, 16 deletions
diff --git a/pkg/container/docker_build.go b/pkg/container/docker_build.go
index 95d15e2..537a5bd 100644
--- a/pkg/container/docker_build.go
+++ b/pkg/container/docker_build.go
@@ -20,6 +20,7 @@ import (
// NewDockerBuildExecutorInput the input for the NewDockerBuildExecutor function
type NewDockerBuildExecutorInput struct {
ContextDir string
+ Container Container
ImageTag string
Platform string
}
@@ -46,8 +47,12 @@ func NewDockerBuildExecutor(input NewDockerBuildExecutorInput) common.Executor {
Remove: true,
Platform: input.Platform,
}
-
- buildContext, err := createBuildContext(input.ContextDir, "Dockerfile")
+ var buildContext io.ReadCloser
+ if input.Container != nil {
+ buildContext, err = input.Container.GetContainerArchive(ctx, input.ContextDir+"/.")
+ } else {
+ buildContext, err = createBuildContext(input.ContextDir, "Dockerfile")
+ }
if err != nil {
return err
}
diff --git a/pkg/container/docker_run.go b/pkg/container/docker_run.go
index b050d3d..6e4d3d8 100644
--- a/pkg/container/docker_run.go
+++ b/pkg/container/docker_run.go
@@ -66,6 +66,7 @@ type Container interface {
Create(capAdd []string, capDrop []string) common.Executor
Copy(destPath string, files ...*FileEntry) common.Executor
CopyDir(destPath string, srcPath string, useGitIgnore bool) common.Executor
+ GetContainerArchive(ctx context.Context, srcPath string) (io.ReadCloser, error)
Pull(forcePull bool) common.Executor
Start(attach bool) common.Executor
Exec(command []string, env map[string]string, user string) common.Executor
@@ -150,6 +151,11 @@ func (cr *containerReference) CopyDir(destPath string, srcPath string, useGitIgn
).IfNot(common.Dryrun)
}
+func (cr *containerReference) GetContainerArchive(ctx context.Context, srcPath string) (io.ReadCloser, error) {
+ a, _, err := cr.cli.CopyFromContainer(ctx, cr.id, srcPath)
+ return a, err
+}
+
func (cr *containerReference) UpdateFromEnv(srcPath string, env *map[string]string) common.Executor {
return cr.extractEnv(srcPath, env).IfNot(common.Dryrun)
}
diff --git a/pkg/runner/step_context.go b/pkg/runner/step_context.go
index 98c2e7c..372c594 100644
--- a/pkg/runner/step_context.go
+++ b/pkg/runner/step_context.go
@@ -1,7 +1,10 @@
package runner
import (
+ "archive/tar"
"context"
+ "io"
+
// Go told me to?
_ "embed"
"fmt"
@@ -77,8 +80,8 @@ func (sc *StepContext) Executor() common.Executor {
case model.StepTypeUsesActionLocal:
actionDir := filepath.Join(rc.Config.Workdir, step.Uses)
return common.NewPipelineExecutor(
- sc.setupAction(actionDir, ""),
- sc.runAction(actionDir, ""),
+ sc.setupAction(actionDir, "", true),
+ sc.runAction(actionDir, "", true),
)
case model.StepTypeUsesActionRemote:
remoteAction := newRemoteAction(step.Uses)
@@ -116,8 +119,8 @@ func (sc *StepContext) Executor() common.Executor {
}
return common.NewPipelineExecutor(
ntErr,
- sc.setupAction(actionDir, remoteAction.Path),
- sc.runAction(actionDir, remoteAction.Path),
+ sc.setupAction(actionDir, remoteAction.Path, false),
+ sc.runAction(actionDir, remoteAction.Path, false),
)
case model.StepTypeInvalid:
return common.NewErrorExecutor(fmt.Errorf("Invalid run/uses syntax for job:%s step:%+v", rc.Run, step))
@@ -330,13 +333,35 @@ func (sc *StepContext) runUsesContainer() common.Executor {
//go:embed res/trampoline.js
var trampoline []byte
-func (sc *StepContext) setupAction(actionDir string, actionPath string) common.Executor {
+func (sc *StepContext) setupAction(actionDir string, actionPath string, localAction bool) common.Executor {
return func(ctx context.Context) error {
- f, err := os.Open(filepath.Join(actionDir, actionPath, "action.yml"))
+ var readFile func(filename string) (io.Reader, io.Closer, error)
+ if localAction {
+ _, cpath := sc.getContainerActionPaths(sc.Step, path.Join(actionDir, actionPath), sc.RunContext)
+ readFile = func(filename string) (io.Reader, io.Closer, error) {
+ tars, err := sc.RunContext.JobContainer.GetContainerArchive(ctx, path.Join(cpath, filename))
+ if err != nil {
+ return nil, nil, os.ErrNotExist
+ }
+ treader := tar.NewReader(tars)
+ if _, err := treader.Next(); err != nil {
+ return nil, nil, os.ErrNotExist
+ }
+ return treader, tars, nil
+ }
+ } else {
+ readFile = func(filename string) (io.Reader, io.Closer, error) {
+ f, err := os.Open(filepath.Join(actionDir, actionPath, filename))
+ return f, f, err
+ }
+ }
+
+ reader, closer, err := readFile("action.yml")
if os.IsNotExist(err) {
- f, err = os.Open(filepath.Join(actionDir, actionPath, "action.yaml"))
+ reader, closer, err = readFile("action.yaml")
if err != nil {
- if _, err2 := os.Stat(filepath.Join(actionDir, actionPath, "Dockerfile")); err2 == nil {
+ if _, closer, err2 := readFile("Dockerfile"); err2 == nil {
+ closer.Close()
sc.Action = &model.Action{
Name: "(Synthetic)",
Runs: model.ActionRuns{
@@ -381,9 +406,10 @@ func (sc *StepContext) setupAction(actionDir string, actionPath string) common.E
} else if err != nil {
return err
}
+ defer closer.Close()
- sc.Action, err = model.ReadAction(f)
- log.Debugf("Read action %v from '%s'", sc.Action, f.Name())
+ sc.Action, err = model.ReadAction(reader)
+ log.Debugf("Read action %v from '%s'", sc.Action, "Unknown")
return err
}
}
@@ -420,7 +446,7 @@ func (sc *StepContext) getContainerActionPaths(step *model.Step, actionDir strin
}
// nolint: gocyclo
-func (sc *StepContext) runAction(actionDir string, actionPath string) common.Executor {
+func (sc *StepContext) runAction(actionDir string, actionPath string, localAction bool) common.Executor {
rc := sc.RunContext
step := sc.Step
return func(ctx context.Context) error {
@@ -461,7 +487,7 @@ func (sc *StepContext) runAction(actionDir string, actionPath string) common.Exe
log.Debugf("executing remote job container: %s", containerArgs)
return rc.execJobContainer(containerArgs, sc.Env)(ctx)
case model.ActionRunsUsingDocker:
- return sc.execAsDocker(ctx, action, actionName, actionDir, actionPath, rc, step)
+ return sc.execAsDocker(ctx, action, actionName, containerActionDir, actionLocation, rc, step, localAction)
case model.ActionRunsUsingComposite:
return sc.execAsComposite(ctx, step, actionDir, rc, containerActionDir, actionName, actionPath, action, maybeCopyToActionDir)
default:
@@ -474,7 +500,7 @@ func (sc *StepContext) runAction(actionDir string, actionPath string) common.Exe
}
}
-func (sc *StepContext) execAsDocker(ctx context.Context, action *model.Action, actionName string, actionDir string, actionPath string, rc *RunContext, step *model.Step) error {
+func (sc *StepContext) execAsDocker(ctx context.Context, action *model.Action, actionName string, containerLocation string, actionLocation string, rc *RunContext, step *model.Step, localAction bool) error {
var prepImage common.Executor
var image string
if strings.HasPrefix(action.Runs.Image, "docker://") {
@@ -483,7 +509,11 @@ func (sc *StepContext) execAsDocker(ctx context.Context, action *model.Action, a
image = fmt.Sprintf("%s:%s", regexp.MustCompile("[^a-zA-Z0-9]").ReplaceAllString(actionName, "-"), "latest")
image = fmt.Sprintf("act-%s", strings.TrimLeft(image, "-"))
image = strings.ToLower(image)
- contextDir := filepath.Join(actionDir, actionPath, action.Runs.Main)
+ basedir := actionLocation
+ if localAction {
+ basedir = containerLocation
+ }
+ contextDir := filepath.Join(basedir, action.Runs.Main)
anyArchExists, err := container.ImageExistsLocally(ctx, image, "any")
if err != nil {
@@ -507,9 +537,14 @@ func (sc *StepContext) execAsDocker(ctx context.Context, action *model.Action, a
if !correctArchExists {
log.Debugf("image '%s' for architecture '%s' will be built from context '%s", image, rc.Config.ContainerArchitecture, contextDir)
+ var actionContainer container.Container = nil
+ if localAction {
+ actionContainer = sc.RunContext.JobContainer
+ }
prepImage = container.NewDockerBuildExecutor(container.NewDockerBuildExecutorInput{
ContextDir: contextDir,
ImageTag: image,
+ Container: actionContainer,
Platform: rc.Config.ContainerArchitecture,
})
} else {
diff --git a/pkg/runner/testdata/basic/push.yml b/pkg/runner/testdata/basic/push.yml
index 2e660b8..8b67f21 100644
--- a/pkg/runner/testdata/basic/push.yml
+++ b/pkg/runner/testdata/basic/push.yml
@@ -22,6 +22,7 @@ jobs:
runs-on: ubuntu-latest
needs: [check]
steps:
+ - uses: actions/checkout@v2
- uses: ./actions/action1
with:
args: echo 'build'
diff --git a/pkg/runner/testdata/parallel/push.yml b/pkg/runner/testdata/parallel/push.yml
index 39ad508..0e79d81 100644
--- a/pkg/runner/testdata/parallel/push.yml
+++ b/pkg/runner/testdata/parallel/push.yml
@@ -5,6 +5,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
+ - uses: actions/checkout@v2
- uses: ./actions/action1
with:
args: echo 'build'
diff --git a/pkg/runner/testdata/uses-composite/push.yml b/pkg/runner/testdata/uses-composite/push.yml
index 9451890..cecb119 100755
--- a/pkg/runner/testdata/uses-composite/push.yml
+++ b/pkg/runner/testdata/uses-composite/push.yml
@@ -5,6 +5,7 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
+ - uses: actions/checkout@v2
- uses: ./uses-composite/composite_action
id: composite
with: