diff --git a/changelog/2025-12-16-workspace-forks/index.md b/changelog/2025-12-16-workspace-forks/index.md
new file mode 100644
index 000000000..b7c0e406e
--- /dev/null
+++ b/changelog/2025-12-16-workspace-forks/index.md
@@ -0,0 +1,17 @@
+---
+slug: workspace-forks
+version: v1.593.0
+title: Workspace forks
+tags: ['Workspaces', 'Git sync', 'Collaboration']
+description: Create independent copies of workspaces for parallel development workflows, similar to git branches. Merge changes back to parent workspaces directly from the UI or through git sync.
+features:
+ [
+ 'Fork workspaces to create independent development environments',
+ 'Automatically create git branches when used with git sync',
+ 'Merge forked workspaces back to parent workspaces from the UI',
+ 'Multiple developers can work on separate forks simultaneously',
+ 'Deploy individual items to parent workspace using deployment UI'
+ ]
+docs: /docs/advanced/workspace_forks
+video: /videos/merge-ui-demo.mp4
+---
diff --git a/docs/advanced/11_git_sync/git_sync_diagram.png b/docs/advanced/11_git_sync/git_sync_diagram.png
new file mode 100644
index 000000000..d3dba9882
Binary files /dev/null and b/docs/advanced/11_git_sync/git_sync_diagram.png differ
diff --git a/docs/advanced/11_git_sync/index.mdx b/docs/advanced/11_git_sync/index.mdx
index cc00fa85e..b42d0a26a 100644
--- a/docs/advanced/11_git_sync/index.mdx
+++ b/docs/advanced/11_git_sync/index.mdx
@@ -1,18 +1,10 @@
import DocCard from '@site/src/components/DocCard';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
# Git sync
-From the workspace settings, you can set a [git_repository](../../integrations/git_repository.mdx) resource on which the workspace will automatically commit and push scripts, flows and apps to the repository on each [deploy](../../core_concepts/0_draft_and_deploy/index.mdx).
-
-You can use this feature to [Deploy to prod using a git workflow](#git-sync---promotion-mode-deploy-to-prod-using-a-git-workflow).
-
-
-
-
+Git sync lets Windmill workspaces be tracked by git. Each time an item is deployed, Widnmill will create and push a commit to the specified repository. It is also possible, and recommended, to setup CI/CD actions that will deploy items on windmill when a new commit is detected, enabling bi-directional synchronization.
:::tip Version control
@@ -20,7 +12,13 @@ For all details on Version control in Windmill, see [Version control](../../adva
:::
-This video shows how to set up a Git repository for a workspace (Git sync - sync mode).
+This feature is [Cloud & Enterprise Self-Hosted](/pricing) only.
+
+
+
+## Setup - Git sync from Windmill
+
+This video shows how to set up a Git repository for a workspace.
-## Git sync - Sync mode
-
-All scripts, flows and apps located in the workspace will be pushed to the Git repository. You can filter Git sync on [path](../../core_concepts/16_roles_and_permissions/index.mdx#path) so that only the scripts, flows and apps with a matching path will be pushed to the Git repository. By default, everything in [folders](../../core_concepts/8_groups_and_folders/index.mdx) will be synced (with rule `f/**`).
-
-On each [deployment](../../core_concepts/0_draft_and_deploy/index.mdx#deployed-version), only the updated script/flow/app will be pushed to the remote Git repository.
-
-This feature is [Cloud & Enterprise Self-Hosted](/pricing) only.
-
-Note that you can explicitly exclude (or include) specific files or folders to be taken into account with a [`wmill.yaml` file](https://github.com/windmill-labs/windmill-sync-example/blob/main/wmill.yaml).
-
-### Setup
-
-#### 1. Initialize Git repository
+### 1. Initialize Git repository
First, create a Git repository to store your Windmill workspace:
@@ -80,15 +66,14 @@ git push -u origin main
You now have your Windmill workspace on a GitHub repository.
-#### 2. Setup in Windmill
+### 2. Setup in Windmill
1. Go to workspace settings → Git Sync tab
2. Click **+ Add connection**
3. Create or select a [git_repository](../../integrations/git_repository.mdx) resource pointing to your Git repository. You have two authentication options:
- **GitHub App**: Use the [GitHub App](../../integrations/git_repository.mdx#github-app) for simplified authentication and enhanced security
- **Personal Access Token**: Use a [token](https://github.com/settings/tokens) with Read-and-write on "Contents". Your URL should be `https://[USERNAME]:[TOKEN]@github.com/[ORG|USER]/[REPO_NAME].git`
-4. Select sync mode ([sync mode or promotion mode](#sync-modes))
-5. Complete the configuration of the connection and save
+4. Complete the configuration of the connection and save

@@ -103,7 +88,7 @@ If the repository already contains a `wmill.yaml` file, the settings will be aut

-#### Signing commits with GPG
+### Signing commits with GPG
If your repo requires signed commits, you can set up GPG on your Windmill instance.
@@ -113,7 +98,7 @@ If your repo requires signed commits, you can set up GPG on your Windmill instan
gpg --full-generate-key
```
-2. Add the key to your GithHub account:
+2. Add the key to your GitHub account:
```
gpg --armor --export
@@ -137,10 +122,10 @@ Make sure to double check that the email address associated with the key is the
All commits will now be signed and commited as the user matching the email address associated with the
-key.
+key.
:::
-#### Azure DevOps with Service Principal setup
+### Azure DevOps with Service Principal setup
In Microsoft Entra ID, create an application and a secret (also known as Service Principal - an identity used by applications to access Azure resources).
Create an `azure` resource on your Windmill instance with the application's `client_id`, `client_secret` and `tenant_id`.
@@ -151,11 +136,170 @@ In Git sync settings of your Windmill instance, define a new repository with URL
https://AZURE_DEVOPS_TOKEN()@dev.azure.com///_git/
```
+## Setup - CI/CD from git repository
+
+To allow for bidirectional sync, CI/CD can be configured to sync back changes to Windmill anytime a commit is made.
+
+### Github Actions
+
+1. Add [GitHub Actions](https://github.com/features/actions) to your repository. You will find the necessary actions in the [windmill-sync-example repository](https://github.com/windmill-labs/windmill-sync-example).
+2. Create a `.github/workflows` directory in your repository and add the following files:
+ - `open-pr-on-fork-commit.yaml`: This action automatically creates a PR when Windmill commits a change to a workspace fork. Workspace forks are explained in a section below.
+ - `push-on-merge.yaml`: This action automatically pushes the content of the repo to the Windmill prod workspace when a PR is merged. Update the `WMILL_WORKSPACE` variable to the name of your prod workspace.
+ - Optionnaly, if you want to add a staging workspace, copy the previous GitHub action/workflow file but now set the `WMILL_WORKSPACE` variable to the id of the staging workspace and the `WMILL_URL` variable to the base URL of the Windmill instance if different than the one for prod. Also changes the trigger to listen to the branches: 'staging'.
+ - `push-on-merge-to-forks.yaml`: This does the same as `push-on-merge.yaml` but for all [Workspace Forks](../20_workspace_forks/index.mdx), enabling the full power of the feature.
+3. In GitHub, [allow actions](https://docs.github.com/en/enterprise-server@3.10/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#preventing-github-actions-from-creating-or-approving-pull-requests) to create and approve pull requests.
+4. Create a [user token](../../core_concepts/4_webhooks/index.mdx#user-token) in Windmill and save it as a [secret](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository) named `WMILL_TOKEN` in your GitHub repository Settings > "Secret and Variable" > "Actions".
+
+On top of `WMILL_TOKEN`, 2 other variables need to be set in the GitHub action workflow file:
+
+- `WMILL_WORKSPACE`: the name of the workspace
+- `WMILL_URL`: the base URL of the Windmill instance (e.g. https://app.windmill.dev/)
+
+
+
+```yaml
+name: "Open pull request for workspace forks"
+on:
+ push:
+ branches:
+ - wm-fork/**
+
+env:
+TARGET_BRANCH: main
+
+jobs:
+submit_pull_requests:
+runs-on: ubuntu-latest
+permissions:
+contents: read
+pull-requests: write
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Create pull request
+ run: |
+ gh pr view ${{ github.ref_name }} \
+ && gh pr reopen ${{ github.ref_name }} \
+ || gh pr create -B ${{ env.TARGET_BRANCH }} -H ${{ github.ref_name }} \
+ --title "${{github.event.head_commit.message }}" \
+ --body "PR created by Github action '${{ github.workflow }}'"
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+````
+
+
+```yaml
+name: "Push main to Windmill workspace"
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - "main"
+ # if the windmill workspace is persisted in a subfolder of this repos, you can add the following to avoid pushing to windmill when there's no change
+ # paths:
+ # - wm/**
+
+env:
+ WMILL_URL: https://app.windmill.dev/
+ WMILL_WORKSPACE: github-sync-example-prod
+
+jobs:
+ sync:
+ environment: windmill
+ runs-on: "ubuntu-latest"
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 20
+
+ # We check the commit to make sure it doesn't start with [WM] which commits coming from Windmill Git Sync do.\
+ # If that's the case, then we stop the workflow as we want to avoid overwriting changes that are out-of-sync
+ # (for instance if one were to deploy in quick succession)
+ - name: Check commit message
+ id: check_message
+ run: |
+ COMMIT_MESSAGE="${{ github.event.head_commit.message }}"
+ if [[ "$COMMIT_MESSAGE" =~ ^\[WM\] ]]; then
+ echo "Commit message starts with '[WM]', skipping push to Windmill to avoid overwriting deploy that immediately follows it"
+ echo "skip=skip" >> $GITHUB_OUTPUT
+ fi
+
+ # (push will pull first to detect conflicts and only push actual changes)
+ - name: Push changes
+ if: steps.check_message.outputs.skip != 'skip'
+ run: |
+ npm install -g windmill-cli@1.393.3
+ wmill sync push --yes --skip-variables --skip-secrets --skip-resources --workspace ${{ env.WMILL_WORKSPACE }} --token ${{ secrets.WMILL_TOKEN }} --base-url ${{ env.WMILL_URL }}
+````
+
+
+
+```yaml
+name: "Push forks to Windmill workspace forks"
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - wm-fork/**
+
+env:
+WMILL_URL: https://app.windmill.dev/
+
+jobs:
+sync:
+environment: windmill
+runs-on: "ubuntu-latest"
+steps: - name: Checkout
+uses: actions/checkout@v3
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 20
+
+ - name: Extract workspace from branch name
+ id: workspace
+ run: |
+ BRANCH_NAME=${GITHUB_REF#refs/heads/}
+ WORKSPACE=$(echo "$BRANCH_NAME" | sed 's|wm-fork/|wm-fork-|' | sed 's|/|-|g')
+ echo "workspace=$WORKSPACE" >> $GITHUB_OUTPUT
+
+ # We check the commit to make sure it doesn't start with [WM] which commits coming from Windmill Git Sync do.\
+ # If that's the case, then we stop the workflow as we want to avoid overwriting changes that are out-of-sync
+ # (for instance if one were to deploy in quick succession)
+ - name: Check commit message
+ id: check_message
+ run: |
+ COMMIT_MESSAGE="${{ github.event.head_commit.message }}"
+ if [[ "$COMMIT_MESSAGE" =~ ^\[WM\] ]]; then
+ echo "Commit message starts with '[WM]', skipping push to Windmill to avoid overwriting deploy that immediately follows it"
+ echo "skip=skip" >> $GITHUB_OUTPUT
+ fi
+
+ # (push will pull first to detect conflicts and only push actual changes)
+ - name: Push changes
+ if: steps.check_message.outputs.skip != 'skip'
+ run: |
+ npm install -g windmill-cli@1.393.3
+ wmill sync push --yes --skip-variables --skip-secrets --skip-resources --workspace ${{ steps.workspace.outputs.workspace }} --token ${{ secrets.WMILL_TOKEN }} --base-url ${{ env.WMILL_URL }}
+
+````
+
+
+
+### Other Git hosting platforms
+
+If you are using a different git hosting platform, such as GitLab or Codeberg, you just need to setup similar actions in your CI/CD. There are currently no detailed instructions for other platforms so you will need to use the provided GitHub ones and adpapt it to your needs.
+
## Filters
### Path filters
-Only scripts, flows and apps with their path matching one of the set filters will be synced to the Git repositories below. The filters allow `*'` and `**'` characters, with `*'` matching any character allowed in paths until the next slash (`/`) and `**'` matching anything including slashes.
+Only scripts, flows and apps with their path matching one of the set filters will be synced to the Git repositories below. The filters allow `*` and `**` characters, with `*` matching any character allowed in paths until the next slash (`/`) and `**` matching anything including slashes.
By default everything in folders (with rule `f/**`) will be synced.
You can configure:
@@ -185,32 +329,9 @@ You can filter on:
- **Workspace settings** - Global workspace configuration
- **Encryption key** - Workspace encryption key
-## Repositories to sync
-
-The changes will be deployed to all the repositories set in the Git sync settings.
-
-### Sync modes
-
-You can choose between two sync modes for each repository:
-
-#### Sync mode (default)
-
-Changes are committed directly to the branch specified in the [git_repository](../../integrations/git_repository.mdx) resource. This is the standard mode for simple workspace synchronization.
+## Adding secondary sync repositories
-When combined with [branch-specific items](../3_cli/branch-specific-items.mdx), different workspaces can sync to different branches while maintaining environment-specific configurations (e.g., production workspace syncs to `prod` branch, development workspace syncs to `dev` branch).
-
-#### Promotion mode
-
-Windmill will create branches per deployed object based on its path, prefixed with 'wm_deploy/'. This enables advanced deployment workflows with pull requests and code review processes.
-
-When promotion mode is enabled, you can choose to:
-
-- **Create one branch per deployed object** (default)
-- **Group deployed objects by folder**: Create a branch per folder containing objects being deployed instead
-
-You can configure promotion-specific sync behavior using `promotionOverrides` in your [`wmill.yaml`](../3_cli/sync.mdx#wmillyaml) file. This allows different filter settings when promoting changes to specific branches.
-
-This promotion mode is used to [deploy to a prod workspace using a git workflow](#git-sync---promotion-mode-deploy-to-prod-using-a-git-workflow).
+You can add secondary sync repositories if you need to. Just go to Git sync settings, press `+ Add secondary sync repo` and follow the same instructions as for the first one. Note that having multiple bidirectional repositories is not currently supported, secondary repositories can only act as read-only copies of the workspace.
## Repository operations
@@ -239,41 +360,30 @@ The frontend will detect existing `wmill.yaml` files and merge settings appropri
You can exclude specific types per repository, overriding the global workspace filters.
-## Git sync - Promotion mode: Deploy to prod using a git workflow
+## Workspace forks integration
-This feature can be used alongside GiHub Actions to adopt a robust development process for your Windmill scripts, flows and apps,
-with for example a Staging Workspace making automatically PRs on a repo that pushes to a Prod workspace upon merge.
+Git sync automatically creates corresponding git branches for [workspace forks](../20_workspace_forks/index.mdx). When you fork a workspace with git sync enabled, Windmill creates a branch with the naming pattern `wm-fork//` and keeps it synchronized with the forked workspace.
-
+This enables parallel development workflows where multiple developers can work on separate workspace forks, each with its own git branch, and merge changes back to the parent workspace either through the UI or via pull requests.
-
+
+
+
-
+## Promotion workflow: Cross-instance deployment using a git workflow
-More details at:
+One option you will see in the Git Sync settings tab, is to add a Promotion target. This is an advanced setup that leverages the feature to create deployements from one workspace to another.
+
+Learn how to setup this promotion workflow:
-
-
diff --git a/docs/advanced/11_git_sync/windmill_collaboration.mdx b/docs/advanced/11_git_sync/windmill_collaboration.mdx
new file mode 100644
index 000000000..95601309a
--- /dev/null
+++ b/docs/advanced/11_git_sync/windmill_collaboration.mdx
@@ -0,0 +1,51 @@
+import DocCard from '@site/src/components/DocCard';
+
+# Collaborating on Windmill
+
+In windmill there are multiple ways to collaborate
+
+## Workspace forks
+
+The easiest and main way of collaborating on windmill is through the use of workspace forks. This feature lets users branch off of a workspace and have an exact copy where they can create new items or make changes, test them, and deploy them to the main workspace once it's all working.
+
+
+
+
+## Git sync
+
+Git sync is a feature that replicates the state of a workspace into a git repository. When properly set-up, changes made to the repository are immediately reflected in the workspace, and vice-versa. This enables local development as well as development in the Web IDE to be tracked and managed by git, and any git-based workflow is possible.
+
+
+### Git sync + Workspace forks
+
+Workspace forks unlock their full potential when git sync is enabled. When a fork is created, a branch with a corresponding name is created, and changes are tracked there.
+
+### Example: feature development workflow
+
+1. **Create fork**: The user forks the `main` workspace into a fork named `wm-fork-new-feature`
+2. **Develop**: User makes changes in the forked workspace -> The changes are reflected in the branch `wm-fork/main/new-feature` of the repo
+3. **Create PR**: A PR is automatically created by the CI from `wm-fork/main/new-feature` -> `main`
+4. **Review & merge**: Team reviews changes before merging to main branch
+5. **Sync back changes**: Changes are automatically synced to the main workspace as soon as the PR is merged.
+
+
+
+
+## Advanced setup: Cross-instance deployment (promotion)
+
+When you have workspaces in different instances, for example in a setup with a staging instance and a prod instance, you might want to deploy changes from one workspace to the other. One way to do this is through a cross-instance promotion: when changes are made in the first "staging" workspace, a branch with a name corresponding to the item is created in the second workspace's repo. A PR is automatically created through the CI/CD. Changes are reviewed, and once the PR is merged the changes are reflected in the "production" workspace.
+
+**Requirements**:
+- Git sync should be setup on both workspaces, so that they're both syncing changes with their respective repositories.
+
+
diff --git a/docs/advanced/12_deploy_to_prod/index.mdx b/docs/advanced/12_deploy_to_prod/index.mdx
index 2b88e9926..4789534fb 100644
--- a/docs/advanced/12_deploy_to_prod/index.mdx
+++ b/docs/advanced/12_deploy_to_prod/index.mdx
@@ -2,37 +2,34 @@ import DocCard from '@site/src/components/DocCard';
# Deploy to prod
-To deploy to prod, 3 options are possible.
-
-[Draft and deploy](#option-1-draft-and-deploy---single-workspace) is the simplest method. It is meant to be used in a single workspace.
-
-[Git integration](#option-2-deploy-to-prod-using-a-git-workflow---multi-workspace-recommended) is clearly the superior, most powerful method but it is more complex. Usually, to deploy to prod you would want absolutely to have the normal CI flow that goes through one review which is something that is built-in with GitHub/GitLab. Also you may want to put some CI checks there.
-
-However, in a setting where you have dev/staging/prod, you could use the [UI to deploy to staging from dev](#option-3-deploy-to-prod-using-the-ui-only---multi-workspace), and then use git between staging and prod to tighten down prod.
+When working on Windmill, you will quickly be looking for ways to iterate on and test your scripts, flows, and apps all the while having a working version running. The following section explains the different methods available in Windmill to have a production environement and deploy to it.
## Option 1. Draft and deploy - Single workspace
A simple setup in which deploying to prod means deploying items that have been iterated on in the UI as Drafts.
Deployments in Windmill are commonly done from the same workspace using the [Draft and deploy](../../core_concepts/0_draft_and_deploy/index.mdx) buttons.
-## Option 2. Deploy to prod using a git workflow - Multi workspace (recommended)
+## Option 2. Workspace forks - Multi workspace (recommended)
+
+[Windmill workspaces](../20_workspace_forks/index.mdx) can be forked, creating a new copy of the workspace at that point in time. The forked workspace can be iterated on, tested, and once changes are ready, merged back to the original workspace, thus deploying the new versions of the scripts, flows, or apps. The workflow will be familiar to anyone who has used branches in version control tools such as git. The analogy can be further reinforced if [Git Sync](../11_git_sync/index.mdx) is setup: Windmill will autmatically create branches for each of the forks, and merging can be controlled direclty through git.
+
+## Option 3. Promotion workflow: deploying through git - Multi workspace (possible cross-instance)
-The integration can be used to push from git, and receive changes done from the UI in a bi-directional way.
-You can also use a separate dev and staging branch and repo and have Windmill create automatically branches and Pull Request upon any changes deployed to staging/dev.
+This is a more complex but very reliable setup that leverages [Git Sync](../11_git_sync/index.mdx) to deploy from one workspace to another through git. When changes are done to the Staging workspace, they are pushed to a branch in the Prod repo. Once merge to the main branch of the Prod repo, the Prod workspace is updated with the changes.
-This process can be used in particular for [local development](../4_local_development/index.mdx) with a solid setup:
+This workflow lets you review all the changes on a PR before merging and deploying. It also has the advantage, unlike the other options here, to work across separate windmill instances.
-
+
-## Option 3. Deploy to prod using the UI only - Multi workspace
+## Option 4. Deploy to prod using the UI only - Multi workspace
From a workspace in Windmill, you can deploy a script/flow/resource/variable and all its dependencies to another workspace.
diff --git a/docs/advanced/20_workspace_forks/index.mdx b/docs/advanced/20_workspace_forks/index.mdx
index e2bd95c2b..a8303b38c 100644
--- a/docs/advanced/20_workspace_forks/index.mdx
+++ b/docs/advanced/20_workspace_forks/index.mdx
@@ -35,8 +35,8 @@ Key features:
### Prerequisites
- Being on a self-hosted EE instance
-- [Git sync](../11_git_sync/index.mdx) configured (recommended for full functionality)
-- [CI/CD actions ](../9_deploy_gh_gl/index.mdx#github-actions-setup) to merge back from the git remote to Windmill
+- [Git sync](../11_git_sync/index.mdx) configured (optional, required only for git-based workflows)
+- [CI/CD actions ](../9_deploy_gh_gl/index.mdx#github-actions-setup) to merge back from the git remote to Windmill (only required for git sync workflows)
### Fork creation
@@ -80,7 +80,7 @@ When workspace forks are used with [git sync](../11_git_sync/index.mdx), Windmil
the parent workspace, and keep track of changes there. External changes to the branch are then synced back to the forked workspace if the appropriate
CI/CD actions are setup. Once the changes are ready, a PR can be opened to sync back changes to the original workspace.
-Workspace forks are designed to be used with git sync, so make sure to have it properly setup and in particular the [CI/CD actions](../9_deploy_gh_gl/index.mdx#github-actions-setup) specific to forks should be set. Make sure to not forget the `push-on-merge-to-forks.yaml` action.
+Workspace forks can be used with git sync for full version control integration. If using git sync, make sure to have it properly setup and in particular the [CI/CD actions](../9_deploy_gh_gl/index.mdx#github-actions-setup) specific to forks should be set. Make sure to not forget the `push-on-merge-to-forks.yaml` action.
### Fork and branch naming
@@ -101,7 +101,28 @@ This naming convention is what enables Windmill to match branches to workspaces
Once a fork is created, it is automatically setup to deploy to its parent branch. You can deploy any item to the parent branch directly from the UI by clicking it and selecting `Deploy to staging/prod`. Learn more about the [Deployment UI](../../core_concepts/12_staging_prod/index.md).
-There is currently no way to update the parent workspace changes back to the fork through the UI, but some features are planned to remediate to this.
+### Merge workspaces from the UI
+
+You can merge changes from a forked workspace back to its parent workspace directly from the UI without requiring git sync. This provides a simpler workflow for teams that don't need full git integration.
+
+To merge a fork:
+
+1. Navigate to the forked workspace
+2. On the home page, a banner will show you the diff with its parent workspace. Click `Review & Deploy Changes`
+3. Review the changes and confirm the merge
+
+
+
+#### Items behind and conflicts
+
+If it is detected that some of the differences come in fact from the original workspace, these changes will be shown as 'behind'. Before deploying, all behind changes must be updated into the fork and properly tested. When an items has changes that are both ahead and behind, it will be marked as a conflict and will be warned to the user. The user must then review the diff and decide how to edit the item to resolve the conflicting changes. Until deployed or updated however, the item will still be marked as a conflict. For more granular conflict detection and better tracked resolution, you can choose to merge the workspaces through a git workflow instead.
+
+The merge will transfer all selected scripts, flows, apps, resources, and variables from the fork to the parent workspace.
### Git sync based merging
@@ -134,7 +155,3 @@ When git sync is properly setup, the workspace is synchronized with one of the b
href="/docs/core_concepts/collaboration"
/>
-
-
-
-
diff --git a/docs/advanced/4_local_development/index.mdx b/docs/advanced/4_local_development/index.mdx
index 1c8030e46..c422de7bc 100644
--- a/docs/advanced/4_local_development/index.mdx
+++ b/docs/advanced/4_local_development/index.mdx
@@ -10,48 +10,25 @@ Windmill has [its own integrated development environment](../../code_editor/inde
To simply create and edit scripts and flows locally, you can directly go to the [Develop Locally](#develop-locally) section.
-For a more complex setup involving Git, you can go to the [Local development Recommended Setup](#local-development-recommended-setup).
-
-
-
-## Local development recommended setup
-
-Local development involves two components:
-
-1. Being able to create and edit Windmill scripts and flow from your favorite IDE.
-2. Deploy them to Windmill and at the same time [version](../13_version_control/index.mdx) them in a Git repository.
-
-In addition to the core functionalities just mentioned, some might want to add the concept of [deployment](../12_deploy_to_prod/index.mdx). This encompasses having a staging and production Windmill environment, and being able to deploy from Staging to Production.
-
-The diagram below illustrates the full process. We're going to explain it quickly, and in the following sections we will decompose it.
-
-
-
-It works as follows:
-
-- 2 different workspaces exist in Windmill: one for Staging and one for Prod, and a Git repository that has been set to sync the Windmill Staging workspace.
-- Some developers work from their favorite IDE. They can create new Windmill scripts and flows, edit existing ones, and push them to the Staging repository. Some developers can work directly in Windmill's web IDE. All of this happens in the Staging workspace.
-- Every time a script or a flow is deployed in the Staging workspace, Windmill will automatically commit the change to the Git repository using [Git sync](../11_git_sync/index.mdx). It can either commit directly to a specific (i.e. `staging`) branch, or open PRs to this branch (one PR per script/flow).
-- Within the Git repository, every time the `staging` branch is merged into the production branch (i.e. `main`), all the changes are pushed at once the Windmill Production workspace.
-
-To summarize, developers operate only in Windmill Staging workspace. Windmill Production workspace is updated only by the CI when the Git staging branch is merged into the production branch.
-
-Now let's deep dive into the first part. We will first explain how developers can set up their local environment to be able to create and edit Windmill script from their IDE, then we will see how to sync Windmill workspaces to a Git repository.
-
-The second part is well covered in:
+Usually however, you will need for a robust setup to enable collaboration and compatibility with version control tools like git. The recommended approach for this is to use [Workspace Forks](../20_workspace_forks/index.mdx) and [Git Sync](../11_git_sync/index.mdx).
+
+
+
+
+Another advanced workflow that doesn't use workspace forks is explained here:
diff --git a/docs/advanced/9_deploy_gh_gl/index.mdx b/docs/advanced/9_deploy_gh_gl/index.mdx
index 00de8e761..3320ef9be 100644
--- a/docs/advanced/9_deploy_gh_gl/index.mdx
+++ b/docs/advanced/9_deploy_gh_gl/index.mdx
@@ -2,11 +2,7 @@ import DocCard from '@site/src/components/DocCard';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
-# Deploy to prod using a git workflow
-
-Windmill integration with Git repositories makes it possible to adopt a robust development process for your Windmill scripts, flows and apps.
-
-This is the recommended way to deploy to prod in Windmill.
+# Promotion workflow (cross-instance)
:::info Deploy to prod in Windmill
@@ -14,51 +10,26 @@ For all details on Deployments to prod in Windmill, see [Deploy to prod](../12_d
:::
-
-
-> See section [Setup the full Git workflow](#setup-the-full-git-workflow) for the detailed setup steps.
-
-
-
-The integration with git works in three-folds:
-
-1. [GitHub Action](https://docs.github.com/en/actions) + [CLI](../3_cli/index.mdx): upon any commit to a particular branch, the GitHub action will run the `wmill` CLI and push to a Windmill workspace this works using the CLI doing `wmill sync push` ([free & open source](/pricing)).
-
-:::tip
-
-You can also trigger a webhook and push the changes to Windmill using [this Windmill script](https://hub.windmill.dev/scripts/windmill/11414/git-sync-push-windmill) and pass the arguments as query args in the webhook triggered after pushing to the repo.
-
-:::
-
-2. [Git sync](../11_git_sync/index.mdx) (Sync mode): Windmill automatically committing to a git repository upon any deployment to a workspace, this works using the CLI doing `wmill sync pull` ([Cloud and Enterprise Self-Hosted](/pricing)). Having it commit back to Windmill has 2 benefits:
-
- - It ensures that any automatically created metadata files are wrote-back (in case you pushed a script without its metadata for instance).
- - It ensures that any modification done in the UI is kept in sync with the git repository and guarantees a bi-sync between the repo and the UI.
-
-3. [Git sync](../11_git_sync/index.mdx) (Promotion mode): Windmill automatically creates a branch specific to that item (and whose name is derived from that item) that targets the branch set in the git sync settings, upon any change to any items, be it from the UI or from git ([Cloud and Enterprise Self-Hosted](/pricing)). This should be coupled with a GitHub action that automatically create a PR when a branch is created. This PR can then be reviewed and merged. Upon being merged to the prod branch, a GitHub action as described in 1. would then deploy it to the prod branch.
-
-Once everything is set up, the process is as follows:
-
-- Users iterate and make their changes in the "staging" Windmill workspace UI or in the git staging branch directly.
-- Every time a Windmill App, Flow or Script is deployed to that workspace (via Windmill's UI or through the GitHub action that deploys to staging upon any change), Windmill automatically sync it back to the repo on the "staging" branch (Git sync - sync mode) and also create a branch that targets prod and keep it in sync with any new changes (Git sync - Promotion mode)
-- On every new branch created, PRs are automatically created via a GitHub Action. Approved GitHub users can review and merge those PRs.
-- Every time a PR is merged, another GitHub Action automatically deploys the change to a "production" Windmill workspace.
+Promotion workflow is an advanced setup leveraging the same tech as [Git Sync](../11_git_sync/index.mdx) for deploying from a workspace to another, even across different instances.
-Note that although the CLI is used by both the GitHub Action and the Git sync, the CLI does not need to be used directly by any users and everything happen behind the scene in an automated way.
+Let's walk through an example to better understand it.
-This gives the flexibility to fully test new Windmill scripts, flows and apps, while having them [version-controlled](../13_version_control/index.mdx) and deployed in an automated way to the production environment.
+- There are two workspaces `staging` and `prod`, setup with [Git Sync](../11_git_sync/index.mdx) to their respective repositories `staging-repo` and `prod-repo`. `staging` is also set to target `prod-repo` for promotion.
+- A user makes a change in the script "f/shared/amazing_script" in workspace `staging`.
+- This triggers the promotion, which will create a branch named "wm_deploy/staging/f/shared/amazing_script" on the repository `prod-repo` with the changes.
+- A PR is automatically created through a CI/CD action.
+- The change is reviewed by someone with merge rights to `prod-repo` and merged.
+- Once merged, the Git Sync setup between `prod` and `prod-repo` ensures the change is reflected in the `prod` workspace. Deployment complete
-This process can be used in particular for [local development](../4_local_development/index.mdx).
+Note that `prod-repo` and `staging-repo` can be (and often are) the same repo but targetting a different branch.
-:::tip
+Here is a diagram to better illustrate the workflow with this setup.
-Check out the [windmill-sync-example repository](https://github.com/windmill-labs/windmill-sync-example) as an illustration of this process.
+
-:::
-
-Deploying to a prod workspace using git requires the [Git sync](../11_git_sync/index.mdx) feature, which is is a [Cloud plans and Self-Hosted Enterprise Edition](/pricing)-only feature.
+> See section [Setup the full Git workflow](#setup-the-full-git-workflow) for the detailed setup steps.
-From the workspace settings, you can set a [git_repository](../../integrations/git_repository.mdx) resource on which the workspace will automatically commit and push scripts, flows and apps to the repository on each [deploy](../../core_concepts/0_draft_and_deploy/index.mdx).
+This workflow requires the [Git sync](../11_git_sync/index.mdx) feature, which is is a [Cloud plans and Self-Hosted Enterprise Edition](/pricing)-only feature.
-## Setup the full Git workflow
-
-Note: this is the detailed setup steps for a [GitHub](https://github.com/) repository. It will need to be adapted for [GitLab](https://about.gitlab.com/).
-
-The video below shows a simplified setup, see the steps below it for the full setup.
-
-
+:::tip
-
+You can also trigger a webhook and push the changes to Windmill using [this Windmill script](https://hub.windmill.dev/scripts/windmill/11414/git-sync-push-windmill) and pass the arguments as query args in the webhook triggered after pushing to the repo.
-:::warning
-If you are not using the [Enterprise Edition](/pricing) (EE) version of Windmill, you can still follow the parts of this guide that do not involve Git sync.
:::
:::tip
-The guide covers a staging and prod setup. To add an additional dev environment, simply consider staging to be the target of the dev workspace and prod to be the target of the staging workspace.
-:::
-### Pull workspace locally
+Check out the [windmill-sync-example repository](https://github.com/windmill-labs/windmill-sync-example) as an illustration of this process.
-1. Open your terminal and add your workspace to the [Windmill CLI](../3_cli/index.mdx) using the command:
- ```bash
- wmill workspace add
- ```
-2. Authorize the CLI to access the workspace.
-3. [Pull](../3_cli/sync.mdx) the entire Windmill workspace locally to your machine.
+:::
-The CLI is able to sync [variables](../../core_concepts/2_variables_and_secrets/index.mdx), [resources](../../core_concepts/3_resources_and_types/index.mdx) and [secrets](../../core_concepts/2_variables_and_secrets/index.mdx#secrets) as well. However, everywhere the CLI is used here, it it set with the flags `--skip-variables --skip-secrets --skip-resources` to avoid syncing them. This is because variables, resources and secrets should have values that are specific to each environment.
+## Setup the full workflow
-For instance, a [resource](../../core_concepts/3_resources_and_types/index.mdx) named `f/myproject/myimportantdb` should have a different value in staging and prod. This is why they are not synced and should be set manually in each environment. You can however if you prefer, manually sync those. Do note that secrets have an additional layer of encryption and are by default exported in their encrypted form whose decryption key is workspace specific. To sync them between workspace, use `--plain-secrets` to export them in plain text.
+Note: this is the detailed setup steps for a [GitHub](https://github.com/) repository. It will need to be adapted for [GitLab](https://about.gitlab.com/) or other git hosting platforms.
-### Push workspace to GitHub
+
-1. Create a new private repository on GitHub.
-2. Use the [suggested Git commands](../11_git_sync/index.mdx#push-workspace-to-github) to push your local repository to GitHub.
-3. Verify that your workspace is now available in the GitHub repository.
+:::tip
+The guide covers a staging and prod setup. To add an additional dev environment, simply consider staging to be the target of the dev workspace and prod to be the target of the staging workspace.
+:::
### Setup git sync
-1. In Windmill, navigate to the workspace settings and go to the [Git sync](../11_git_sync/index.mdx) tab.
-2. Create a `git_repository` [resource](../../core_concepts/3_resources_and_types/index.mdx) with the necessary URL, username, repo name, and a GitHub token. You can also use a [GitHub app installation](../integrations/git_repository#github-app) to connect a repo to your windmill instance.
-3. Generate a fine-grained GitHub [token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token) with read and write permissions for content and add it to the Windmill `git_repository` resource.
-
-Your URL should be `https://[USERNAME]:[TOKEN]@github.com/[ORG|USER]/[REPO_NAME].git`
+[Git Sync](../11_git_sync/index.mdx) must be setup on both staging and prod workspaces. You can choose to sync them to different repositories, or to the same repository but on different branches. Learn [how to setup Git Sync](../11_git_sync/index.mdx#setup---git-sync-from-windmill) for your workspaces. Make sure to include the CI/CD actions for bidirectional sync.
-If you do the setup with a staging workspace, you can set the branch to 'Staging'.
+### Set the promotion target
-Test git sync:
+There should now be two workspaces, `staging` and `prod` and two branches `staging-branch`, `prod-branch`. The `staging` workspace must now be setup to target the `prod-branch` for promotion. If this is not clear, go back to the diagram at the top of this page.
-1. Create a [folder](../../core_concepts/8_groups_and_folders/index.mdx) in your Windmill workspace and add scripts, apps, and flows to it.
-2. Verify that these items are pushed to the GitHub repository and appear in the correct folder structure.
+To do this go to the `staging` workspace -> Workspace Settings -> Git Sync. If you properly set up Git Sync in the last step, you should find the git sync settings and the git repository resource that points to the `staging-branch` branch. Under that, you will find the option to add a promotion target. The configuration is identical to Git Sync. Make sure you create a new git resource that points to the `prod-branch` in the appropriate repo.
-### Deploy to a prod workspace using a git workflow
+Additionally, you will be asked to choose between:
+- **Create one branch per deployed object** (default)
+- **Group deployed objects by folder**: Create a branch per folder containing objects being deployed
-1. Set up a new empty workspace in Windmill that will be the target of the prod branch.
-2. Enable the [Create one branch per deployed object](../11_git_sync/index.mdx#create-one-branch-per-deployed-object) option in the Git sync settings.
-3. In GitHub, [allow actions](https://docs.github.com/en/enterprise-server@3.10/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#preventing-github-actions-from-creating-or-approving-pull-requests) to create and approve pull requests.
-4. Create a [user token](../../core_concepts/4_webhooks/index.mdx#user-token) in Windmill and save it as a [secret](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository) named `WMILL_TOKEN` in your GitHub repository Settings > "Secret and Variable" > "Actions".
-
-Test deploy to prod workspace:
-
-1. From the staging workspace, create a new flow and save it in a folder.
-2. Verify that a new branch is created in the GitHub repository and a pull request is opened.
-3. Merge the pull request and check that the changes are deployed to the prod workspace in Windmill.
+Now you've succesfully set-up the `prod-branch` as the promotion target for the `staging` workspace. Any changes done to the staging workspace will now also be committed on a branch off of `prod-branch` named `wm-deploy/f/folder/item`. In the next step we will create a Github Action that automaticccaly creates a PR to merge these.
### GitHub Actions setup
-1. Add [GitHub Actions](https://github.com/features/actions) to your repository. You will find the necessary actions in the [windmill-sync-example repository](https://github.com/windmill-labs/windmill-sync-example).
-2. Create a `.github/workflows` directory in your repository and add the following files:
- - `open-pr-on-commit.yaml`: This action automatically creates a PR when Windmill commits a change.
- - `push-on-merge.yaml`: This action automatically pushes the content of the repo to the Windmill prod workspace when a PR is merged. Update the `WMILL_WORKSPACE` variable to the name of your prod workspace.
- - Optionnaly, if you want to add a staging workspace, copy the previous GitHub action/workflow file but now set the `WMILL_WORKSPACE` variable to the id of the staging workspace and the `WMILL_URL` variable to the base URL of the Windmill instance if different than the one for prod. Also changes the trigger to listen to the branches: 'staging'.
- - `push-on-merge-to-forks.yaml`: This does the same as `push-on-merge.yaml` but for all [Workspace Forks](../20_workspace_forks/index.mdx), enabling the full power of the feature.
-
-On top of `WMILL_TOKEN`, 2 other variables need to be set in the GitHub action workflow file:
-
-- `WMILL_WORKSPACE`: the name of the workspace
-- `WMILL_URL`: the base URL of the Windmill instance (e.g. https://app.windmill.dev/)
+On top of the CI/CD [actions you already setup during the Git Sync configuration](../11_git_sync/index.mdx#github-actions), you need one more action to automatically create a PR when the `wm-deploy/*` branches are created
-
+
```yaml
-name: Windmill Pull Request
+name: "Promotion: Deploy from staging to prod"
on:
push:
branches:
- - wm_deploy/github-sync-example-staging/**
- - wm-fork/**
-
+ - wm_deploy/**
env:
-TARGET_BRANCH: main
+TARGET_BRANCH: prod
jobs:
submit_pull_requests:
@@ -187,109 +111,6 @@ pull-requests: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-````
-
-
-```yaml
-name: "Push main to Windmill workspace"
-on:
- workflow_dispatch:
- push:
- branches:
- - "main"
- # if the windmill workspace is persisted in a subfolder of this repos, you can add the following to avoid pushing to windmill when there's no change
- # paths:
- # - wm/**
-
-env:
- WMILL_URL: https://app.windmill.dev/
- WMILL_WORKSPACE: github-sync-example-prod
-
-jobs:
- sync:
- environment: windmill
- runs-on: "ubuntu-latest"
- steps:
- - name: Checkout
- uses: actions/checkout@v3
-
- - uses: actions/setup-node@v4
- with:
- node-version: 20
-
- # We check the commit to make sure it doesn't start with [WM] which commits coming from Windmill Git Sync do.\
- # If that's the case, then we stop the workflow as we want to avoid overwriting changes that are out-of-sync
- # (for instance if one were to deploy in quick succession)
- - name: Check commit message
- id: check_message
- run: |
- COMMIT_MESSAGE="${{ github.event.head_commit.message }}"
- if [[ "$COMMIT_MESSAGE" =~ ^\[WM\] ]]; then
- echo "Commit message starts with '[WM]', skipping push to Windmill to avoid overwriting deploy that immediately follows it"
- echo "skip=skip" >> $GITHUB_OUTPUT
- fi
-
- # (push will pull first to detect conflicts and only push actual changes)
- - name: Push changes
- if: steps.check_message.outputs.skip != 'skip'
- run: |
- npm install -g windmill-cli@1.393.3
- wmill sync push --yes --skip-variables --skip-secrets --skip-resources --workspace ${{ env.WMILL_WORKSPACE }} --token ${{ secrets.WMILL_TOKEN }} --base-url ${{ env.WMILL_URL }}
-````
-
-
-
-```yaml
-name: "Push forks to Windmill workspace forks"
-on:
- workflow_dispatch:
- push:
- branches:
- - wm-fork/**
- # if the windmill workspace is persisted in a subfolder of this repos, you can add the following to avoid pushing to windmill when there's no change
- # paths:
- # - wm/**
-
-env:
-WMILL_URL: https://app.windmill.dev/
-
-jobs:
-sync:
-environment: windmill
-runs-on: "ubuntu-latest"
-steps: - name: Checkout
-uses: actions/checkout@v3
-
- - uses: actions/setup-node@v4
- with:
- node-version: 20
-
- - name: Extract workspace from branch name
- id: workspace
- run: |
- BRANCH_NAME=${GITHUB_REF#refs/heads/}
- WORKSPACE=$(echo "$BRANCH_NAME" | sed 's|wm-fork/|wm-fork-|' | sed 's|/|-|g')
- echo "workspace=$WORKSPACE" >> $GITHUB_OUTPUT
-
- # We check the commit to make sure it doesn't start with [WM] which commits coming from Windmill Git Sync do.\
- # If that's the case, then we stop the workflow as we want to avoid overwriting changes that are out-of-sync
- # (for instance if one were to deploy in quick succession)
- - name: Check commit message
- id: check_message
- run: |
- COMMIT_MESSAGE="${{ github.event.head_commit.message }}"
- if [[ "$COMMIT_MESSAGE" =~ ^\[WM\] ]]; then
- echo "Commit message starts with '[WM]', skipping push to Windmill to avoid overwriting deploy that immediately follows it"
- echo "skip=skip" >> $GITHUB_OUTPUT
- fi
-
- # (push will pull first to detect conflicts and only push actual changes)
- - name: Push changes
- if: steps.check_message.outputs.skip != 'skip'
- run: |
- npm install -g windmill-cli@1.393.3
- wmill sync push --yes --skip-variables --skip-secrets --skip-resources --workspace ${{ steps.workspace.outputs.workspace }} --token ${{ secrets.WMILL_TOKEN }} --base-url ${{ env.WMILL_URL }}
-
````
@@ -298,11 +119,13 @@ uses: actions/checkout@v3
You are now ready to test the workflow. You can do so by:
1. Create and deploy a new script in the staging workspace, give it a path within the allowed [filters](../11_git_sync/index.mdx#path-filters).
-2. Verify in the GitHub action run that the sync push has been able to push the change to the staging workspace (or the prod workspace if you have not set up a staging workspace).
-3. Check the target workspace in Windmill if the script has been deployed.
-4. Go to the runs page, toggle the "Sync" kind of jobs. You should see at least 2 jobs, one to push back your change to the staging (if set) workspace (no-op), and one to create a branch that targets the main branch (the one that will be merged).
-5. Now in your repository, you should see a new branch named wm_deploy/[WORKSPACE_NAME]/[SCRIPT_PATH] (for instance wm_deploy/staging/f/example/script).
-6. Merge that branch, now the changes should trigger the "Deploy to prod" GitHub action in the main branch.
+2. Check if a PR was created on GitHub to merge wm_deploy/[WORKSPACE_NAME]/[SCRIPT_PATH] into the production branch.
+3. Merge the PR and check the production workspace. The new script should be now there.
+
+
+If you have issues you can try the following:
+- To see the sync job if you need to debug, go to the runs page and select the "Sync" filter. Git sync jobs should appear there.
+- Check the GitHub action runs to see if they were succesful
## Managing multiple teams and folders
diff --git a/sidebars.js b/sidebars.js
index b7a802272..20b316896 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -939,11 +939,6 @@ const sidebars = {
label: 'Git sync'
},
'advanced/git_sync/cli_sync',
- {
- type: 'doc',
- id: 'advanced/workspace_forks/index',
- label: 'Workspace forks'
- },
{
type: 'doc',
id: 'core_concepts/versioning/index',
@@ -961,6 +956,7 @@ const sidebars = {
},
items: [
'core_concepts/draft_and_deploy/index',
+ 'advanced/workspace_forks/index',
'advanced/deploy_gh_gl/index',
'core_concepts/staging_prod/index'
],
diff --git a/static/videos/merge-ui-demo.mp4 b/static/videos/merge-ui-demo.mp4
new file mode 100644
index 000000000..cf6540ae6
Binary files /dev/null and b/static/videos/merge-ui-demo.mp4 differ