zuke

← Python API reference

Zuke for Python: author your build as typed Python, run it on the Zuke engine.

Symbols

#

BooleanParameter

class
class BooleanParameter(Parameter)

A boolean parameter: a flag that takes no value.

  • default(value: bool) -> Self

    The value when the flag is not given.

  • value: bool | None

    The resolved value, or None when unset.

#

Build

class
class Build

Extend this with targets as fields; see target.

  • deadline: ClassVar[Duration | None]

    How long the whole run may take, as a duration or milliseconds.

  • unforceable: ClassVar[tuple[Target, ...]]

    Targets --force may never re-run.

  • targets_: ClassVar[dict[str, Target]]

    The targets by name, in declaration order; set when the subclass is made.

  • parameters_: ClassVar[dict[str, Parameter]]

    The parameters by name, in declaration order; set when the subclass is made.

  • groups_: ClassVar[dict[str, Group]]

    The groups by name, in declaration order; set when the subclass is made.

  • ci_: ClassVar[dict[str, Ci]]

    The CI files by name, in declaration order; set when the subclass is made.

  • on_start() -> Awaitable[None] | None

    Override to run before the first target; sync or async.

  • on_target_start(target: str) -> Awaitable[None] | None

    Override to run before each target; sync or async.

  • on_target_end(target: str, status: str) -> Awaitable[None] | None

    Override to run after each target settles, with its status; sync or async.

  • on_finish(ok: bool) -> Awaitable[None] | None

    Override to run when the build is done, told whether it succeeded.

  • hooks_() -> dict[str, bool]

    Which hooks this build overrides: the ones the engine will call.

  • describe() -> dict[str, object]

    The manifest: what build.describe answers.

  • configure(parameters: Mapping[str, str | None]) -> None

    Take the resolved parameters from build.configure.

  • target_(name: str, method: str) -> Target

    The target method asks about, or a ProtocolError naming it.

  • service_(name: str, method: str) -> Service

    The service method asks about, or a ProtocolError naming it.

#

Ci

class
class Ci(Field)

One CI file. Start one with ci.

  • provider(provider: Provider) -> Self

    The provider to render for; GitHub when not set.

  • path(path: str) -> Self

    The output path, overriding the one the field name implies.

  • pipeline(fields: Mapping[str, object]) -> Self

    The pipeline fields, and the jobs unless invokes or fan_out do.

  • invokes(*entries: Field | str | Mapping[str, object]) -> Self

    The targets to run as jobs: bare, or through invoke to adjust.

  • fan_out(options: bool | Mapping[str, object]=True) -> Self

    One job per target in the graph, with the fan-out options.

  • pins(pins: Mapping[str, object]) -> Self

    Pinned action references by action name.

  • references() -> list[Field | str]

    Every target the file invokes, for the build to check.

  • manifest() -> dict[str, object]

    The file as the manifest's ci list carries it.

#

ci

function
def ci() -> Ci

A new CI file, to configure fluently and assign to a build field.

#

CommandError

class
class CommandError(Exception)

A command ServiceContext.sh ran exited with a code other than zero.

  • argv: tuple[str, ...]

    The command, as discrete arguments.

  • result: ExecResult

    Its exit code and output.

#

Context

class
class Context(ServiceContext)

What a body is handed: the run it is part of, and all the engine serves it.

  • run_id: str

    The run's id, as the run record and zuke resume name it.

  • dry_run: bool

    Whether the run is a --dry-run.

  • state: StateHandle

    This target's durable state.

  • state_of(target: str) -> StateHandle

    Another target's durable state.

  • async outcome_of(target: str) -> Outcome | None

    What target did in this run, or None if it has not run.

  • async outcomes() -> dict[str, Outcome]

    What every settled target did in this run, by name.

  • async summary(pairs: Mapping[str, str | float]) -> None

    Report notes into this target's row of the build summary.

  • async plan() -> Plan

    The run's plan: the planned targets and each one's dependencies.

  • async signals() -> dict[str, object]

    The external signals this run has received, by name.

#

Duration

type
Duration = str | int

A duration as the engine takes it: "5m", "250ms" or milliseconds.

#

ExecResult

class
class ExecResult

What a command the engine ran for the body came back with.

  • code: int

    The exit code.

  • stdout: str

    What it printed to stdout.

  • stderr: str

    What it printed to stderr.

#

Group

class
class Group(Field)

A parallel batch of targets, named like one. Start one with group.

  • members_: tuple[Target, ...]

    The targets in the group.

  • manifest() -> dict[str, object]

    The group as the engine's manifest describes it.

#

group

function
def group(*members: Target) -> Group

A new group of members, to assign to a build field.

#

invoke

function
def invoke(target: Field | str, *, after: Sequence[Field | str]=(), **adjustments: object) -> dict[str, object]

An invoked target with the runner's adjustments, for Ci.invokes.

after adds needs: edges; the other keywords, such as matrix, are the invocation's fields as the engine names them.

#

LockSettings

class
class LockSettings

A cross-run lock, as .lock(lambda s: ...) configures it.

  • key(key: str) -> Self

    The lock's key, shared by every run that must not overlap.

  • ttl(ttl: Duration) -> Self

    How long the lock may be held.

  • wait_up_to(limit: Duration) -> Self

    How long to wait for a held lock before giving up.

  • poll_every(interval: Duration) -> Self

    How often to poll a held lock.

  • hold_for_run() -> Self

    Keep the lock until the run ends rather than until the target does.

  • manifest() -> dict[str, object]

    The lock section of target.settings.

#

NumberListParameter

class
class NumberListParameter(Parameter)

A list of numbers: a comma-separated value on the command line.

  • value: list[float] | None

    The resolved values, each an int when whole, or None when unset.

#

NumberParameter

class
class NumberParameter(Parameter)

A number parameter.

  • default(value: float) -> Self

    The value when none is supplied.

  • array() -> NumberListParameter

    Make it a list instead: a comma-separated value.

  • value: float | None

    The resolved value, an int when it is whole, or None when unset.

#

Outcome

class
class Outcome

What another target in this run did, as Context.outcome_of tells.

  • status: str

    The record's status: succeeded, failed, skipped, waiting, …

  • error: str | None

    The failure's message, when it failed.

  • started_at: str | None

    When it started, ISO-8601, if it did.

  • ended_at: str | None

    When it settled, ISO-8601, if it has.

#

Parameter

class
class Parameter(Field)

What every parameter has, whatever its kind. Start one with parameter.

  • required() -> Self

    A value must be supplied.

  • secret() -> Self

    Mask the value and redact it from everything the run prints or records.

  • flag(name: str) -> Self

    The command-line flag, when it is not derived from the field name.

  • env(name: str) -> Self

    The environment variable, when it is not derived from the field name.

  • resolve(value: str | None) -> None

    Take the value the engine resolved, in CLI form, or None when unset.

  • manifest() -> dict[str, object]

    The parameter as the engine's manifest describes it.

#

parameter

function
def parameter(description: str='') -> StringParameter

A new string parameter; .number(), .boolean() or .array() recast it.

The description is what --help shows for it.

#

Plan

class
class Plan

The run's plan, as Context.plan reports it.

  • targets: list[str]

    The planned targets, in order.

  • dependencies: dict[str, list[str]]

    Each planned target's dependencies.

#

run

function
def run(build: type[Build]) -> None

Host build when the engine started this file; otherwise do nothing.

A build file ends with run(MyBuild). Started by the engine, the file becomes its worker. Imported, by a test say, the call is a no-op, even inside a command the engine is running for a body, whose environment still names the engine. Run by hand with python, it says how a build is run and exits.

#

Service

class
class Service(Target)

A target the engine starts before its dependants and stops after them.

Start one with service. Its phases get a ServiceContext, which can run commands but has no body-only call.

  • start(phase: Start) -> Self

    The start phase; it answers the handle the probe and the stop phase get.

  • ready(probe: Ready, timeout: Duration | None=None) -> Self

    The readiness probe, asked until it answers true or timeout passes.

  • stop(phase: Stop) -> Self

    The stop phase, run once every dependant has settled.

  • manifest() -> dict[str, object]

    The service as the engine's manifest describes it.

  • async start_(ctx: ServiceContext) -> str

    Answer service.start.

  • async ready_(ctx: ServiceContext, handle: str) -> bool

    Answer service.ready.

  • async stop_(ctx: ServiceContext, handle: str) -> None

    Answer service.stop; a service with no stop phase has nothing to do.

#

service

function
def service() -> Service

A new service, to configure fluently and assign to a build field.

#

ServiceContext

class
class ServiceContext

What a service phase is handed: the engine's services a phase may use.

  • target: str

    The target whose phase or body this is.

  • async call_(method: str, **params: object) -> object

    Ask the engine as this target; an engine-side cancel unwinds the caller.

  • async sh(*argv: str, cwd: str | None=None, env: Mapping[str, str] | None=None, stdin: str | None=None, check: bool=True) -> ExecResult

    Run argv through the engine, in the worker's directory and environment. cwd and env adjust those for this command; stdin is fed to it. Raises CommandError on a non-zero code unless check is off.

  • async secret(value: str) -> None

    Redact value from everything the run prints or records from now on.

  • async log(line: str) -> None

    Log a line attributed to this target.

#

StateHandle

class
class StateHandle

Durable state of one target, kept by the engine across runs and resumes.

  • async get() -> dict[str, object]

    The state as last written.

  • async set(patch: Mapping[str, object]) -> None

    Merge patch into the state.

  • async try_set(patch: Mapping[str, object]) -> bool

    Merge patch if the engine will record it now; whether it did.

#

StringListParameter

class
class StringListParameter(Parameter)

A list of strings: a comma-separated value on the command line.

  • value: list[str] | None

    The resolved values, or None when unset.

#

StringParameter

class
class StringParameter(Parameter)

A string parameter, the default kind.

  • default(value: str) -> Self

    The value when none is supplied.

  • options(*values: str) -> Self

    The only values accepted.

  • number() -> NumberParameter

    Make it a number parameter instead.

  • boolean() -> BooleanParameter

    Make it a boolean parameter instead: a flag that takes no value.

  • array() -> StringListParameter

    Make it a list instead: a comma-separated value.

  • value: str | None

    The resolved value, or None when unset.

#

Target

class
class Target(Field)

A unit of work the engine schedules. Start one with target.

  • body_: Body | None

    The body, or None for a target that only aggregates its dependencies.

  • description(text: str) -> Self

    The line --list shows for this target.

  • depends_on(*targets: Target) -> Self

    Targets that must succeed first; each is a sibling field declared above.

  • unlisted() -> Self

    Hide the target from --list and --help.

  • inputs(*paths: str) -> Self

    Paths whose contents key the cache.

  • outputs(*paths: str) -> Self

    Paths that must exist for a cache hit.

  • produces(*paths: str) -> Self

    Artifact paths this target produces.

  • retry(times: int, delay: Duration=0) -> Self

    Run the body up to times more times after it fails, delay apart.

  • timeout(limit: Duration) -> Self

    Fail an attempt that runs longer than limit.

  • before(*targets: Target | str) -> Self

    Run before these when both are planned; a string names a later field.

  • after(*targets: Target | str) -> Self

    Run after these when both are planned; a string names a later field.

  • triggers(*targets: Target | str) -> Self

    Pull these in and run them after this one; a string names a later field.

  • proceed_after_failure() -> Self

    Keep the build running after this target fails.

  • always() -> Self

    Run even after the build has failed.

  • dry_runnable() -> Self

    Run the body under --dry-run too.

  • requires(*parameters: Parameter) -> Self

    Parameters that must resolve before this target runs.

  • on_cancel(compensation: Target | str) -> Self

    The target to run when the run is cancelled after this one succeeded.

  • on_failure(disposition: Target | str) -> Self

    On failure: a compensation target, "fail" or "cancel-run".

  • executes(body: Body) -> Self

    The body, sync or async.

  • condition(check: Check) -> Self

    Run only when check answers true, asked just before the target's turn.

  • cache_key(key: CacheKey) -> Self

    An extra key the cache fingerprint includes, asked when fingerprinting.

  • lock(configure: Configure[LockSettings]) -> Self

    Hold a cross-run lock while this target runs; see LockSettings.

  • waits_for(configure: Configure[WaitSettings]) -> Self

    Suspend the run here until a trigger fires; see WaitSettings.

  • validate_during(configure: Configure[ValidateDuringSettings]) -> Self

    Run checks on an interval while the body runs; see ValidateDuringSettings.

  • references() -> list[tuple[str, Target | str]]

    Every target this one names, and the setter that named it, for the build.

  • parameters() -> list[Parameter]

    The parameters this target requires, for the build to check.

  • manifest() -> dict[str, object]

    The target as the engine's manifest describes it.

  • async run_body(ctx: Context) -> None

    Run the body, if any, awaiting it when it is async.

  • async condition_() -> bool

    Answer target.condition.

  • async cache_key_() -> str

    Answer target.cacheKey.

  • settings_() -> dict[str, object]

    Answer target.settings: the declared sections, evaluated now.

  • async wait_check_() -> bool

    Answer wait.check: the resume_when predicate.

  • async validate_(check: str) -> None

    Answer target.validate: run the named check, which raises to fail.

#

target

function
def target() -> Target

A new target, to configure fluently and assign to a build field.

#

ValidateDuringSettings

class
class ValidateDuringSettings

Checks run on an interval while the body runs, from .validate_during.

  • every(interval: Duration) -> Self

    The interval between rounds of checks.

  • check(name: str, validation: Validation) -> Self

    A named check; it raises to report a problem.

  • checks: dict[str, Validation]

    The checks by name, in the order declared.

  • manifest() -> dict[str, object]

    The validateDuring section of target.settings.

#

WaitSettings

class
class WaitSettings

A wait gate, as .waits_for(lambda s: ...) configures it.

  • external_signal(name: str) -> Self

    Wait for zuke resume <run> --signal <name>.

  • resume_when(check: Check, every: Duration | None=None) -> Self

    Wait until check answers true, asked on every interval.

  • timeout(limit: Duration) -> Self

    How long to wait before the timeout disposition applies.

  • on_timeout(disposition: Field | str) -> Self

    On timeout: a compensation target, "fail" or "cancel-run".

  • check: Check | None

    The resume_when predicate, when that is the trigger.

  • manifest() -> dict[str, object]

    The waitsFor section of target.settings.