Deploy a workflow
In this guide you will use the scripts/deploy.py CLI shipped with the workflow template to bundle one (or every) workflow in your repo and register it with the UniteLabs platform.
Prerequisites
- A repo cloned (or scaffolded) from the workflow template. Each top-level
w*-*/directory is a standalone workflow package with its ownpyproject.tomldeclaring[project].name,[project].version, and[tool.unitelabs.workflow]metadata. uv(latest) and Python 3.12+.- UniteLabs API credentials:
BASE_URL,AUTH_URL,CLIENT_ID,CLIENT_SECRET.
Store your credentials
Copy .env.example to .env at the repo root and fill in the four values:
BASE_URL=https://api.<your-tenant>.unitelabs.io/
AUTH_URL=https://auth.<your-tenant>.unitelabs.io/realms/<tenant-id>/protocol/openid-connect/
CLIENT_ID=<your-client-id>
CLIENT_SECRET=<your-client-secret>
scripts/deploy.py loads .env automatically when run locally. CI/CD pipelines set the same four variables as platform secrets — see CI/CD for workflows.
.env is in the template's .gitignore. Never commit credentials.What the deploy script does
scripts/deploy.py is a PEP-723 single-file CLI — its own dependencies (requests, python-dotenv) are declared inline so uv run scripts/deploy.py … resolves them into an ephemeral env. There is no project-level pyproject.toml at the repo root.
For each workflow you deploy it:
- Discovers the workflow by globbing
w*-*/pyproject.tomland matching[project].name(the slug). - Builds a bundle as a zip with the workflow directory verbatim plus the
shared/library flat-vendored at the bundle root, soimport shared.steps.Xresolves on the platform withoutsys.pathtricks. - Stitches install-time dependencies from the workflow's
[project].dependencies+shared's[project].dependencies(deduped, workflow wins, the localsharedentry dropped) and sends the merged list to the platform'sdependenciesfield. The platform installs the runtime venv from this list. - Authenticates with OAuth2 client credentials.
- Looks up the workflow by its
display_name(paginated, client-side match). If found, PATCHes it; otherwise POSTs a new record. The lookup refuses to deploy on duplicate display names, so you can never silently overwrite the wrong record. - Patches metadata — description, tags,
enabled: true— so a "soft-deleted" record (the UI delete only flipsenabled=false) is resurrected on redeploy rather than living on as a hidden duplicate.
Commands
All five forms are mutually exclusive; pick whichever fits your need.
Deploy a single workflow
uv run scripts/deploy.py w03-liquid-handling
The positional argument is the workflow's slug — [project].name in its pyproject.toml.
Deploy every workflow
uv run scripts/deploy.py --all
Deploy only what changed
uv run scripts/deploy.py --changed-from origin/main
Runs git diff --name-only <ref>..HEAD and deploys only the workflows whose directory was touched. Use it locally to preview what a merge would redeploy, or in CI on push-to-main (see CI/CD for workflows).
shared/ or to scripts/deploy.py itself marks every workflow as affected — shared/ is vendored into every bundle and scripts/deploy.py rewrites every bundle's contents. The rule lives in the Python helper affected_workflows() so it's testable and single-source.Deploy a tagged release
uv run scripts/deploy.py --git-tag w03-liquid-handling/v1.2.0
Parses the tag (<slug>/v<X.Y.Z>), verifies the workflow's [project].version matches 1.2.0, and adds v1.2.0 to the platform tags. Refuses to deploy if pyproject and tag disagree — the pyproject is the source of truth.
Print without deploying
uv run scripts/deploy.py --list
uv run scripts/deploy.py --list --changed-from origin/main
Prints the selected slugs (one per line) and exits before loading .env or authenticating. CI pipelines (or you, locally) can use this to sanity-check the selection without needing credentials.
Channels: DEV / STG / PRD
uv run scripts/deploy.py w03-liquid-handling --channel dev
uv run scripts/deploy.py --all --channel stg
uv run scripts/deploy.py --git-tag w03-liquid-handling/v1.2.0 --channel prd
--channel layers on top of any of the forms above. It prepends [DEV] /[STG] /[PRD] to the platform display_name and adds the channel name as a platform tag. The result: a single tenant can host parallel DEV, STG, and PRD records of the same workflow as distinct platform entries — bench testing on DEV doesn't risk the production record.
The channel-to-trigger mapping is established by CI; locally you'll usually omit --channel (deploys land as untagged "main" records) or pass --channel dev when iterating against a shared DEV tenant. The full mapping is in CI/CD for workflows.
Extra platform tags
uv run scripts/deploy.py w03-liquid-handling --tag prod --tag stable
--tag/-t is repeatable and stacks with --git-tag's version label and --channel's channel tag. Use it for ad-hoc labels (a feature flag, a customer name) without bumping the workflow's version.
Release a workflow
Each workflow ships independently. To release w03-liquid-handling v1.2.0:
- Bump the version. Edit
w03-liquid-handling/pyproject.tomland set[project].version = "1.2.0". - Commit:
git add w03-liquid-handling/pyproject.toml git commit -m "release: w03-liquid-handling v1.2.0" - Tag and push:
git tag w03-liquid-handling/v1.2.0 git push origin main --tags
The tag push triggers deploy-prd in CI — see CI/CD for workflows. You can also run the release locally:
uv run scripts/deploy.py --git-tag w03-liquid-handling/v1.2.0 --channel prd
<slug>/v<X.Y.Z> is mandatory — bare v1.2.0 tags won't match the deploy regex, intentionally. A repo with several workflows needs per-workflow tags so bumping one doesn't pretend every other workflow changed.Verify
Open the UniteLabs Workflows page and confirm the workflow appears with the expected [CHANNEL] prefix, version, and tags.
The script's stdout shows what landed on the platform — display name, resolved entrypoint, bundle size, dep count, and whether the record was created or updated.
Next steps
- Set up CI/CD — wire
scripts/deploy.pyinto GitHub Actions or GitLab CI with the three-channel (dev/stg/prd) model. - Trigger a workflow run — confirm the deployment end-to-end.
AGENTS.md— authoring rules for adding new workflows to the template.