executor

package
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

Package executor runs a provider-agnostic pipeline.Pipeline by creating a Docker container per job and executing its steps inside it via the Docker Engine API (never by shelling out to the docker CLI).

Index

Constants

This section is empty.

Variables

View Source
var ErrAborted = fmt.Errorf("pipeline aborted by user")

ErrAborted is returned by Run/runJob when a StepController returns Abort for a step that had itself succeeded (an unprompted failure instead surfaces its own, more specific error).

Functions

func IsShellSupported added in v0.3.1

func IsShellSupported(shell string) bool

IsShellSupported reports whether shell is one execStep can actually run a step's command under — the same check shellCommand makes, exposed so `polyci check` can classify a step's shell: without needing Docker or duplicating this package's list of supported shells.

Types

type Decision

type Decision int

Decision is the debugger's answer to whether the pipeline should keep going after a step, returned from StepController.AfterStep.

const (
	// Continue moves on to the pipeline's next step, even one that
	// followed a failed step — a debugger may let the user override a
	// failure and keep going to investigate further.
	Continue Decision = iota
	// Abort stops the whole pipeline immediately.
	Abort
	// Retry re-runs the step that just finished — same container, same
	// command — instead of moving on or stopping. If the retry fails too,
	// the controller is consulted again with that fresh result, so retry
	// can be chosen repeatedly.
	Retry
)

type Docker

type Docker struct {
	// contains filtered or unexported fields
}

Docker executes pipelines against a Docker Engine.

func New

func New(log Logger, opts ...Option) (*Docker, error)

New connects to the local Docker Engine and returns a Docker executor. If DOCKER_HOST is unset, it resolves the host from the Docker CLI's active context (as `docker` itself does), so engines like Colima or Rancher Desktop that aren't the "default" context are found without the caller having to export DOCKER_HOST by hand.

func (*Docker) Close

func (d *Docker) Close() error

Close releases the underlying Docker client connection.

func (*Docker) Run

func (d *Docker) Run(ctx context.Context, p *pipeline.Pipeline) error

Run executes the pipeline's jobs according to their DependsOn edges: every job starts as soon as all of its dependencies have finished successfully, so independent jobs (and jobs whose shared dependencies have already succeeded) run concurrently rather than waiting on each other. If a job fails or is skipped, everything that depends on it (directly or transitively) is skipped rather than run — but that only affects that job's own dependents; independent branches of the DAG are unaffected and still run to completion. Run itself always waits for every job to reach a terminal state before returning, so one branch failing early never cuts a sibling branch short.

p.SkippedJobs — jobs the parser already determined can't run at all (e.g. a GitHub Actions job with no container:) — are reported via JobSkipped up front, before any job starts; they were never part of p.Jobs to begin with, so nothing else in Run needs to know about them.

func (*Docker) Shell

func (d *Docker) Shell(ctx context.Context, containerID string) error

Shell drops the caller into an interactive shell inside the given container, wiring os.Stdin/os.Stdout to it over a Docker exec TTY. It prefers bash if the image has it, falling back to sh, and blocks until the shell exits.

type Logger

type Logger interface {
	// JobStart is called before a job's first step runs.
	JobStart(jobName, stage, image string)
	// StepStart is called before a step runs.
	StepStart(jobName, stepName, command string)
	// StepOutput is called with a chunk of a step's combined stdout/stderr.
	StepOutput(jobName, stepName string, chunk []byte)
	// StepDone is called after a step finishes.
	StepDone(jobName, stepName string, exitCode int64, err error)
	// JobDone is called after a job's steps finish (or one failed). Not
	// called for a job that was skipped — see JobSkipped.
	JobDone(jobName string, err error)
	// JobSkipped is called instead of JobStart/JobDone for a job that
	// never ran because a dependency it needed failed or was itself
	// skipped. reason explains why.
	JobSkipped(jobName string, reason error)
}

Logger receives streamed pipeline output. Independent jobs run concurrently, so its methods may be called from multiple goroutines at once for different jobs — implementations must be safe for concurrent use. Calls for any single job are still made in order and never overlap with each other.

type Option

type Option func(*Docker)

Option configures optional behavior on a Docker executor.

func WithController

func WithController(c StepController) Option

WithController attaches a debugger layer that is asked, after every step, whether the pipeline should continue or abort.

func WithWorkspace

func WithWorkspace(hostPath string) Option

WithWorkspace overrides the host directory bind-mounted into every job's container at /workspace (read-write). Defaults to the current working directory, matching how a real checkout puts the repo at the job's working directory.

type ShellFunc

type ShellFunc func(ctx context.Context) error

ShellFunc drops the caller into an interactive shell inside the container a step just ran in, wiring the real terminal's stdin/stdout to it. It blocks until the user exits the shell.

type StepController

type StepController interface {
	AfterStep(ctx context.Context, jobName string, step pipeline.Step, exitCode int64, stepErr error, shell ShellFunc) Decision
}

StepController is consulted after every step finishes, letting a debugger layer pause the pipeline, offer an interactive shell in the step's own container, and decide whether to continue or abort. When nil, the executor runs straight through and stops automatically at the first failing step (Phase 1 behavior).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL