Skip to main content

Collaboration and deployment stages

This page describes how to set up collaboration and deployment in Windmill as a progression of four stages, from simplest to most advanced. Each stage is additive: it builds on the previous one and adds one capability. Most teams settle at stage 2 or stage 3 — stage 4 is only needed when you need a separate production environment with a promotion workflow.

StageWhat you addGit requiredForksWorkspaces
Stage 1Shared workspace, u/f/NoNo1
Stage 2Forks, merge UI, protection rulesetsNoYes1
Stage 3Bi-directional git sync, local developmentYesYes1
Stage 4Multi-workspace (dev/staging/prod)YesYes2+
Edition requirements

Stage 1 — Shared workspace

Everyone on the team works in the same workspace. Developers iterate in their own user space (u/<user>/) and, once an item is ready to be shared, move it to a shared folder (f/<folder>/). This is the simplest possible setup and the right starting point for almost every team.

Architecture

  • One workspace (for example main)
  • Developers own u/<username>/ and iterate there
  • Shared items live under f/<folder>/, with folder-level permissions granting write access to the relevant group
  • No git, no forks, no protection rulesets

Setup

  1. Create a workspace and invite your team.
  2. Create one or more folders that represent your projects, and assign write permission to the groups that should own each project.
  3. That's it — developers can start building.

Developer workflow

  1. A developer creates a script, flow or app under u/<their-name>/. Items in user space are private to them by default.
  2. They iterate freely, test, and share drafts with teammates via the draft system.
  3. When the item is ready, they move it from u/<user>/ to the appropriate f/<folder>/. Moving an item into a folder transfers ownership to that folder's permissions.
  4. Other members of the folder's group can now edit, run, and depend on the item.

When to move to stage 2

  • Someone broke an item in the shared workspace and you wish it had been isolated.
  • You want a review gate before changes reach the shared workspace.
  • Developers want sandboxes to test risky changes without affecting anyone else.

Stage 2 — Add forks and the merge UI

Stop editing the shared workspace directly. Instead, developers create a workspace fork for each change, iterate in the fork, and merge back via the merge UI. Protection rulesets enforce this: direct deploys to the shared workspace are blocked except for a small wm_deployer group.

This is still a pure UI workflow — no git, no CI/CD, no external tools. Stage 3 will add git sync on top, and forks integrate seamlessly with it when you get there.

Forks are optional

Forks are not a prerequisite for stage 3. Git sync works on a plain shared workspace, so if you already want git history and local development, you can skip this stage and go straight to stage 3. Adopt forks later if you need isolated sandboxes and a review gate.

Architecture

  • One shared workspace (same as stage 1), now called prod or main
  • Protection rulesets block direct deploys; a wm_deployer group has bypass permissions
  • Developers create workspace forks to develop features
  • Changes merge back through the merge UI

UI only forks

Setup

1. Create the wm_deployer group

  1. Open the workspace settings and go to Groups.
  2. Create a group called wm_deployer and add the users who are allowed to deploy directly or approve merges.

2. Enable protection rulesets

  1. Go to Workspace settingsProtection Rulesets.
  2. Add a rule that enables Disable direct deployment.
  3. Add the wm_deployer group to the bypass list.

This blocks everyone except the deployer group from modifying f/ items directly. Developers must now use forks.

Developer workflow

  1. A developer creates a workspace fork from the shared workspace via the workspace menu.
  2. They iterate, test, and deploy freely inside the fork — triggers are not copied over to avoid unwanted executions.
  3. When ready, they open the fork home page, click Review & Deploy Changes, and review the diff in the merge UI.
  4. A member of wm_deployer approves the merge. The changes land in the shared workspace.

When to move to stage 3

  • You want a history of changes outside Windmill (audit, backup, rollback).
  • You want to edit scripts and flows locally in your IDE or with agentic coding tools like Claude Code.
  • You want fork branches mirrored in git so PRs can be reviewed there too.
  • You're planning to add a separate production environment (stage 4), which requires git sync.

Stage 3 — Add git sync

Connect the workspace from stages 1 and 2 to a git repository using git sync. Every deploy is committed to git, and changes pushed to the repository are synced back to Windmill via CI/CD. This gives you a full audit trail, external version control, and local development — and each fork from stage 2 now automatically gets its own git branch, so the merge UI and git PRs stay in lockstep.

Git sync is available on Cloud and Enterprise Self-Hosted, and on Community Edition for workspaces with up to 2 users.

Architecture

  • The shared workspace and its forks from stage 2, unchanged
  • A git repository with a single branch (for example main)
  • Git sync configured on the workspace: each deploy pushes a commit
  • A CI/CD workflow that syncs commits back to the workspace, enabling bi-directional sync
  • A wmill.yaml file in the repository with a single entry in the workspaces: key
  • Fork branches auto-created as wm-fork/<parent-branch>/<fork-name>

Workspace Forks + git sync

Setup

1. Create the git repository

Create an empty repository on GitHub, GitLab or similar with a single main branch.

2. Configure git sync on the workspace

  1. Go to Workspace settingsGit Sync.
  2. Click + Add connection and create a git_repository resource pointing at your repository and the main branch.
  3. Save. Use Initialize Git repository to populate the repository with the current workspace contents and a default wmill.yaml.

See the full walkthrough in git sync setup.

3. Add the CI/CD workflows

Git sync only pushes from Windmill to git by default. To make changes in git flow back into the workspace, add GitHub Actions workflows (or equivalent). A working reference is the windmill-sync-example repository. You will want:

Without the fork workflows, forks still work exactly as in stage 2 — their git branches just won't receive external edits.

You will need:

  • A Windmill user token saved as a WMILL_TOKEN GitHub secret.
  • The WMILL_WORKSPACE and WMILL_URL variables set in the workflows.

Full details in git sync CI/CD setup.

4. Minimal wmill.yaml

A single-workspace wmill.yaml looks like this:

defaultTs: bun
includes:
- f/**
excludes: []
skipVariables: true
skipResources: true
skipSecrets: true

workspaces:
main:
baseUrl: https://app.windmill.dev
gitBranch: main

See workspace-specific items for the full schema.

Developer workflow

  1. Developers continue to use forks from stage 2. When they create a fork, a matching wm-fork/main/<name> git branch is created automatically.
  2. They can now also edit the fork locally: work on the workspace outside of Windmill with wmill sync pull, edit in their IDE, the VS Code extension, or an agentic coding tool like Claude Code, then wmill sync push back.
  3. Every deploy creates a commit in the git repository.
  4. Merging a fork via the merge UI or via a normal git PR both work — pick whichever your team prefers for review.
  5. External commits (from local development or PR merges) are replayed into the workspace by the CI/CD workflow.

When to move to stage 4

  • You need a separate production environment that is fully isolated from day-to-day development.
  • You want PR-based review on the promotion step, not just the merge-to-shared step.
  • You're deploying across multiple Windmill instances.

Stage 4 — Add multi-workspace promotion

Introduce one or more additional workspaces (for example staging and prod), each connected to its own git branch. Day-to-day development happens on staging using forks (exactly as in stage 3). When changes are ready for production, they are promoted from staging to prod through git promotion, which opens a PR on the prod branch.

The prod workspace is never edited directly. Its only source of change is a merged PR on the prod branch.

Architecture

  • Two (or more) workspaces, each on its own git branch
  • Each workspace has its own git_repository resource and its own entry under workspaces: in wmill.yaml
  • Git sync is configured in promotion mode from staging to prod
  • Developers edit staging via forks (stage 2 pattern)
  • prod is protected by protection rulesets and only the promotion CI/CD can deploy to it
WorkspaceGit branchPromotes to
stagingstagingprod
prodprod

Git Promotion

Setup

1. Create the branches and workspaces

  1. In your git repository, create a staging branch and a prod branch.
  2. Create a staging workspace and a prod workspace in Windmill.

2. Configure git sync on each workspace

For each workspace, go to Workspace settingsGit Sync and create a git_repository resource pointing at the corresponding branch:

  • staging workspace → git_repository on staging branch
  • prod workspace → git_repository on prod branch

3. Configure the promotion target

On the staging workspace:

  1. Under the git sync connection, click Add promotion target.
  2. Create a separate git_repository resource targeting the prod branch (this is not the same resource as the one used for git sync).
  3. Save.
Two resources are required

The git sync resource points at the workspace's own branch (staging). The promotion target points at the target branch (prod). They must be different git_repository resources, even if they point at the same repository.

4. Add the CI/CD workflows

  • push-on-merge.yaml — one copy per workspace (WMILL_WORKSPACE=staging, WMILL_WORKSPACE=prod), triggered by merges to staging and prod respectively.
  • open-pr-on-promotion-commit.yaml — opens a PR on prod when staging promotes a change.
  • push-on-merge-to-forks.yaml and open-pr-on-fork-commit.yaml — unchanged from stage 3, now scoped to the staging workspace.

See git sync CI/CD setup for the workflow files.

5. Multi-workspace wmill.yaml

defaultTs: bun
includes:
- f/**
excludes: []

workspaces:
staging:
baseUrl: https://app.windmill.dev
gitBranch: staging
specificItems:
resources:
- "f/config/**"
settings: true

prod:
baseUrl: https://app.windmill.dev
gitBranch: prod
specificItems:
resources:
- "f/config/**"
settings: true

Each workspace declares its own gitBranch. Items listed under specificItems (for example, environment-specific database credentials) are stored per workspace on disk. See workspace-specific items for the full schema.

Per-folder ownership defaults on deploy

By default, a newly deployed script, flow, app, schedule or trigger runs as whichever user pushed it. For CLI / CI/CD deploys that's the identity behind WMILL_TOKEN — typically a workspace admin or a dedicated deploy user that you've added to wm_deployers. If you want items under a folder to run as a specific service account instead — and to differ per environment — set default_permissioned_as rules on the folder in the target workspace:

# f/customer_x/folder.meta.yaml — committed per workspace via specificItems
summary: ''
display_name: customer_x
owners: []
extra_perms: {}
default_permissioned_as:
- path_glob: 'jobs/**'
permissioned_as: u/customer_x_svc # or g/customer_x or an email
- path_glob: '**'
permissioned_as: u/ops

Rules are ordered; the first path_glob (relative to the folder root) that matches an item wins. Applied only at create time and only when the caller is admin or a member of wm_deployers — existing items are untouched, and non-deployer users still deploy as themselves. Set folders: ["f/**/folder.meta.yaml"] under specificItems in wmill.yaml if you want different rules per workspace on the same path.

Edit the rules in the folder settings UI, or commit them directly in folder.meta.yaml. The CLI also exposes per-item overrides for already-deployed items via wmill script|flow|app|schedule|trigger set-permissioned-as <path> <email>.

Folder defaults are advisory: they only fill in the default when the pushed item does not already carry an explicit on_behalf_of. To opt in to CLI preview of which items will be affected by rules on the next push, set syncBehavior: v1 in wmill.yaml.

6. Protect prod

Enable protection rulesets on the prod workspace with no bypass group — the only way in is the promotion PR.

Developer workflow

  1. A developer needs to change something. They fork the staging workspace (not prod).
  2. They iterate in the fork and merge back to staging via the merge UI. This is the stage 2 workflow plus the git sync integration from stage 3.
  3. When the change needs to go live, they trigger a git promotion from staging to prod.
  4. A PR is opened on the prod branch. The team reviews it in their git platform.
  5. Merging the PR triggers the push-on-merge.yaml workflow, which syncs prod to the new state.

Advantages

  • Fully isolated production environment with a git PR as the only gate.
  • Dev/staging/prod across multiple Windmill instances if needed.
  • Per-workspace configuration via workspace-specific items.
  • All the benefits of stages 1–3 still apply.

Choosing a stage

Most teams should start at stage 1 and only move up when they feel the pain the next stage solves. Stage 4 is real operational overhead and should not be the default — the majority of teams are well served by stages 2 or 3.

  • Stage 1 if you have a small team, no compliance requirements, and a single environment is fine.
  • Stage 2 if you want enforced review on every change and isolated sandboxes, but don't need external version control.
  • Stage 3 if you want git history, backup, local development, and the option of git PR-based review on top of stage 2.
  • Stage 4 if you need a separate production environment with a promotion gate, or you deploy across multiple Windmill instances.

Stages 1 → 2 → 3 → 4 are designed to be adopted in order, but you can skip stages: a small team on Community Edition can go stage 1 → stage 3 (skip forks) to get git sync and local development without needing fork-based review.