Turnkey GitLab Flow implementation for CI/CD and branching strategy

Are releases stalled by branch confusion and manual merges? We implement GitLab Flow turnkey: we define the branching strategy, configure automated release deployment and branch protection. Deployment speeds up significantly, merge conflicts disappear, and recovery from failure takes minutes.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

GitLab Flow Doesn't Stick: Where Release Deployment Breaks

GitLab Flow works while branches live for days.

As soon as develop, parallel release/*, and a couple of urgent fixes appear alongside, the branching strategy starts to diverge: the same logic is edited in three places, and merge conflicts stop being mechanical—code is merged by hand, file by file.

What is expensive here is not the merging itself, but the loss of confidence. A change that has already passed verification in the main branch has to be manually transferred to the release branch, and no one can guarantee that exactly the same thing was transferred.

The broken release cycle manifests later: a fix is present in one branch and absent in another, and this is discovered in an environment where rollback is more expensive than the fix itself.

Long-lived branches add a third problem—a person. The pipeline builds and checks code, but the order of merges and release composition rests on one engineer who remembers branch history. While he is available, releases proceed; on vacation or on another task, deployment stops entirely.

The typical cause is not the tool, but the absence of agreements: it is not defined which branch is considered the source of release, how the branch and version tag are related, what happens to a fix after release. We explain how this is addressed.

What Changes After Moving Releases to a Single Strategy

A single strategy starts with short-lived task branches: changes enter the main branch only through a merge request with mandatory checks.

Build and tests start on every commit, not on a release tag, so the time for a change to reach the working environment drops from days to hours.

The share of automated checks becomes measurable: static analysis, unit and integration tests, migration checks, and artifact build run in a single pipeline and block merging if they fail. Manual operations are reduced to confirming deployment to the production environment.

GitLab Flow adds environment branches: a change passes sequentially through test, pre-production, and production environments, and at each step it is visible which commit is where.

Rollback is a return to the previous tag with an already built artifact, so recovery time is measured in minutes, not in searching for the offending change.

Deployment frequency grows not because someone presses buttons faster: the version is built once and promoted between environments without rebuilding. A release stops being an event with night on-call and a manual checklist.

A separate class of failures related to configuration drift between environments and "in-place" edits goes away—environments are described as code and reproduced identically.

This is visible in metrics: the share of changes reaching the production environment without rollback grows, and incidents due to human error become fewer.

GitLab Flow, trunk-based, and release branches: comparing modes

The branching mode is chosen by three parameters: how many versions are in production, how often changes are released, and how many people edit the same code. Below is a comparison of branching approaches with their limitations by team composition and release frequency.

Mode When It Fits Limitations
Trunk-based: commits to the main branch, short-lived task branches live for hours One version in production, releases several times a day, critical paths covered by automated tests Without checks on every commit, the main branch breaks; manual acceptance slows the flow; supporting an old version is only possible via a branch from the tag
GitLab Flow with environment branches: main → pre-production → production Multiple verification environments, release once every one to two weeks Delay between merge and release; a fix must be applied across all environments in sequence; more manual operations at deployment
Release branches: main plus a branch per version Several supported versions, deliveries to customer sites, long acceptance Every fix must be transferred to the main branch and to the other releases, otherwise branches diverge; maintenance becomes more expensive with more versions
Hybrid: trunk-based plus a release branch during freeze Fast main flow and a stable cut for long acceptance A policy is needed: who creates the branch and how fixes are transferred, otherwise the cut diverges from the main branch

We usually start with trunk-based and add a release branch only when a second supported version appears. Transition in either direction is reversible: branch protection rules and mandatory checks are described by configuration.

Implementation Order: From Inventory to Handover

Implementing GitLab Flow is a sequence where each step relies on the result of the previous one. If you skip repository inventory and immediately configure protection, the rules are laid over branch chaos and break team work on the very first day.

  1. Repository inventory. We collect a list of projects, owners, long-lived branches, and current build configurations. Separately, we record where access is over-provisioned and where the build does not start at all.
  2. Branching scheme design. We leave one long-lived trunk, define naming rules for working branches, the order of moving changes between environments, and how release branches are handled.
  3. Branch protection setup. We enable a ban on direct pushes to the trunk, mandatory review, the requirement of a successful build, and restrict the circle of people with merge rights. We describe the rules in a configuration file—they are versioned together with the code.
  4. Test environment setup. We deploy an environment where each set of changes passes checks and tests and is deployed in an isolated environment before reaching the trunk.
  5. Merge verification on real tasks. We run working changes through the new rules: we look at where blocking occurs, how long verification takes, and whether there are false rejections.
  6. Trial run and training. We show teams the new order on their tasks, walk through common situations—conflict in the trunk, rollback, urgent fix.
  7. Handover. We hand over build file templates, the branching scheme, the on-call policy, and instructions for adding a new project.

Turnkey implementation ends not with a report, but with the team adding a new repository using a ready template without engineers' involvement—and getting the same checks automatically.

Artifacts: Branching Schemes, Access Policies, Procedures

After implementation, the team is left not only with working build pipelines, but also with artifacts that allow the process to be handed over further without us. All of them live in the repository itself next to the code—not in chats or in someone else's head.

  • Branching scheme — which branches are permanent (main, release branches, environment branches), which are short-lived, where an urgent fix goes, and how a branch relates to an environment in GitLab Flow logic.
  • Access policies — roles and rights: who pushes to protected branches, who approves merges, who changes build settings and environment variables.
  • Mandatory checks — what blocks merging and what only warns: build, tests, linters, dependency analysis, manual approval for the release branch.
  • Rollback procedure — step-by-step order for returning to the previous release: which artifact is reused, whether a revert commit is needed, who makes the decision and within what timeframe.
  • Release order — how the version tag is formed, how the branch, build, and artifact are related, who releases a change to production and when.
  • Secrets and variables map — where keys are stored, who owns access to each environment, how rotation works when an engineer changes.
  • Process documentation — a short onboarding in the repository: how to bring up the environment, how to release a change, whom to ask a question.

We discuss each point with the team on a live scenario—release, rollback, merging someone else's branch—so that the procedure does not diverge from real practice a month after handover.

Case: How Recovery Time and the Number of Conflicts Were Reduced

The project came to us with several years of history: a main branch, a release branch, and a set of long-lived branches by area. Over that time, they had diverged so much that each release build turned into a separate day of manually sorting out discrepancies.

There were no fixed naming or branch lifetime rules, so the same fix was often made in three places independently.

Where We Started

We captured metrics over several release cycles so that later we could speak in numbers, not impressions. Fewer than half of changes reached release without manual edits—the rest had to be fixed right during merging.

The number of conflicts per release stayed around 12–15, and preparing a fix for an already released version took from six hours to two days: the engineer searched for which branch contained the needed code and where to move it.

What We Changed and What We Got

We moved to GitLab Flow: one main branch and short-lived task branches, protection of the main branch from direct commits, mandatory pipeline checks before merging. Changes went in one direction—from main to release, not the other way around—and each release is tagged.

The share of changes reaching release without manual edits grew to 92%, and the number of conflicts per release dropped to 1–2. Preparing a fix was reduced to 40–60 minutes, because rollback and transfer are now done by tag, not by searching through branches.

What to Do If Another Process Is Already Deployed in the Project?

The transition does not begin with rewriting history—first comes inventory: in each repository we look at branch protection rules, mandatory checks, where keys and build artifacts are stored.

Some checks are usually configured manually and described nowhere, and it is precisely they that determine whether we can move forward without surprises.

Then we migrate repositories one at a time, not all at once. The old scheme continues to work: releases go out from old branches, while the new build runs in parallel on the same changes and only reports discrepancies. Until mandatory checks align, they do not prohibit merging—first a warning, then blocking.

Accumulated branch discrepancies are aligned through a common merge point: we fix the base, move changes on top of it, and establish the order of their appearance in the main branch. The history remains readable, and returning to the previous state remains possible.

If there are several repositories, we keep a single template for check configuration and branching rules and roll it out in waves: first one service, then the rest.

Different schemes in different repositories live in parallel until the last one moves to the common one—releases do not stop.

Rollback at any step is restoring the branch protection rule and the previous set of checks: it takes minutes and does not require rebuilding artifacts. This order allows changing the process on a live system without freezing delivery.

Technical Doubts: Limitations, Checks, Branch Protection

A branching scheme is a set of rules in repository settings, not an agreement in the responsible person's head.

Below are answers to objections most often checked before starting: does the scheme fit current tools, which checks will become mandatory, and who will get the right to change protected branches.

We already have pipelines working—will everything have to be rewritten?

No. Existing build and test stages are transferred almost as is: the list of trigger branches and launch conditions changes.

If the configuration is declarative, the adjustment comes down to the rule “checks in the merge request, artifact build and deployment in the release branch.”

Will mandatory checks slow the team down?

We make mandatory only those that catch errors invisible during review: build, tests on affected modules, absence of conflicts. We leave long integration suites and style checks optional—otherwise an urgent fix will queue up. Time to merge usually does not grow; time to detect a defect shrinks.

Who will be able to push to the main and release branches?

Role rights are separated by levels: a developer works in their own branch, merge approval belongs to the maintainer, the release branch is closed to direct pushes for everyone, including administrators. Any weakening of a rule goes into the log, so a “temporary” exception does not become permanent.

What limitations does the scheme itself have?

The scheme does not fix weak tests and does not replace review—it sets the route of a change from branch to release and makes it verifiable. If the team has no review practice, the scheme will show it rather than hide it.

It also does not cover manual steps outside the repository: we move them into the pipeline as a separate task.

Let's Discuss Your Branching Scheme and Release Cycle

The first step is a 40–60 minute conversation with the engineer who maintains your repositories: they will show where it hurts now faster than any document. To avoid clarifying things in circles, prepare inputs on your infrastructure.

  • Branching scheme: how many branches are in permanent use, who merges changes and by what rule.
  • Release cycle: how often you deploy, who decides about release, whether there is a maintenance branch for previous versions.
  • Pre-merge checks: what runs automatically, what is done manually, and where it breaks most often.
  • Environments and access: how many there are, how they differ, how rights are granted, whether there are restrictions on external connections.
  • Artifacts and rollback: where builds are stored, how many versions you keep, how quickly you roll back.
  • Responsible people: who approves the rules and who is on call for night releases.

In response, we return with an estimate and a plan: a map of the target GitLab Flow scheme for your processes, branch protection rules, the order for migrating current repositories, and automation stages. For each point, it is clear what we do and what remains on your side.

Describe the task in two or three paragraphs and attach your current repository settings—that is enough to discuss the task and come back with an estimate and a plan.