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 Type | Pattern | Purpose | Lifetime |
|---|---|---|---|
| Main | main | Production releases | Permanent |
| Release | release/v0.X.x | Minor version series | Long-lived |
| Feature | {iid}-{slug} | Issue-driven work | Temporary |
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
.xindicates 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:
- Analyzes commits
- Calculates next patch version
- Creates git tag (e.g.,
v0.3.5) - Generates changelog
- 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:
- Extract branch version:
release/v0.3.x0.3 - Find latest tag:
git tag -l "v0.3.*" --sort=-v:refname | head -n 1 - Increment patch:
v0.3.4v0.3.5 - Create new tag:
v0.3.5
Manual vs Automatic
| Aspect | Manual | Automatic (Agent Platform) |
|---|---|---|
| Patch version | Developer decides | CI auto-increments |
| Minor version | Developer decides | Release branch name |
| Major version | Developer decides | Release branch name |
| Changelog | Written by hand | Auto-generated |
| Git tags | Created manually | CI creates |
| Releases | Published manually | CI 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
| Milestone | Target Branch | Released Versions |
|---|---|---|
v0.1.x | release/v0.1.x | v0.1.0, v0.1.1, v0.1.2... |
v0.2.x | release/v0.2.x | v0.2.0, v0.2.1, v0.2.2... |
v0.3.x | release/v0.3.x | v0.3.0, v0.3.1, v0.3.2... |
v1.0.x | release/v1.0.x | v1.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 Status | Support Level | Updates |
|---|---|---|
| Current | Full support | Features + fixes |
| Previous | Security only | Security patches |
| Older | EOL | None (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
-
Create release branches from main
git checkout main git pull origin main git checkout -b release/v0.3.x -
Use consistent naming
- Always:
release/v{MAJOR}.{MINOR}.x - Never:
release-v0.3,v0.3.x,0.3.x
- Always:
-
Match milestones to branches
- Milestone:
v0.3.x - Branch:
release/v0.3.x
- Milestone:
-
Protect release branches
- Require MRs for all changes
- Require CI/CD to pass
- Require approvals
-
Upstream-first for hotfixes
- Fix in latest release branch first
- Backport to older branches if needed
-
Document release notes
- Auto-generate from commits
- Highlight breaking changes
- Include migration guide
DON'T
-
Don't commit directly to release branches
- Always use MRs
- Always get approval
-
Don't create arbitrary branches
- Follow naming convention
- Don't use custom formats
-
Don't skip versions
- Let CI auto-increment
- Don't manually create tags
-
Don't backport features
- Only security and critical fixes
- Features go to next version
-
Don't merge backwards
- Don't merge newer release to older
- Only cherry-pick specific commits
-
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