Documentation
¶
Overview ¶
Package taskrun is an embeddable task and script runner.
A Definition is validated and frozen by New, so later mutation of the caller's maps cannot change a run. Each Run gets isolated variables, environment and working directory; actions run through explicit shells or host handlers, and the processes an action owns are terminated when its context is canceled or its deadline expires.
Index ¶
- Constants
- Variables
- type ActionResult
- type Definition
- type DynamicVar
- type Engine
- type ErrorKind
- type Event
- type EventKind
- type ExecSpec
- type FileSpec
- type Handler
- type HostCall
- type HostSpec
- type IO
- type Interpreter
- type Observer
- type Option
- func WithBaseEnv(env map[string]string) Option
- func WithDynamicOutputLimit(limit int64) Option
- func WithEngine(engine Engine) Option
- func WithHandler(name string, handler Handler) Option
- func WithKillGrace(grace time.Duration) Option
- func WithMaxCallDepth(depth int) Option
- func WithMaxExpansions(limit int) Option
- func WithObserver(observer Observer) Option
- type Plan
- type PlannedAction
- type PreparedAction
- type ProcessEngine
- type ProcessError
- type Request
- type Result
- type RunError
- type Runner
- type ScriptFile
- type ShellSpec
- type Source
- type Status
- type Step
- type StepResult
- type Task
- type TaskCall
- type TaskResult
- type TreeKillMode
Constants ¶
const ( // DefaultMaxCallDepth bounds the static task call chain. DefaultMaxCallDepth = 64 // DefaultMaxExpansions bounds the number of task calls in one run. DefaultMaxExpansions = 10000 // DefaultKillGrace is how long a canceled process tree may exit on its own // before it is killed. DefaultKillGrace = 200 * time.Millisecond // DefaultDynamicOutputLimit bounds the captured output of a dynamic // variable command. DefaultDynamicOutputLimit = 1 << 20 )
Default limits applied by New unless an Option overrides them.
Variables ¶
var ( // ErrNotFound reports that the requested root task name is unknown. // A missing dependency is invalid_definition, not ErrNotFound. ErrNotFound = errors.New("taskrun: task not found") // ErrInvalidRequest reports a rejected Request. ErrInvalidRequest = errors.New("taskrun: invalid request") // ErrInvalidDefinition reports a rejected definition or reference. ErrInvalidDefinition = errors.New("taskrun: invalid definition") // ErrDependencyCycle reports a dependency or task-call cycle. ErrDependencyCycle = errors.New("taskrun: task dependency cycle") // ErrExpansionLimit reports that the run exceeded its call budget. ErrExpansionLimit = errors.New("taskrun: task call expansion limit exceeded") // ErrStart reports that a program could not be started. ErrStart = errors.New("taskrun: program start failed") // ErrExit reports a non-zero process exit. ErrExit = errors.New("taskrun: non-zero exit") // ErrHandler reports a host handler failure. ErrHandler = errors.New("taskrun: handler failed") // ErrOutputLimit reports captured output above its bound. ErrOutputLimit = errors.New("taskrun: output limit exceeded") // ErrIO reports a stream or capture failure. ErrIO = errors.New("taskrun: io failure") )
Functions ¶
This section is empty.
Types ¶
type ActionResult ¶
type ActionResult struct {
Started bool
ExitCode *int
Output []byte
ErrorOutput []byte
Truncated bool
}
ActionResult is returned by an Engine or Handler.
type Definition ¶
type Definition struct {
// Version is the configuration schema version. It is independent of the Go
// module version and must be 1 when set.
Version int
// BaseDir is the absolute directory that relative Dir values and registered
// script files resolve against.
BaseDir string
// Vars are definition level default variables.
Vars map[string]any
// Env are definition level default environment variables.
Env map[string]string
// EnvPaths are prepended to the effective PATH, before Task and Step paths.
EnvPaths []string
// Tasks are the named tasks.
Tasks map[string]Task
// Files is the registry of named script files. A file action refers to a
// name in this registry; configuration cannot load arbitrary programs.
Files map[string]ScriptFile
// Sources records where a loaded definition came from, for diagnostics.
Sources []Source
}
Definition is a task and script definition. New validates it and publishes a private snapshot; later mutations of the caller's value have no effect.
type DynamicVar ¶
DynamicVar is a variable produced by running a command. Only one action may be set.
type Engine ¶
type Engine interface {
Execute(ctx context.Context, action PreparedAction, streams IO) (ActionResult, error)
}
Engine executes a prepared external action. It must honor ctx cancellation, must not schedule tasks or call handlers, and must return a ProcessError (or an error wrapping a context cause) so the runner can classify the failure.
type ErrorKind ¶
type ErrorKind string
ErrorKind classifies a RunError. Consumers should normally test with errors.Is against the package sentinel errors instead of comparing kinds.
const ( // ErrKindInvalidDefinition is a rejected definition or reference. ErrKindInvalidDefinition ErrorKind = "invalid_definition" // ErrKindInvalidRequest is a rejected Request. ErrKindInvalidRequest ErrorKind = "invalid_request" // ErrKindNotFound means the requested root task name does not exist. ErrKindNotFound ErrorKind = "not_found" // ErrKindLoad is a configuration load failure. ErrKindLoad ErrorKind = "load" // ErrKindStart means a program could not be started. ErrKindStart ErrorKind = "start" // ErrKindExit is a non-zero process exit. ErrKindExit ErrorKind = "exit" // ErrKindHandler is a host handler failure. ErrKindHandler ErrorKind = "handler" // ErrKindCanceled is a canceled run. ErrKindCanceled ErrorKind = "canceled" // ErrKindTimedOut is an expired task or step deadline. ErrKindTimedOut ErrorKind = "timed_out" // ErrKindOutputLimit means captured output exceeded its bound. ErrKindOutputLimit ErrorKind = "output_limit" // ErrKindExpansionLimit means the run expanded too many task calls. ErrKindExpansionLimit ErrorKind = "expansion_limit" // ErrKindIO is a stream or capture failure. ErrKindIO ErrorKind = "io" )
type Event ¶
type Event struct {
Kind EventKind
Task string
CallID string
Step string
// ActionKind is "exec", "shell", "file", "task" or "host" for step events.
ActionKind string
// Depth is the task call depth, starting at 1 for the root task.
Depth int
Status Status
// Reason explains a skipped task or step.
Reason string
// Dir is the effective working directory of the run, task or step.
Dir string
// ExitCode is set for a started process.
ExitCode *int
// Err carries the classified failure when one occurred.
Err error
Time time.Time
}
Event is a structured execution event for host logging and progress display. Events never carry captured output; use Result for that. A successful run reports the final status through EventRunFinished.
type EventKind ¶
type EventKind string
EventKind identifies one observable execution event.
const ( // EventRunStarted is emitted once a run has a validated root task. EventRunStarted EventKind = "run_started" // EventRunFinished is emitted once the final status is known. EventRunFinished EventKind = "run_finished" // EventTaskStarted is emitted before a task call evaluates its steps. EventTaskStarted EventKind = "task_started" // EventTaskSkipped is emitted when a call is skipped by platform or condition. EventTaskSkipped EventKind = "task_skipped" // EventTaskFinished is emitted after a task call completes or fails. EventTaskFinished EventKind = "task_finished" // EventStepStarted is emitted before a step action runs. EventStepStarted EventKind = "step_started" // EventStepSkipped is emitted when a step is skipped by platform or condition. EventStepSkipped EventKind = "step_skipped" // EventStepFinished is emitted after a step completes, fails or is ignored. EventStepFinished EventKind = "step_finished" )
type Handler ¶
type Handler func(context.Context, HostCall) (ActionResult, error)
Handler executes an explicitly registered host action. Handlers are registered before New and cannot be replaced afterwards.
type HostCall ¶
type HostCall struct {
Name string
Args []any
Vars map[string]any
Env map[string]string
Dir string
}
HostCall is the isolated input to a Handler. Handlers must respect ctx cooperatively: a Go goroutine cannot be stopped by force.
type IO ¶
IO controls process streams and bounded capture. A nil Stdin means EOF and a nil Stdout or Stderr means the data is discarded. CaptureLimit is a per stream byte bound: 0 streams without collecting, negative values are rejected.
type Interpreter ¶
Interpreter identifies a script interpreter and its prefix arguments, for example go + [run].
type Observer ¶
type Observer func(Event)
Observer receives execution events. Observers cannot change scheduling and do not return errors. Callbacks of one run arrive in order from the goroutine running that run; different runs may call an observer concurrently, so the host must synchronize and return quickly.
type Option ¶
type Option func(*runnerConfig) error
Option configures a Runner. Options are applied before the definition is validated, so an invalid engine, handler name or limit fails New.
func WithBaseEnv ¶
WithBaseEnv sets the environment baseline snapshot. The default is os.Environ copied when New runs; a run never re-reads the process environment and never modifies it.
func WithDynamicOutputLimit ¶
WithDynamicOutputLimit bounds the captured output of a dynamic variable command. Output above the bound fails the run instead of rendering a truncated value.
func WithEngine ¶
WithEngine replaces the external action backend. The backend must honor cancellation and return a ProcessError or a context cause so failures can be classified.
func WithHandler ¶
WithHandler registers a host action. Handlers are immutable after New: a definition that names an unregistered handler is rejected.
func WithKillGrace ¶
WithKillGrace sets how long a canceled process tree may exit on its own before the engine kills it.
func WithMaxCallDepth ¶
WithMaxCallDepth bounds the static task call chain. Zero or negative disables the static check.
func WithMaxExpansions ¶
WithMaxExpansions bounds the number of task calls in one run.
func WithObserver ¶
WithObserver registers an event observer. Observers are optional, cannot change scheduling decisions and do not return errors; callbacks of one run are delivered in order, while different runs may call the observer concurrently.
type Plan ¶
type Plan struct {
Task string
Actions []PlannedAction
Deferred []string
Skipped []string
}
Plan is a side-effect-free execution preview produced by Inspect.
type PlannedAction ¶
type PlannedAction struct {
Task string
CallID string
Step string
Kind string
Program string
Args []string
Script string
Dir string
EnvKeys []string
Status Status
Reason string
}
PlannedAction describes an action in execution order without running it.
type PreparedAction ¶
type PreparedAction struct {
// Kind is "exec", "shell" or "file".
Kind string
// Program is the executable for exec and file, and the requested shell name
// for shell ("sh", "bash", "zsh", "cmd", "pwsh" or "powershell").
Program string
// Args is the argv for exec and file. Exec arguments keep their boundaries:
// the engine must not re-split them.
Args []string
// Script is the complete source for shell actions.
Script string
// Dir is the absolute working directory, empty when BaseDir is used.
Dir string
// Env is the complete environment for the child process. It is never nil.
Env []string
}
PreparedAction is an action that has been validated and rendered. It never represents a task call or a host action, so an Engine can never re-enter the scheduler.
type ProcessEngine ¶
type ProcessEngine struct {
// TreeKill selects the behavior when the strongest available tree cleanup
// cannot be established. The zero value is TreeKillAuto.
TreeKill TreeKillMode
// contains filtered or unexported fields
}
ProcessEngine is the default Engine. It runs argv actions and explicit shell sources as child processes, resolves programs against the effective environment, bounds captured output and terminates the processes it owns when the context is canceled or a deadline expires.
func (ProcessEngine) Execute ¶
func (e ProcessEngine) Execute(ctx context.Context, action PreparedAction, streams IO) (ActionResult, error)
Execute implements Engine.
type ProcessError ¶
ProcessError is the classified error returned by the default process engine.
func (*ProcessError) Error ¶
func (e *ProcessError) Error() string
func (*ProcessError) Is ¶
func (e *ProcessError) Is(target error) bool
Is reports whether the error matches a package sentinel or context cause.
func (*ProcessError) Unwrap ¶
func (e *ProcessError) Unwrap() error
Unwrap exposes the underlying cause.
type Request ¶
type Request struct {
Task string
Args []string
Vars map[string]any
Env map[string]string
HostData map[string]any
Dir string
DryRun bool
IO IO
}
Request describes one isolated run. Inputs are copied when the run starts; the caller must not mutate them concurrently during Run.
type Result ¶
type Result struct {
Status Status
Task string
Tasks []TaskResult
Steps []StepResult
Plan *Plan
StartedAt time.Time
EndedAt time.Time
}
Result is a structured execution result. Status never contradicts the error returned by Run: a non-nil error means the status is Failed, Canceled or TimedOut.
type RunError ¶
type RunError struct {
Kind ErrorKind
Task string
CallID string
Step string
Source string
Err error
}
RunError is the classified error returned by Run and Inspect. It carries the task, call, step and source coordinates of the failure and preserves the underlying cause, including context.Canceled and context.DeadlineExceeded.
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner holds a validated definition snapshot and an immutable backend configuration. One Runner may serve concurrent Runs.
func New ¶
func New(def Definition, opts ...Option) (*Runner, error)
New validates a definition and publishes a private snapshot. Load, New, Lookup, List and Inspect never execute commands; only Run produces side effects through explicit actions and dynamic variables.
func (*Runner) Inspect ¶
Inspect validates the request and expands the call graph without running any action, handler or dynamic variable command.
func (*Runner) Lookup ¶
Lookup returns an exact-name copy of a task. The returned value shares no mutable state with the Runner.
type ScriptFile ¶
type ScriptFile struct {
Name string
Path string
Interpreter Interpreter
Args []string
Env map[string]string
Dir string
}
ScriptFile is a named executable script. Path is absolute after New.
type ShellSpec ¶
type ShellSpec struct {
// Name is one of sh, bash, zsh, cmd, pwsh or powershell.
Name string
// Script is the complete source, rendered with the same template rules as
// other fields.
Script string
// Args are extra arguments inserted before the script for interpreters that
// need them. PrefixArgs are not needed for the built-in shells.
PrefixArgs []string
}
ShellSpec describes explicit shell execution. The shell must be named; the library never guesses a default shell.
type Source ¶
type Source struct {
// Name identifies the file or logical reader.
Name string
// BaseDir is the absolute directory of the source.
BaseDir string
// Format is "json", "yaml" or "toml" when known.
Format string
}
Source records the origin of decoded configuration.
type Status ¶
type Status string
Status is the final status of a run, a task call or a step.
const ( // StatusSucceeded means every executed action completed without error. StatusSucceeded Status = "succeeded" // StatusSucceededWithWarnings means at least one error was tolerated by // ignore_error and the remaining steps completed. StatusSucceededWithWarnings Status = "succeeded_with_warnings" // StatusIgnoredFailure is a step-only status for a tolerated error. StatusIgnoredFailure Status = "ignored_failure" // StatusFailed means the run stopped on an error. StatusFailed Status = "failed" // StatusCanceled means the run was canceled through its context. StatusCanceled Status = "canceled" // StatusTimedOut means a task or step deadline expired. StatusTimedOut Status = "timed_out" // StatusSkipped means a task or step was skipped by a condition or platform rule. StatusSkipped Status = "skipped" // StatusDryRun is the status of a preview produced by Request.DryRun. StatusDryRun Status = "dry_run" // StatusDeferred is a plan-only status: the value depends on a dynamic // variable or other runtime data that Inspect must not evaluate. StatusDeferred Status = "deferred" // StatusPlanned is a plan-only status for an action that will run. StatusPlanned Status = "planned" )
type Step ¶
type Step struct {
Name string
Exec *ExecSpec
Shell *ShellSpec
File *FileSpec
Task *TaskCall
Host *HostSpec
Vars map[string]any
DynamicVars map[string]DynamicVar
Env map[string]string
EnvPaths []string
Dir string
If string
Platform []string
// IgnoreError tolerates a started process with a non-zero exit code or a
// handler business error. It never tolerates a start failure, cancellation,
// timeout, output-limit, IO or configuration error.
IgnoreError bool
// Timeout bounds this step, including its dynamic variables. Zero inherits
// the task budget; negative is invalid.
Timeout time.Duration
}
Step is exactly one action.
type StepResult ¶
type StepResult struct {
Name string
CallID string
Kind string
Status Status
Started bool
ExitCode *int
Output []byte
ErrorOutput []byte
Truncated bool
Err error
StartedAt time.Time
EndedAt time.Time
}
StepResult records one step outcome.
type Task ¶
type Task struct {
Name string
Desc string
Deps []string
Steps []Step
Vars map[string]any
DynamicVars map[string]DynamicVar
Env map[string]string
// CleanEnv drops the Runner base environment for this task. Explicit Env
// values are kept.
CleanEnv bool
EnvPaths []string
// Dir is relative to the run base directory, or absolute.
Dir string
// If is an expr condition. An empty condition means true.
If string
// Platform lists accepted runtime.GOOS values. Empty means every platform.
Platform []string
// Timeout bounds this task call, including its dependencies, steps and
// dynamic variables. Zero inherits the parent budget; negative is invalid.
Timeout time.Duration
}
Task is one executable unit of work.
type TaskCall ¶
type TaskCall struct {
Name string
Args []string
// ForwardArgs appends the root request arguments after Args.
ForwardArgs bool
}
TaskCall invokes another task. A nil Args value inherits the current call arguments; an empty, non-nil Args replaces them.
type TaskResult ¶
type TaskResult struct {
Name string
CallID string
Status Status
Reason string
Err error
StartedAt time.Time
EndedAt time.Time
}
TaskResult records one task call, including skipped calls and their reason.
type TreeKillMode ¶
type TreeKillMode int
TreeKillMode selects what the default engine does when the strongest available tree cleanup cannot be established.
const ( // TreeKillAuto falls back to the next available mechanism. On Windows, when // the process cannot be assigned to a job object (for example because a // restricted job already owns it, as on GitHub Actions runners), the engine // terminates the tree by walking parent process ids instead. The tree is // still terminated; only the owning mechanism differs. TreeKillAuto TreeKillMode = iota // TreeKillRequired fails the action instead of falling back. Use it when the // strongest platform guarantee is mandatory. TreeKillRequired )
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
taskrun
command
Command taskrun runs one task from a definition file.
|
Command taskrun runs one task from a definition file. |
|
examples
|
|
|
basic
command
Command basic shows the smallest embedding of the library: build a definition in Go, run one task and read the structured result.
|
Command basic shows the smallest embedding of the library: build a definition in Go, run one task and read the structured result. |
|
config
command
Command config loads a YAML/JSON/TOML definition file, optionally discovers it from the current directory upwards, and runs a task.
|
Command config loads a YAML/JSON/TOML definition file, optionally discovers it from the current directory upwards, and runs a task. |
|
host
command
Command host shows how an application exposes its own capabilities to a task through an explicitly registered handler, plus dynamic variables and conditions.
|
Command host shows how an application exposes its own capabilities to a task through an explicitly registered handler, plus dynamic variables and conditions. |
|
Package formats decodes task definitions from YAML, JSON and TOML into the taskrun data model, and converts legacy Kite task maps.
|
Package formats decodes task definitions from YAML, JSON and TOML into the taskrun data model, and converts legacy Kite task maps. |
|
internal
|
|
|
data
Package data holds the copy, merge and validation helpers shared by the public package and its internal implementations.
|
Package data holds the copy, merge and validation helpers shared by the public package and its internal implementations. |
|
graph
Package graph validates the static task graph: it rejects dependency and task call cycles and over-deep call chains before any action runs.
|
Package graph validates the static task graph: it rejects dependency and task call cycles and over-deep call chains before any action runs. |
|
process
Package process owns the platform specific process tree of one action.
|
Package process owns the platform specific process tree of one action. |
|
render
Package render interpolates the library's namespaced templates and evaluates expr conditions against a read-only view.
|
Package render interpolates the library's namespaced templates and evaluates expr conditions against a read-only view. |