Skip to main content

release branches

Release Branch Strategy

Overview

The Agent Platform uses a release branch model with automatic patch versioning. This strategy provides long-lived release branches for each minor version series, enabling parallel development, hotfixes, and controlled releases.

Branch Model

main (production releases only)
  
   merge when production-ready
  
release/v0.1.x > v0.1.0, v0.1.1, v0.1.2...
  
  
release/v0.2.x > v0.2.0, v0.2.1, v0.2.2...
  
  
release/v0.3.x > v0.3.0, v0.3.1, v0.3.2...
  
  
106-issue-slug (feature branches)

Branch Types

Branch TypePatternPurposeLifetime
MainmainProduction releasesPermanent
Releaserelease/v0.X.xMinor version seriesLong-lived
Feature{iid}-{slug}Issue-driven workTemporary

Release Branch Lifecycle

1. Creation

Release branches are created when starting a new minor version series.

# Create new release branch from main git checkout main git pull origin main git checkout -b release/v0.3.x git push origin release/v0.3.x # Create corresponding milestone glab milestone create v0.3.x \ --title "v0.3.x Release Series" \ --description "Release branch for v0.3.x series" \ --group blueflyio/agent-platform

Naming Convention:

  • Format: release/v{MAJOR}.{MINOR}.x
  • Examples: release/v0.1.x, release/v0.2.x, release/v1.0.x
  • The .x indicates all patch versions

2. Development

Feature branches are created from issues and target the appropriate release branch.

# GitLab creates branch from issue: 106-add-oauth2-support # Developer works in worktree cd .worktrees/2026-01-08/openstandardagents/106-add-oauth2-support/ # Make changes git add . git commit -m "feat: add OAuth2 authentication support" git push origin 106-add-oauth2-support # Create MR targeting release/v0.3.x glab mr create \ --title "Add OAuth2 authentication" \ --target-branch release/v0.3.x \ --milestone v0.3.x

3. Merging

When MR merges to release branch, CI automatically:

  1. Analyzes commits
  2. Calculates next patch version
  3. Creates git tag (e.g., v0.3.5)
  4. Generates changelog
  5. Creates GitLab release
# Automatic on merge to release/v0.X.x v0.3.4 (existing) > merge MR CI runs v0.3.5 (new tag)

4. Promotion to Main

Release branches are merged to main when production-ready.

# Merge release branch to main git checkout main git pull origin main git merge --no-ff release/v0.3.x -m "chore: merge release/v0.3.x to main" git push origin main

Note: Only merge to main for production releases, not after every MR.

5. Maintenance

Release branches continue to receive:

  • Bug fixes (patch versions)
  • Security updates (patch versions)
  • Hotfixes (patch versions)

No new features after release branch is merged to main.

Version Numbering

Automatic Patch Incrementing

CI/CD automatically determines the next patch version:

release/v0.3.x branch:

First MR merge:  v0.3.0
Second MR merge: v0.3.1
Third MR merge:  v0.3.2
...

Algorithm:

  1. Extract branch version: release/v0.3.x 0.3
  2. Find latest tag: git tag -l "v0.3.*" --sort=-v:refname | head -n 1
  3. Increment patch: v0.3.4 v0.3.5
  4. Create new tag: v0.3.5

Manual vs Automatic

AspectManualAutomatic (Agent Platform)
Patch versionDeveloper decidesCI auto-increments
Minor versionDeveloper decidesRelease branch name
Major versionDeveloper decidesRelease branch name
ChangelogWritten by handAuto-generated
Git tagsCreated manuallyCI creates
ReleasesPublished manuallyCI publishes

Milestone Integration

Group Milestones

The Agent Platform uses group milestones for version tracking:

Group: blueflyio/agent-platform
Milestones:
  - v0.1.x  (maps to release/v0.1.x)
  - v0.2.x  (maps to release/v0.2.x)
  - v0.3.x  (maps to release/v0.3.x)
  - v1.0.x  (maps to release/v1.0.x)

Milestone-to-Branch Mapping

MilestoneTarget BranchReleased Versions
v0.1.xrelease/v0.1.xv0.1.0, v0.1.1, v0.1.2...
v0.2.xrelease/v0.2.xv0.2.0, v0.2.1, v0.2.2...
v0.3.xrelease/v0.3.xv0.3.0, v0.3.1, v0.3.2...
v1.0.xrelease/v1.0.xv1.0.0, v1.0.1, v1.0.2...

Workflow

# 1. Create issue with milestone glab issue create \ --title "Add OAuth2 support" \ --milestone v0.3.x \ --repo blueflyio/openstandardagents # 2. GitLab creates branch: 106-add-oauth2-support # 3. Create MR targeting matching release branch glab mr create \ --title "Add OAuth2 support" \ --target-branch release/v0.3.x \ --milestone v0.3.x # 4. On merge: CI creates v0.3.X tag automatically

Hotfix Workflow

Upstream-First Policy

All hotfixes must be merged to the most recent release branch first, then backported if needed.

Hotfix discovered in production (v0.2.5):

1. Create fix on latest release branch (release/v0.3.x)
2. Merge to release/v0.3.x  creates v0.3.6
3. Test thoroughly
4. Backport to release/v0.2.x  creates v0.2.6 (if needed)
5. Deploy v0.2.6 to production

Hotfix Process

Step 1: Create Hotfix Issue

# Create issue with appropriate milestone glab issue create \ --title "Critical: Fix authentication bypass" \ --label "security,hotfix" \ --milestone v0.3.x \ --assignee @me

Step 2: Develop Fix on Latest Release Branch

# GitLab creates branch from issue: 150-fix-auth-bypass # Setup worktree DATE=$(date +%Y-%m-%d) WORKTREE_PATH="/Users/thomas.scola/Sites/Agent-platform/.worktrees/$DATE/openstandardagents/150-fix-auth-bypass" cd /Users/thomas.scola/Sites/Agent-platform/_Source/openstandardagents git fetch origin 150-fix-auth-bypass git worktree add "$WORKTREE_PATH" 150-fix-auth-bypass # Develop fix cd "$WORKTREE_PATH" # ... make changes ... git commit -m "fix: resolve authentication bypass vulnerability" git push origin 150-fix-auth-bypass

Step 3: Merge to Latest Release Branch

# Create MR targeting latest release branch glab mr create \ --title "Fix authentication bypass" \ --target-branch release/v0.3.x \ --milestone v0.3.x \ --label "security,hotfix" # After merge: CI creates v0.3.6

Step 4: Backport (if needed)

# Cherry-pick to older release branch git checkout release/v0.2.x git cherry-pick <commit-hash> git push origin release/v0.2.x # CI creates v0.2.6

Emergency Hotfix

For critical production issues requiring immediate fix:

# 1. Create hotfix branch from production tag git checkout v0.2.5 git checkout -b hotfix/v0.2.6-auth-bypass # 2. Fix the issue git commit -m "fix: resolve authentication bypass" # 3. Merge to release/v0.2.x git checkout release/v0.2.x git merge --no-ff hotfix/v0.2.6-auth-bypass git push origin release/v0.2.x # 4. CI creates v0.2.6 # 5. IMPORTANT: Merge up to latest release branch git checkout release/v0.3.x git merge --no-ff release/v0.2.x git push origin release/v0.3.x # 6. Clean up hotfix branch git branch -d hotfix/v0.2.6-auth-bypass

Backporting

When to Backport

Backport fixes to older release branches only when:

  • Security vulnerabilities
  • Critical production bugs
  • Customer explicitly requires it
  • Regression introduced in older version

DO NOT backport:

  • New features
  • Non-critical bug fixes
  • Refactoring
  • Documentation updates

Backporting Process

Manual Cherry-Pick

# 1. Identify commit to backport COMMIT_HASH="abc123def456" # 2. Checkout target release branch git checkout release/v0.2.x git pull origin release/v0.2.x # 3. Cherry-pick the commit git cherry-pick $COMMIT_HASH # 4. Resolve conflicts if any git status # ... resolve conflicts ... git cherry-pick --continue # 5. Push to trigger release git push origin release/v0.2.x # CI creates v0.2.7

Using GitLab MR

# 1. Create new branch from older release branch git checkout release/v0.2.x git pull origin release/v0.2.x git checkout -b backport-150-to-v0.2.x # 2. Cherry-pick commit git cherry-pick <commit-hash> # 3. Push and create MR git push origin backport-150-to-v0.2.x glab mr create \ --title "Backport: Fix authentication bypass to v0.2.x" \ --target-branch release/v0.2.x \ --milestone v0.2.x \ --label "backport"

Backport Validation

# .gitlab-ci.yml validate-backport: stage: validate script: - | # Check if MR is labeled as backport if echo "$CI_MERGE_REQUEST_LABELS" | grep -q "backport"; then # Ensure commit already exists in newer release branch TARGET_BRANCH=$CI_MERGE_REQUEST_TARGET_BRANCH_NAME COMMITS=$(git log --format=%H origin/$TARGET_BRANCH..HEAD) for commit in $COMMITS; do # Check if commit exists in newer branches NEWER_BRANCHES=$(git branch -r | grep "origin/release" | sort -V | awk -v target="$TARGET_BRANCH" '$0 > target') FOUND=0 for branch in $NEWER_BRANCHES; do if git log $branch --format=%B | grep -F "$(git log --format=%B -n 1 $commit)"; then FOUND=1 break fi done if [ $FOUND -eq 0 ]; then echo "ERROR: Commit $commit not found in newer release branches" echo "Backports must be applied to latest release first (upstream-first policy)" exit 1 fi done fi only: - merge_requests

Parallel Development

Supporting Multiple Versions

The Agent Platform may maintain multiple active release branches:

release/v0.2.x  v0.2.5, v0.2.6... (security fixes only)
release/v0.3.x  v0.3.0, v0.3.1... (active development)
release/v0.4.x  v0.4.0-alpha...   (next version)

Feature Development

# Current stable: v0.3.x # Next version: v0.4.x # Create new release branch for v0.4.x git checkout main git checkout -b release/v0.4.x git push origin release/v0.4.x # Create group milestone glab milestone create v0.4.x --group blueflyio/agent-platform # Target new features to v0.4.x glab issue create \ --title "Add Kubernetes operator" \ --milestone v0.4.x

Version Support Policy

Version StatusSupport LevelUpdates
CurrentFull supportFeatures + fixes
PreviousSecurity onlySecurity patches
OlderEOLNone (by exception only)

Example:

v0.3.x  Current (active development)
v0.2.x  Previous (security fixes only)
v0.1.x  EOL (no updates)

CI/CD Integration

Release Branch Detection

# .gitlab-ci.yml variables: # Detect if current branch is a release branch IS_RELEASE_BRANCH: | if echo "$CI_COMMIT_REF_NAME" | grep -E '^release/v[0-9]+\.[0-9]+\.x$'; then echo "true" else echo "false" fi # Only run on release branches auto-release: stage: release script: - echo "Creating release..." only: - /^release\/v[0-9]+\.[0-9]+\.x$/

Version Calculation

calculate-version: stage: version image: alpine/git script: - | # Extract version from branch name BRANCH_VERSION=$(echo $CI_COMMIT_REF_NAME | sed 's/release\/v\([0-9]*\.[0-9]*\)\.x/\1/') echo "Branch version: $BRANCH_VERSION" # Get latest tag for this release branch LATEST_TAG=$(git tag -l "v${BRANCH_VERSION}.*" --sort=-v:refname | head -n 1) echo "Latest tag: ${LATEST_TAG:-none}" # Calculate next version if [ -z "$LATEST_TAG" ]; then NEXT_VERSION="v${BRANCH_VERSION}.0" else PATCH=$(echo $LATEST_TAG | awk -F. '{print $NF}') NEXT_PATCH=$((PATCH + 1)) NEXT_VERSION="v${BRANCH_VERSION}.${NEXT_PATCH}" fi echo "Next version: $NEXT_VERSION" echo "NEXT_VERSION=$NEXT_VERSION" >> version.env artifacts: reports: dotenv: version.env only: - /^release\/v[0-9]+\.[0-9]+\.x$/

Protected Branches

Configure in GitLab: Settings Repository Protected Branches

Branch: release/v*
Allowed to merge: Maintainers
Allowed to push: No one
Allowed to force push: No

Enforce via CI/CD:

protect-release-branches: stage: validate script: - | if echo "$CI_COMMIT_REF_NAME" | grep -E '^release/v[0-9]+\.[0-9]+\.x$'; then if [ "$CI_PIPELINE_SOURCE" != "merge_request_event" ]; then echo "ERROR: Direct pushes to release branches are not allowed" echo "Please create a merge request" exit 1 fi fi except: - merge_requests

Release Branch Best Practices

DO

  1. Create release branches from main

    git checkout main git pull origin main git checkout -b release/v0.3.x
  2. Use consistent naming

    • Always: release/v{MAJOR}.{MINOR}.x
    • Never: release-v0.3, v0.3.x, 0.3.x
  3. Match milestones to branches

    • Milestone: v0.3.x
    • Branch: release/v0.3.x
  4. Protect release branches

    • Require MRs for all changes
    • Require CI/CD to pass
    • Require approvals
  5. Upstream-first for hotfixes

    • Fix in latest release branch first
    • Backport to older branches if needed
  6. Document release notes

    • Auto-generate from commits
    • Highlight breaking changes
    • Include migration guide

DON'T

  1. Don't commit directly to release branches

    • Always use MRs
    • Always get approval
  2. Don't create arbitrary branches

    • Follow naming convention
    • Don't use custom formats
  3. Don't skip versions

    • Let CI auto-increment
    • Don't manually create tags
  4. Don't backport features

    • Only security and critical fixes
    • Features go to next version
  5. Don't merge backwards

    • Don't merge newer release to older
    • Only cherry-pick specific commits
  6. Don't keep stale branches

    • Archive EOL release branches
    • Document support policy

Troubleshooting

Issue: Wrong Target Branch

Problem: MR targets main instead of release/v0.3.x

Solution:

# Change MR target branch glab mr update <MR_ID> --target-branch release/v0.3.x

Issue: Milestone Doesn't Match Branch

Problem: Milestone v0.3.x but targets release/v0.2.x

Solution:

# Update MR milestone and target glab mr update <MR_ID> \ --milestone v0.2.x \ --target-branch release/v0.2.x

Issue: Release Branch Doesn't Exist

Problem: Trying to target release/v0.4.x but branch doesn't exist

Solution:

# Create release branch git checkout main git pull origin main git checkout -b release/v0.4.x git push origin release/v0.4.x # Create milestone glab milestone create v0.4.x --group blueflyio/agent-platform

Issue: Version Collision

Problem: Tag v0.3.5 already exists

Solution: CI should detect and skip or increment. If manual:

# Check existing tags git tag -l "v0.3.*" --sort=-v:refname # CI will create v0.3.6 automatically

Issue: Hotfix Needed in Old Version

Problem: Need to fix v0.1.5 but release/v0.1.x is archived

Solution:

# 1. Request exception from tech lead # 2. Re-activate release branch git checkout release/v0.1.x git pull origin release/v0.1.x # 3. Apply fix git cherry-pick <commit-hash> git push origin release/v0.1.x # 4. Document exception and re-archive after release

Comparison with Other Models

Git Flow

Git Flow:

main  develop  feature branches
           
      release/v1.0  main + develop

Agent Platform:

main  release/v0.3.x  feature branches
          (when ready)
       main

Key Difference: Git Flow uses develop as integration branch. Agent Platform uses release branches directly.

GitHub Flow

GitHub Flow:

main  feature branches  main (via PR)

Agent Platform:

main  release/v0.3.x  feature branches  release/v0.3.x

Key Difference: GitHub Flow has single main branch. Agent Platform has multiple release branches.

GitLab Flow

GitLab Flow (with environment branches):

main  pre-production  production

Agent Platform (release-based):

main  release/v0.3.x  feature branches

Key Difference: GitLab Flow uses environment branches. Agent Platform uses version-based release branches.

Migration Guide

From Git Flow

# 1. Rename develop to release/v0.1.x git checkout develop git branch -m release/v0.1.x git push origin release/v0.1.x git push origin --delete develop # 2. Create milestones glab milestone create v0.1.x --group blueflyio/agent-platform # 3. Update CI/CD to target release branches # Edit .gitlab-ci.yml # 4. Update documentation # Document new workflow

From GitHub Flow

# 1. Create first release branch from main git checkout main git checkout -b release/v0.1.x git push origin release/v0.1.x # 2. Protect main and release branches # Settings Repository Protected Branches # 3. Create milestones glab milestone create v0.1.x --group blueflyio/agent-platform # 4. Update CI/CD # Add auto-versioning pipeline # 5. Retarget open MRs # Update MRs to target release/v0.1.x instead of main

Resources

See Also