Example 07 — Release Management¶
File: files/examples/release-management.toml Industry: Open Source / SaaS DevOps Tags: release, publish, registry
Features Demonstrated¶
matrixexpansion across five package registries (npm, pypi, dockerhub, ghcr, homebrew)registerfor the release version stringworking_dirper taskretrieson publish tasks (registry rate limits)ignore_failureon announcement tasks- Runtime
--varfor release channel envfor registry credentialstimeoutper publish task
Why this pattern matters¶
Publishing a release to five registries sequentially takes five times as long as it needs to and fails the entire release if any one registry is temporarily rate-limited. Publishing them in parallel requires coordinating five processes that may succeed or fail independently — exactly what matrix expansion is for.
Each publish[registry=X] node is independent in the DAG. If npm publish fails due to a transient rate limit, the retries handle it without blocking PyPI or DockerHub. ignore_failure on announcement tasks means a failed Slack notification does not prevent the release from being recorded as complete. The release version is captured once at the top of the pipeline and flows downstream via {{.release_version}} — there is no risk of different tasks using different version strings from a file that may change between reads.
Pipeline Structure¶
[prepare-release] → version
└── [publish[registry=npm]] ─┐
[publish[registry=pypi]] │
[publish[registry=dockerhub]]├→ [announce-release]
[publish[registry=ghcr]] │ (ignore_failure)
[publish[registry=homebrew]] ┘
Run Commands¶
# Stable channel release
wf run release-management --var RELEASE_CHANNEL=stable --parallel --print-output
# Beta release
wf run release-management \
--var RELEASE_CHANNEL=beta \
--work-stealing \
--print-output \
--timeout 30m
# Visualise matrix
wf graph release-management --matrix
What to Observe¶
wf graph release-management --matrixshows five expandedpublishnodes- All five publish nodes run in parallel — verify with
wf audit wf inspectshowsrelease_version— the version captured fromprepare-releaseannounce-releaseuses{{.release_version}}— confirm in logsretries = 3on publish tasks —wf auditshows retry events if registries are slowignore_failure = trueonannounce-release— Slack/tweet failures don't abort the run