Skip to content

Publishing Pipeline

The publishing workflow in pipeline.py runs four sequential phases:

collect → validate → extract → integrate

Phases

Phase Role
collect Gather scene data into named slots on PipelineContext
validate Check collected data meets requirements; abort on failure
extract Process/render/export the data to disk
integrate Copy outputs into the versioned publish tree

Actions

Each phase is a list of @dataclass action instances (CollectAction, ValidateAction, ExtractAction, IntegrateAction). Actions communicate through named slots on PipelineContext.

Pipeline context

Publish and load pipelines share the same PipelineContext class — there are no separate publish/load contexts. Besides the slot dict it carries entity, task, product_type, dcc, and settings, plus three fields for layered products and loads:

Field Set by Meaning
layer Publish UI layer selector / Session.load_product() Layer name to publish under or load; empty = main layer
version Session.load_product() Version to load; -1 (VERSION_LATEST) = most recent
ref_id Session.load_product() Reference id the loaded scene objects are tagged with

The publish UIs (Blender N-panel and standalone publisher) show a layer selector for every pipeline unless its config sets layers = false. Existing layer names are suggested via Entity.get_product_layers(product_type); typing a new name creates a new layer.

Action discovery

Actions are discovered at runtime via load_custom_actions(). Later entries override earlier ones:

  1. kpipe/actions/ (in packages/core) — built-in actions (loaded on import kpipe)
  2. kpipe_<dcc>/…/actions/ (in packages/<dcc>) — DCC-specific actions (loaded by the extension's register())
  3. {KPIPE_ROOT}/actions/ — project-level custom actions (loaded lazily on first PublishPipeline.from_config())

Configuring a pipeline

Pipelines are defined per product-type and DCC in configs/<bundle>/kpipe-publish.toml:

[pipeline.render_blender_cycles]
dcc = "blender"
product_type = "render_exr"

  [pipeline.render_blender_cycles.settings]
  use_selected = false

  [[pipeline.render_blender_cycles.collect]]
  action = "CollectBlenderCollection"
  slot = "beauty"
  collection_name = "Render_Beauty"

  [[pipeline.render_blender_cycles.integrate]]
  action = "IntegrateImageSequence"
  slot = "beauty"