Git flow workflow component
The component configures the project to encourage squash commits while still allowing merge requests to preserve their individual commits.
Configure GITLAB_TOKEN with a group service account before allowing the component to update project settings.
Usage
- Ensure your projects have a description
- Set
GITLAB_TOKENas a masked, protected and hidden variable for your group - Create and protect your
mainanddevelopbranches - Create GitLab pipeline file
.gitlab-ci.yml:
Set branch-name-rule to a GitLab RE2 regular expression to reject new branch
names that do not match your convention. The default empty value leaves an
existing project push rule unchanged. Project push rules require GitLab Premium
or Ultimate.
Use branch-rules to configure protected branches, access levels, and regular
approval rules. Each entry requires branch, allowed-to-merge, and
allowed-to-push. Add approvers to select GitLab usernames, group paths that
start with /, or the role tokens @@guest, @@reporter, @@developer,
@@maintainer, and @@owner. An omitted or empty approvers array selects all
project Maintainers and Owners. A wildcard branch such as renovate/* creates
an approval rule named renovate.
Use GitLab access level 0 for no access, 30 for Developer, or 40 for
Maintainer. Level 60 is available to Administrators on self-managed GitLab.
Force pushes are disabled for every configured rule. By default, Maintainers
can merge into main, direct pushes to main are disabled, and Developers can
push to develop.
When a configured branch contains CODEOWNERS, the component enables Code
Owner approval and keeps the regular approval rule. A merge request must satisfy
both policies. The component also enables automatic Code Owner reviewer
assignment when the GitLab API supports it.
When multiple approval rules are unavailable, GitLab exposes only one
user-defined rule. The component reuses that rule for develop only if it
already applies project-wide, requires at least one approval, and has exactly
the requested users and groups. It does not delete hidden rules or weaken the
visible policy. A non-equivalent rule or an unverifiable capability fails
configuration with an actionable diagnostic. Capability verification uses
GitLab's licensedFeatureAvailability GraphQL field (GitLab 18.11 or later).
API permission failures remain errors; a successful configuration does not
change which approval features the project's subscription enforces.
include:
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/codeowners@stable
inputs:
codeowners: |
[Default]
* @@maintainer @@owner
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/workflow-gitflow@stable
inputs:
branch-name-rule: '^(main|master|develop|(feature|feat|bugfix|fix|hotfix|release|chore|ai|copilot|cursor|claude|codex)/[a-z0-9]+(\.[a-z0-9]+)*(-[a-z0-9]+(\.[a-z0-9]+)*)*)$'
branch-rules:
- branch: main
allowed-to-merge: 40
allowed-to-push: 0
approvers:
- alice
- /root-group/reviewers
- "@@owner"
- branch: develop
allowed-to-merge: 40
allowed-to-push: 30
approvers:
- "@@maintainer"
- "@@owner"
The example follows the Conventional Branch formal grammar.
Merge validation
validate:gitflow runs in merge request pipelines targeting the default branch,
including merged-results and merge-train pipelines. It is independent of
autoconfigure-enabled and the project-configuration rules input. Feature
merges into the development branch and ordinary branch/tag pipelines are not
subject to this validation.
Disable Squash commits when merge request is accepted for these release
merges. The source must match development-branch (default develop). GitLab
sets CI_MERGE_REQUEST_SQUASH_ON_MERGE to true when squashing is enabled;
an unset or false value represents disabled squashing.
Emergency fixes require both controls:
- Component input
hotfix:reject(default) oraccept. - Pipeline variable
CI_WORKFLOW_GITFLOW_HOTFIX: dropdown optionsreject(default) andaccept.
Set hotfix: accept in the component inputs and explicitly pass
CI_WORKFLOW_GITFLOW_HOTFIX=accept to the merge request pipeline to allow a
source other than the development branch. Neither setting alone permits this.
The dropdown is exposed on GitLab's New pipeline form; a branch pipeline is not
a substitute for the required MR pipeline. Accepted emergency fixes may enable
squash-on-merge; development-branch release merges must leave it disabled.
Rerun the MR pipeline after changing its squash setting.
Branching
Roles
The following roles exist in the scenarios:
- Developer
- Creates the respective hot fix, bug fix, or feature branch
- Implements the respective functionality (=gets hands dirty)
- Pushes source code to the work branch created above
- Creates a merge request to the corresponding target branch after successful local testing (see workflow)
- Maintainer (=Team colleague)
- Reviews merge requests
- Decides whether a merge request should trigger a release
- Merges the merge request (see workflow)
Settings enabled by default
- Create development branch if it does not exist
- Protect
mainanddevelopwith the configured merge and push access levels - Disable force pushes on protected branches
- Branch rules
- fast forward merge
- Pipelines must succeed before merge
- Merged results pipelines
- Skipped pipelines are considered successful
- All discussions must be resolved
- Allow merge request authors and committers to approve when at most three active human Maintainers and Owners can approve. Prevent both approval types for larger teams.
- Remove all approvals when commits are added
- Prevent editing approval rules in merge requests
- Create a regular one-approval rule for each configured branch and assign its configured approvers, or all Maintainers and Owners when none are listed.
- With a
CODEOWNERSfile, also require Code Owner approval and automatically assign matching Code Owners when the GitLab API supports it. - Merge request branch workflow
- Merge request branch workflow:
-
- feat/* -> develop
-
- fix/* -> develop
-
- hotfix/* -> main
Inputs
| Name | Description | Default | Type |
| --- | --- | --- | --- |
| autoconfigure-enabled | Enable or disable the automatic configuration of the pipeline. | true | boolean |
| branch-name-rule | RE2 regular expression that every new branch name must match. An empty value leaves the project push rule unchanged. | string | |
| branch-rules | Protected branch and approval rules. Each rule can assign approvers by username, /group path, or @@role. Access levels are 0 (no access), 30 (Developer), 40 (Maintainer), or 60 (Administrator on self-managed GitLab). | [{"branch":"main","allowed-to-merge":40,"allowed-to-push":0},{"branch":"develop","allowed-to-merge":40,"allowed-to-push":30}] | array |
| development-branch | The name of the development branch. | develop | string |
| hotfix | Permit an explicitly requested hotfix to bypass the development-branch requirement. | reject | string |
| pattern-branch-interruptible | Regex pattern to mark the pipeline as interruptible based on the branch name. Use https://github.com/google/re2/wiki/Syntax | /^(feat|fix|hotfix)\// | string |
| pattern-branch-skip | Regex pattern to skip the pipeline based on the branch name. Use https://github.com/google/re2/wiki/Syntax | string | |
| rules | The jobs that this job depends on. | [{"if":"$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH","when":"always"},{"when":"never"}] | array |