---
title: "Build and deploy a workflow project"
description: "Initialize a Python workflow project, publish a workflow release, and deploy it to a development cluster."
image: "https://tilebox.com/images/tilebox-docs-social-preview.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://tilebox.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Build and deploy a workflow project

import { CardGrid } from "@docs/components/ui/card-grid";
import { LinkCard } from "@docs/components/ui/link-card";

Use workflow releases when the code under test should match the code that runners execute. A release packages a Python workflow project, records the discovered task identifiers, and lets release runners load the deployed code from a cluster.

This guide summarizes the build and deploy path. For the underlying model, see [Workflow releases](/docs/workflows/concepts/workflow-releases) and [Release lifecycle](/docs/workflows/build-and-deploy/releases).

## Prerequisites

- You have installed the [CLI](/docs/cli).
- `TILEBOX_API_KEY` is set in the shell where you run commands.
- `uv` is installed and available on `PATH`.

## Initialize the project

Create a project directory and initialize it as a Tilebox workflow project.

```bash
mkdir my-workflow
cd my-workflow
tilebox workflow init --name "My Workflow"
```

The init command creates the Tilebox workflow, writes `tilebox.workflow.toml`, creates a minimal Python project with `runner.py`, adds the `tilebox` dependency, and runs `uv sync`. It aborts if `tilebox.workflow.toml`, `pyproject.toml`, `runner.py`, or `uv.lock` already exists in the current directory.

<span />
<span />
<span />

- my-workflow/
  - pyproject.toml
  - uv.lock
  - tilebox.workflow.toml
  - runner.py

## Configure a deployment target

Create a logical cluster to deploy the workflow release to, enabling [release runners](/docs/workflows/concepts/runners#release-runners).

```bash
tilebox cluster create "workflow-dev"
```

```text title="Output"
Slug               workflow-dev-<...>
Name               workflow-dev
Deletable          true
```

Add the returned cluster slug to `tilebox.workflow.toml` so deployment commands can refer to a logical environment instead of repeating cluster slugs.

```toml title="tilebox.workflow.toml"
[workflow]
slug = "my-workflow-<...>"
root = "."
runner = "runner:runner"

[build]
include = [
  "tilebox.workflow.toml",
  "pyproject.toml",
  "uv.lock",
  "runner.py",
]

[targets.dev]
clusters = ["workflow-dev-<...>"]
```

## Build and publish the release

Create a new release of the workflow and publish it to Tilebox.

```bash
tilebox workflow publish-release
```

Publishing creates an immutable release. It does not change what any cluster runs until you deploy it.

:::tip
Build locally first when you want detailed validation output.

`tilebox workflow build-release --debug`
:::

## Deploy to a development cluster

Deploy the release to the development target.

```bash
tilebox workflow deploy-release --latest --target dev
```

Start a release runner in an environment you control.

```bash
tilebox runner start --cluster workflow-dev-9xK2mQ4pL8nR7s --debug
```

## Run and inspect a job

Submit a task that matches one of the identifiers discovered from the release.

```bash
tilebox job submit \
  --name my-workflow-test \
  --task my-workflow/HelloWorld \
  --version v0.1 \
  --cluster workflow-dev-9xK2mQ4pL8nR7s \
  --input '{"name":"Tilebox"}' \
  --wait
```

```text
Job submitted: 019ef7a2-56b4-7a86-9c4d-52a1792b1e90
```

Inspect the result before making the next change.

```bash
tilebox job logs <JOB_ID>
tilebox job spans <JOB_ID>
```

## Next steps

    Learn the details of Python workflow project layout.

    Choose where release runners run and how clusters map to environments.

Source: https://tilebox.com/docs/guides/workflows/build-and-deploy-workflow/index.mdx
