Read localaction's from container (#719)
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>
This commit is contained in:
parent
531ea02fb9
commit
0ff204b615
6 changed files with 65 additions and 16 deletions
|
@ -20,6 +20,7 @@ import (
|
||||||
// NewDockerBuildExecutorInput the input for the NewDockerBuildExecutor function
|
// NewDockerBuildExecutorInput the input for the NewDockerBuildExecutor function
|
||||||
type NewDockerBuildExecutorInput struct {
|
type NewDockerBuildExecutorInput struct {
|
||||||
ContextDir string
|
ContextDir string
|
||||||
|
Container Container
|
||||||
ImageTag string
|
ImageTag string
|
||||||
Platform string
|
Platform string
|
||||||
}
|
}
|
||||||
|
@ -46,8 +47,12 @@ func NewDockerBuildExecutor(input NewDockerBuildExecutorInput) common.Executor {
|
||||||
Remove: true,
|
Remove: true,
|
||||||
Platform: input.Platform,
|
Platform: input.Platform,
|
||||||
}
|
}
|
||||||
|
var buildContext io.ReadCloser
|
||||||
buildContext, err := createBuildContext(input.ContextDir, "Dockerfile")
|
if input.Container != nil {
|
||||||
|
buildContext, err = input.Container.GetContainerArchive(ctx, input.ContextDir+"/.")
|
||||||
|
} else {
|
||||||
|
buildContext, err = createBuildContext(input.ContextDir, "Dockerfile")
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ type Container interface {
|
||||||
Create(capAdd []string, capDrop []string) common.Executor
|
Create(capAdd []string, capDrop []string) common.Executor
|
||||||
Copy(destPath string, files ...*FileEntry) common.Executor
|
Copy(destPath string, files ...*FileEntry) common.Executor
|
||||||
CopyDir(destPath string, srcPath string, useGitIgnore bool) 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
|
Pull(forcePull bool) common.Executor
|
||||||
Start(attach bool) common.Executor
|
Start(attach bool) common.Executor
|
||||||
Exec(command []string, env map[string]string, user string) 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)
|
).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 {
|
func (cr *containerReference) UpdateFromEnv(srcPath string, env *map[string]string) common.Executor {
|
||||||
return cr.extractEnv(srcPath, env).IfNot(common.Dryrun)
|
return cr.extractEnv(srcPath, env).IfNot(common.Dryrun)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package runner
|
package runner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"archive/tar"
|
||||||
"context"
|
"context"
|
||||||
|
"io"
|
||||||
|
|
||||||
// Go told me to?
|
// Go told me to?
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -77,8 +80,8 @@ func (sc *StepContext) Executor() common.Executor {
|
||||||
case model.StepTypeUsesActionLocal:
|
case model.StepTypeUsesActionLocal:
|
||||||
actionDir := filepath.Join(rc.Config.Workdir, step.Uses)
|
actionDir := filepath.Join(rc.Config.Workdir, step.Uses)
|
||||||
return common.NewPipelineExecutor(
|
return common.NewPipelineExecutor(
|
||||||
sc.setupAction(actionDir, ""),
|
sc.setupAction(actionDir, "", true),
|
||||||
sc.runAction(actionDir, ""),
|
sc.runAction(actionDir, "", true),
|
||||||
)
|
)
|
||||||
case model.StepTypeUsesActionRemote:
|
case model.StepTypeUsesActionRemote:
|
||||||
remoteAction := newRemoteAction(step.Uses)
|
remoteAction := newRemoteAction(step.Uses)
|
||||||
|
@ -116,8 +119,8 @@ func (sc *StepContext) Executor() common.Executor {
|
||||||
}
|
}
|
||||||
return common.NewPipelineExecutor(
|
return common.NewPipelineExecutor(
|
||||||
ntErr,
|
ntErr,
|
||||||
sc.setupAction(actionDir, remoteAction.Path),
|
sc.setupAction(actionDir, remoteAction.Path, false),
|
||||||
sc.runAction(actionDir, remoteAction.Path),
|
sc.runAction(actionDir, remoteAction.Path, false),
|
||||||
)
|
)
|
||||||
case model.StepTypeInvalid:
|
case model.StepTypeInvalid:
|
||||||
return common.NewErrorExecutor(fmt.Errorf("Invalid run/uses syntax for job:%s step:%+v", rc.Run, step))
|
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
|
//go:embed res/trampoline.js
|
||||||
var trampoline []byte
|
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 {
|
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) {
|
if os.IsNotExist(err) {
|
||||||
f, err = os.Open(filepath.Join(actionDir, actionPath, "action.yaml"))
|
reader, closer, err = readFile("action.yaml")
|
||||||
if err != nil {
|
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{
|
sc.Action = &model.Action{
|
||||||
Name: "(Synthetic)",
|
Name: "(Synthetic)",
|
||||||
Runs: model.ActionRuns{
|
Runs: model.ActionRuns{
|
||||||
|
@ -381,9 +406,10 @@ func (sc *StepContext) setupAction(actionDir string, actionPath string) common.E
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer closer.Close()
|
||||||
|
|
||||||
sc.Action, err = model.ReadAction(f)
|
sc.Action, err = model.ReadAction(reader)
|
||||||
log.Debugf("Read action %v from '%s'", sc.Action, f.Name())
|
log.Debugf("Read action %v from '%s'", sc.Action, "Unknown")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -420,7 +446,7 @@ func (sc *StepContext) getContainerActionPaths(step *model.Step, actionDir strin
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint: gocyclo
|
// 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
|
rc := sc.RunContext
|
||||||
step := sc.Step
|
step := sc.Step
|
||||||
return func(ctx context.Context) error {
|
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)
|
log.Debugf("executing remote job container: %s", containerArgs)
|
||||||
return rc.execJobContainer(containerArgs, sc.Env)(ctx)
|
return rc.execJobContainer(containerArgs, sc.Env)(ctx)
|
||||||
case model.ActionRunsUsingDocker:
|
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:
|
case model.ActionRunsUsingComposite:
|
||||||
return sc.execAsComposite(ctx, step, actionDir, rc, containerActionDir, actionName, actionPath, action, maybeCopyToActionDir)
|
return sc.execAsComposite(ctx, step, actionDir, rc, containerActionDir, actionName, actionPath, action, maybeCopyToActionDir)
|
||||||
default:
|
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 prepImage common.Executor
|
||||||
var image string
|
var image string
|
||||||
if strings.HasPrefix(action.Runs.Image, "docker://") {
|
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("%s:%s", regexp.MustCompile("[^a-zA-Z0-9]").ReplaceAllString(actionName, "-"), "latest")
|
||||||
image = fmt.Sprintf("act-%s", strings.TrimLeft(image, "-"))
|
image = fmt.Sprintf("act-%s", strings.TrimLeft(image, "-"))
|
||||||
image = strings.ToLower(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")
|
anyArchExists, err := container.ImageExistsLocally(ctx, image, "any")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -507,9 +537,14 @@ func (sc *StepContext) execAsDocker(ctx context.Context, action *model.Action, a
|
||||||
|
|
||||||
if !correctArchExists {
|
if !correctArchExists {
|
||||||
log.Debugf("image '%s' for architecture '%s' will be built from context '%s", image, rc.Config.ContainerArchitecture, contextDir)
|
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{
|
prepImage = container.NewDockerBuildExecutor(container.NewDockerBuildExecutorInput{
|
||||||
ContextDir: contextDir,
|
ContextDir: contextDir,
|
||||||
ImageTag: image,
|
ImageTag: image,
|
||||||
|
Container: actionContainer,
|
||||||
Platform: rc.Config.ContainerArchitecture,
|
Platform: rc.Config.ContainerArchitecture,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|
1
pkg/runner/testdata/basic/push.yml
vendored
1
pkg/runner/testdata/basic/push.yml
vendored
|
@ -22,6 +22,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [check]
|
needs: [check]
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
- uses: ./actions/action1
|
- uses: ./actions/action1
|
||||||
with:
|
with:
|
||||||
args: echo 'build'
|
args: echo 'build'
|
||||||
|
|
1
pkg/runner/testdata/parallel/push.yml
vendored
1
pkg/runner/testdata/parallel/push.yml
vendored
|
@ -5,6 +5,7 @@ jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
- uses: ./actions/action1
|
- uses: ./actions/action1
|
||||||
with:
|
with:
|
||||||
args: echo 'build'
|
args: echo 'build'
|
||||||
|
|
1
pkg/runner/testdata/uses-composite/push.yml
vendored
1
pkg/runner/testdata/uses-composite/push.yml
vendored
|
@ -5,6 +5,7 @@ jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
- uses: ./uses-composite/composite_action
|
- uses: ./uses-composite/composite_action
|
||||||
id: composite
|
id: composite
|
||||||
with:
|
with:
|
||||||
|
|
Loading…
Add table
Reference in a new issue