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 ¶
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
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 ¶
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) Run ¶
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.
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 ¶
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 ¶
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).