Skip to main content

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_TOKEN as a masked, protected and hidden variable for your group
  • Create and protect your main and develop branches
  • 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) or accept.
  • Pipeline variable CI_WORKFLOW_GITFLOW_HOTFIX: dropdown options reject (default) and accept.

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 main and develop with 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 CODEOWNERS file, 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​

NameDescriptionDefaultType
------------
autoconfigure-enabledEnable or disable the automatic configuration of the pipeline.trueboolean
branch-name-ruleRE2 regular expression that every new branch name must match. An empty value leaves the project push rule unchanged.string
branch-rulesProtected 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-branchThe name of the development branch.developstring
hotfixPermit an explicitly requested hotfix to bypass the development-branch requirement.rejectstring
pattern-branch-interruptibleRegex 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-skipRegex pattern to skip the pipeline based on the branch name. Use https://github.com/google/re2/wiki/Syntaxstring
rulesThe jobs that this job depends on.[{"if":"$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH","when":"always"},{"when":"never"}]array