# Manage Dives as code
> Use MotherDuck Blueprints to version Dives, preview changes with their data dependencies, and deploy through GitHub Actions.
When a team depends on a Dive, changes to it need the same review as application code: a diff, a preview before it goes live, and a record of what was deployed. [MotherDuck Blueprints](https://github.com/motherduckdb/motherduck-blueprints) is an open-source, Apache 2.0-licensed deployment tool maintained by MotherDuck that gives Dives, Flights, and Guides that workflow in a GitHub repository.

Each resource lives in a directory with its source code and a `blueprint.yml` file that describes what to deploy. Blueprints calls each of these directories a package. GitHub Actions workflows then deploy the packages:

- Opening a pull request deploys a preview copy of the changed packages under branch-scoped names and posts a preview link as a pull request comment.
- Merging to `main` updates production, or staging if you add a staging target.
- Closing the pull request removes the preview resources.

A package can also declare the data it depends on. If a Flight publishes a share and a Dive reads it, the pull request preview runs the Dive against a preview of that data instead of production.

This guide starts with the template's Wikipedia pipeline and dashboard. If you already have Dives in MotherDuck, [adopt your existing resources](#adopt-existing-dives) before enabling deployment.

## Prerequisites

- A [MotherDuck service account](/key-tasks/service-accounts-guide/create-and-configure-service-accounts/) with a read-write token and permission to create the example resources
- Permission to create a GitHub repository and configure GitHub Environments and secrets
- A GitHub plan that supports Environments for your repository

The default template uses the same service account for preview and production. Branch-scoped resource names do not separate credentials. If pull requests must not use production credentials, follow the [staging setup](https://github.com/motherduckdb/motherduck-blueprints/blob/main/docs/setup-your-repository.md#add-staging-optional) before deploying.

## Create your deployment repository

The [Blueprints template](https://github.com/motherduckdb/blueprints-template) is a GitHub template repository. Creating a repository from it copies the template's files into a new repository that you own, with its own commit history. Don't fork it: a fork of a public repository stays public and linked to the original.

The new repository contains:

- An example Flight that loads public Wikipedia pageviews and a Dive that reads the resulting share
- `motherduck.yml`, which lists the deployment targets
- GitHub Actions workflows for deployment, preview cleanup, and a weekly tooling check. Each workflow is a short file that calls a workflow in the Blueprints repository, pinned to a release tag.
- A `Makefile` for local validation, export, and upgrades
- An `AGENTS.md` file that describes the repository conventions for coding agents

The workflows can't deploy anything until you add a MotherDuck token. To create the repository:

1. Open the [Blueprints template](https://github.com/motherduckdb/blueprints-template), select **Use this template → Create a new repository**, and choose **Private**.
2. In your repository, open **Settings → Environments** and create `motherduck-production`.
3. Add the service-account token as an environment secret named `MOTHERDUCK_TOKEN`.

The example packages use this layout:

```text
motherduck.yml
flights/
  wikipedia-pageviews-ingest/
    blueprint.yml
    src/flight.py
dives/
  wikipedia-pageviews/
    blueprint.yml
    src/dive.tsx
```

`motherduck.yml` defines deployment targets. Each `blueprint.yml` declares a package's resources, inputs, and outputs. Keep source code beside its manifest. See the [manifest reference](https://github.com/motherduckdb/motherduck-blueprints/blob/main/docs/blueprint-yml-reference.md) for supported fields.

## Preview a change

1. Edit the `description` in `flights/wikipedia-pageviews-ingest/blueprint.yml`.
2. Commit the change to a feature branch and open a pull request against `main`.
3. Wait for **Deploy Blueprints** to finish. Approve the deployment in GitHub Actions if the environment requires it.
4. Read the plan in the pull request comment and open its Dive preview link. Check that the dashboard displays Wikipedia pageview data.

Start with the Flight package so the first production deployment creates the data before the dashboard. An empty commit or a top-level README change does not trigger this deployment. Pull requests from forks validate without deploying.

## Deploy and check production

Merge the reviewed pull request into `main`. In the default setup, the workflow deploys the changed packages to production and reports its plan in the Actions job summary. Check that the deployment succeeds and the production Dive displays the expected data.

Blueprints checks resource identity and dependencies before writing and verifies the deployment afterward. You still need to review the dashboard's queries and results. Closing the pull request triggers preview cleanup. Keep **Cleanup Preview Blueprints** enabled and check that it succeeds.

Removing package files from Git does not delete their deployed production resources. Plan production retirement separately.

If you add the conventional staging target, merges deploy to staging instead. A published, non-prerelease GitHub Release deploys its tagged code to production. See [staging and promotion](https://github.com/motherduckdb/motherduck-blueprints/blob/main/docs/setup-your-repository.md#add-staging-optional).

## Edit and validate locally

With Python 3.10+ and Git installed, clone your repository and validate its configuration:

```bash
> make validate
```

For dashboard development, also install Node.js 22+:

```bash
> make setup
> make preview-smoke wikipedia-pageviews
```

These checks do not need a MotherDuck token. The preview smoke command builds the dashboard without opening a live preview. For interactive development against deployed data, follow the [local preview setup](https://github.com/motherduckdb/motherduck-blueprints/blob/main/docs/setup-your-repository.md#work-locally-optional).

To create a package containing a pipeline and dashboard, run `make new-project revenue` and edit the files in `projects/revenue/`. Use separate `flights/`, `dives/`, and `guides/` packages when they need independent deployment cycles. Run `make validate` before opening a pull request.

## Adopt existing Dives

In a template-based repository, install the supported MotherDuck CLI and sign in as the account that owns your resources:

```bash
> make install-deploy
> motherduck login
> motherduck status
> make export
> make validate
```

`make export` writes visible Flights, Dives, and Guides as disabled packages bound to their existing UUIDs. It makes no remote changes. Review the exported source for credentials before committing, and remove unwanted starter packages before opening a deployment pull request.

Follow the [adoption guide](https://github.com/motherduckdb/motherduck-blueprints/blob/main/docs/adopt-existing-resources.md) to check ownership, schedules, and dependencies before enabling any package. Export does not transfer ownership, data, secret values, or grants. Existing production references do not automatically become isolated preview dependencies.

For individual assets, the [MotherDuck CLI](/getting-started/interfaces/motherduck-cli/agents/#choosing-between-the-cli-and-mcp) can pull, push, and list Dives from your terminal without passing source through an agent's context. Use Blueprints export when you need disabled packages with ownership and deployment settings for adoption.

If you use the [Dives-only starter](https://github.com/motherduckdb/blessed-dives-example), its scripts and cleanup triggers differ from Blueprints. Use the adoption guide when moving its deployed Dives into Blueprints.

## Choose what Terraform manages

Terraform and Blueprints manage objects that change at different rates. Infrastructure such as service accounts, tokens, compute settings, and shared databases is set up once and changes rarely. Dives, Flights, and Guides change with every feature or fix.

Use the [MotherDuck Terraform provider](/integrations/dev-tools/terraform/) for the long-lived infrastructure, and Blueprints for Flight Python, Dive source, and Guide content. Each tool then gets its own review and deployment cycle, and a dashboard change doesn't need an infrastructure plan.

Assign each object to one deployment tool. The Wikipedia starter creates its own database and share, so don't also declare those objects in Terraform. For a combined workflow, follow [Terraform with Blueprints](https://github.com/motherduckdb/terraform-provider-motherduck/blob/main/docs/guides/blueprints-deployment.md).

## Frequently asked questions

### Can I put an existing MotherDuck Dive under version control?

Yes. Use `make export` in a Blueprints repository to create disabled packages bound to your existing resource IDs. Export makes no remote changes. Follow [adopt existing Dives](#adopt-existing-dives) to check ownership and data dependencies before enabling deployment.

### Are Dive previews isolated from production?

The default template gives previews branch-scoped resource names, but uses the same service account for previews and production. For a separate credential boundary, [configure staging](https://github.com/motherduckdb/motherduck-blueprints/blob/main/docs/setup-your-repository.md#add-staging-optional). Review imported packages separately because their production data references do not automatically point to preview resources.

### Do I need Terraform to deploy Dives?

No. You can start from the Blueprints template with a MotherDuck service-account token and a GitHub repository. Add [Terraform](/integrations/dev-tools/terraform/) when you want to manage identities, compute settings, or shared infrastructure as code. Assign each object to one tool so their deployments don't conflict.

## Related content

- [Build Flights and a Dive with an AI agent](/key-tasks/flights/build-flights-and-a-dive-with-an-ai-agent/)
- [MotherDuck CLI: work with agents](/getting-started/interfaces/motherduck-cli/agents/)
- [Environment management](/key-tasks/data-warehousing/environment-management/)
- [Blueprints setup and troubleshooting](https://github.com/motherduckdb/motherduck-blueprints/blob/main/docs/setup-your-repository.md)
- [Blueprints GitHub Action reference](https://github.com/motherduckdb/motherduck-blueprints/blob/main/docs/github-action.md)


---

## Docs feedback

MotherDuck accepts optional user-submitted feedback about this page at `GET https://motherduck.com/docs/api/feedback/agent`.
For agents and automated tools, feedback submission should be user-confirmed before sending.

URL-encode query parameter values and send a GET request:

```text
GET https://motherduck.com/docs/api/feedback/agent?page_path=%2Fkey-tasks%2Fdives%2Fmanaging-dives-as-code%2F&page_title=Manage%20Dives%20as%20code&text=<url-encoded user feedback, max 2000 characters>
```

Optionally append `&source=<url-encoded interface identifier>` such as `claude.ai` or `chatgpt`.

`page_path` and `text` are required; `page_title` and `source` are optional. Responses: `200 {"feedback_id": "<uuid>"}`, `400` for malformed query parameters, and `429` when rate-limited.
