top of page

My New Monorepo GitOps Workflow

Mar 25

2 min read

The Problem with My Old Workflow

For years, I've been using a GitFlow-inspired workflow with environment-specific branches that trigger deployments on pushes. This approach has some advantages - particularly being able to easily check out what's on any environment for local testing. The main branch is always synced with the production environment.


However, this workflow has created several headaches:

  • Managing multiple environment branches alongside a GitFlow integration branch leads to merge conflicts

  • Relying on fast-forward merges (making branches function more like tags) to keep things clean

  • GitHub's prevention of fast-forward merges in PRs breaks this workflow - deploying to production creates a new commit hash that must be merged back to the integration branch


The move to monorepos has magnified these problems. In our early monorepo setups, we triggered deploys on merges to deployment branches by using git inspection to determine what changed. This resulted in:

  • More severe merge conflicts

  • Unpredictable deployments

  • Inadvertently coupled deploys between applications


A Better Git Workflow for Monorepo CI/CD


GitHub Flow keeps PRs small by focusing on the main branch
GitHub Flow keeps PRs small by focusing on the main branch

After experiencing these pain points firsthand, I'm proposing a simpler, more robust workflow inspired by GitHub Flow:

  1. Feature branches start from main and merge back to main when complete

  2. Merges to main automatically deploy to dev environments

  3. A single, shared GitHub Action creates releases that takes the specific app name as an input

  4. Creating an app-specific release triggers production deployment only for that app

  5. Manual deployments remain available via GitHub Actions for any environment when needed



Each app gets its own release cycle
Each app gets its own release cycle

Important to note: This workflow doesn't use a unified integration branch across all monorepo applications. Each app within the monorepo can maintain its own integration branch if its team prefers that approach. Despite sharing the same release action, each application maintains its own release namespace and deployment triggers, ensuring that apps can be deployed independently despite living in the same repository.


This approach eliminates environment branches entirely, simplifying our git history while providing clearer deployment triggers and better separation between environments.


What git workflow has worked best for your teams, especially when working with monorepos?


PS: Of course we need to hotfix things sometimes. Here's a flowchart for hotfixes:



Comments

Share Your ThoughtsBe the first to write a comment.
bottom of page