pub struct Pipeline {Show 16 fields
pub name: String,
pub label: String,
pub steps: Vec<QedStep>,
pub params: HashMap<String, ParamDef>,
pub on_success: Vec<Outcome>,
pub on_fail: Vec<Outcome>,
pub triggers: Vec<Trigger>,
pub concurrency_key: Option<String>,
pub placement: Placement,
pub workspace: WorkspaceMode,
pub wraps: Option<String>,
pub matrix: Option<MatrixSpec>,
pub toolchain: Option<ToolchainSpec>,
pub binds: Vec<BindSpec>,
pub on_change: Vec<OnChangeHook>,
pub finally: Vec<QedStep>,
}Fields§
§name: String§label: String§steps: Vec<QedStep>§params: HashMap<String, ParamDef>§on_success: Vec<Outcome>§on_fail: Vec<Outcome>§triggers: Vec<Trigger>Triggers that can start this pipeline. Defaults to [Manual] when omitted.
concurrency_key: Option<String>Lock key that serializes concurrent runs. When two runs share a key,
the second one is Queued until the first finishes. None defaults
to the pipeline’s own name (= one-at-a-time per pipeline). Two
pipelines that fight for the same resource (e.g. cargo’s shared
target/) can pin to the same key to serialize across pipelines.
The sentinel "@parallel" opts out — runs of that pipeline never
block each other (use for read-only fan-outs).
placement: PlacementWhere this recipe is allowed to run (W170). Defaults to
Placement::Anywhere. The runner enforces this at kick time
(R435-F2) — the recipe body itself remains environment-agnostic.
workspace: WorkspaceModeHow the runner positions the on-disk tree this pipeline builds against
(W224). Defaults to WorkspaceMode::Checkout (switch to the run’s
ref, bail if dirty). Releases set workspace = "isolated" so a tag is
always cut from a clean worktree, never a dev’s live edits; local-only
pipelines may set workspace = "live" to build the tree as-is.
wraps: Option<String>Optional GHA-workflow this pipeline wraps. Set to "gha:<rel-path>"
in TOML (e.g. wraps = "gha:.github/workflows/release.yml") when the
pipeline exists because it composes a workflow; the daemon then
suppresses that workflow’s auto-ingest so the catalog doesn’t show
both entries. Purely advisory — not interpreted by the runner.
matrix: Option<MatrixSpec>Native matrix expansion (R505). When present, crate::matrix::plan
expands the pipeline into one concrete job per matrix row, with
${{ matrix.<key> }} substituted across each step’s argv / env /
cwd. Absent or empty → single-job plan (no expansion). Mirrors GHA’s
strategy.matrix semantics (cartesian product + include/exclude).
toolchain: Option<ToolchainSpec>Declarative toolchain pinning (R507, W208 pillar 3). [pipeline.toolchain]
pins tool versions (rust/xcode/ndk/msvc/…) checked against the host at
plan time, so a release fails fast with an actionable error instead of
dying mid-build on a missing SDK. Per-step toolchain.<tool> overrides
(see QedStep::toolchain) layer on top. Absent (the default) ⇒ no
pins, no check. See crate::toolchain.
binds: Vec<BindSpec>W209: [[bind]] tables — pipeline-output → in-tree-manifest write-backs.
Each bind names a target file/path, a producer step output (or URI
escape hatch), and an intent predicate. The runner evaluates them
mid-pipeline as each producing step completes; failed steps simply
skip the binds that reference them. Defaults to empty for pipelines
that don’t bind anything.
on_change: Vec<OnChangeHook>W209/R510-F6: [[on_change]] hash-change hooks. Each names a bind
selector (matched against a changed manifest_bind::AppliedBind’s
path) and an action (fire a pipeline, emit an event, or append to a
journal). The runner evaluates them after each step’s binds commit,
firing only for binds that actually changed bytes on disk. Empty for
pipelines without hooks.
finally: Vec<QedStep>W207 Gap #6 (R513-F4): always-run teardown steps. Every step here runs
unconditionally after the main step loop and the background-sidecar reap
— whether the pipeline passed or failed — making it the home for
diagnostics/artifact teardown that must happen either way (upload
Playwright traces, docker compose down, collect logs). Sidecar teardown
itself is already structural (the F2 background reap), so finally is for
the once-after-loop work the reap doesn’t cover.
Semantics (see crate::runner): all finally steps are attempted
best-effort — a failing one never aborts the rest (teardown should always
run to completion). A finally step that fails marks the run Failed
(visible in the run tile + RunFinished) unless it sets
on_fail = "continue", but it does not change which terminal
outcomes fire — on_success vs on_fail is selected from the
pipeline’s work result (steps + sidecars), not from teardown. v1
restricts finally steps to StepKind::Subprocess (the teardown
shape); composite/background kinds in finally are rejected at load
time.
Implementations§
Source§impl Pipeline
impl Pipeline
Sourcepub fn effective_concurrency_key(&self) -> &str
pub fn effective_concurrency_key(&self) -> &str
The effective concurrency key for this pipeline — concurrency_key
if set, otherwise the pipeline name. The daemon’s per-key mutex map
is keyed off this value.
Sourcepub fn is_parallel(&self) -> bool
pub fn is_parallel(&self) -> bool
true when the pipeline opts out of serialization via the sentinel
key "@parallel".
Source§impl Pipeline
impl Pipeline
Sourcepub fn apply_params(&mut self, params: &HashMap<String, String>)
pub fn apply_params(&mut self, params: &HashMap<String, String>)
Substitute {{key}} placeholders in every step’s argv and env
values with the supplied params (e.g. provider=groq turns
"{{provider}}" into "groq"). Unknown placeholders are left
untouched. Required-param validation is the caller’s job — this
only performs the textual substitution.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Pipeline
impl<'de> Deserialize<'de> for Pipeline
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for Pipeline
impl RefUnwindSafe for Pipeline
impl Send for Pipeline
impl Sync for Pipeline
impl Unpin for Pipeline
impl UnsafeUnpin for Pipeline
impl UnwindSafe for Pipeline
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<T> Fruit for T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more