Files
act_runner/act/runner/step_docker.go
T
1745c7c841 fix: fail the step or job whose expression cannot be interpolated (#1199)
An expression that failed to evaluate was logged and replaced by an empty string, so a `run:` step executed an empty script and reported success. The same swallow covered `shell:`, `working-directory:`, step `env:`, `with:`, `uses:`, the job's `env:`, `container:`, `services:`, `runs-on:` and outputs, and a called workflow's `with:` and `secrets:`. Every interpolation now propagates its error as actions/runner does: step-level values fail the step, job-level values fail the job at setup, `timeout-minutes` logs the error and runs unbounded, and a job or step name keeps its source text.

`defaults.run` and a called workflow's inputs and secrets are resolved once at job setup with the job context rather than per step, and the job's image is resolved once, so host mode and `ImageOS` derive from the image the job started with.

Closes https://gitea.com/gitea/runner/issues/392
Closes https://gitea.com/gitea/runner/issues/555

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <2021+silverwind@noreply.gitea.com>
Reviewed-on: https://gitea.com/gitea/runner/pulls/1199
Reviewed-by: silverwind <2021+silverwind@noreply.gitea.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-09-03 10:43:04 +00:00

95 lines
2.3 KiB
Go

// Copyright 2022 The Gitea Authors. All rights reserved.
// Copyright 2022 The nektos/act Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package runner
import (
"context"
"fmt"
"strings"
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/container"
"gitea.dev/actionslib/pkg/model"
"github.com/kballard/go-shellquote"
)
type stepDocker struct {
Step *model.Step
RunContext *RunContext
env map[string]string
}
func (sd *stepDocker) pre() common.Executor { return common.NewPipelineExecutor() }
func (sd *stepDocker) main() common.Executor {
sd.env = map[string]string{}
return runStepExecutor(sd, stepStageMain, sd.runUsesContainer())
}
func (sd *stepDocker) post() common.Executor { return common.NewPipelineExecutor() }
func (sd *stepDocker) getRunContext() *RunContext {
return sd.RunContext
}
func (sd *stepDocker) getGithubContext(ctx context.Context) *model.GithubContext {
return sd.getRunContext().getGithubContext(ctx)
}
func (sd *stepDocker) getStepModel() *model.Step {
return sd.Step
}
func (sd *stepDocker) getEnv() *map[string]string {
return &sd.env
}
func (sd *stepDocker) getIfExpression(_ context.Context, _ stepStage) string {
return sd.Step.If.Value
}
func (sd *stepDocker) runUsesContainer() common.Executor {
rc := sd.RunContext
step := sd.Step
return func(ctx context.Context) error {
image := strings.TrimPrefix(step.Uses, "docker://")
eval := rc.NewExpressionEvaluator(ctx)
args, err := eval.Interpolate(ctx, step.With["args"])
if err != nil {
return fmt.Errorf("unable to interpolate with.args: %w", err)
}
cmd, err := shellquote.Split(args)
if err != nil {
return err
}
var entrypoint []string
entry, err := eval.Interpolate(ctx, step.With["entrypoint"])
if err != nil {
return fmt.Errorf("unable to interpolate with.entrypoint: %w", err)
}
if entry != "" {
entrypoint = []string{entry}
}
stepContainer, err := newStepContainer(ctx, sd, image, cmd, entrypoint, "")
if err != nil {
return err
}
return common.NewPipelineExecutor(
stepContainer.Pull(rc.Config.ForcePull),
stepContainer.Remove(),
stepContainer.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop),
stepContainer.Start(true),
).Finally(stepContainer.Close())(ctx)
}
}
var ContainerNewContainer = container.NewContainer