Skip to content

Latest commit

Β 

History

History
436 lines (331 loc) Β· 14 KB

rc-release-scripts.md

File metadata and controls

436 lines (331 loc) Β· 14 KB

RC Release Management Scripts

This repository contains automated scripts for managing release candidates (RC) in a hybrid development workflow. The scripts support two distinct lifecycles: Normal Development (hybrid automation) and Hotfix (manual process).

Table of Contents


πŸš€ Normal Development Lifecycle

Starting from production tag creation

πŸ“Š View Interactive Flow Diagram β†’

1. Production Release Milestone

βœ… Production tag created (e.g., v2.11.0) from latest RC
βœ… Production workflow triggers: Deploy + bump main to next minor (2.12.0)
βœ… Main becomes: The starting point for next development cycle

2. New Development Train Starts

πŸ”§ Engineer runs: ../cliq-rc-scripts/cut_rc.sh --version 2.12.0 --replace
πŸ”§ Or grab version from package.json: ../cliq-rc-scripts/cut_rc.sh --version $(node -p "require('./package.json').version") --replace
βœ… New RC created: release/2.12.0-rc.0 (first staging snapshot)
βœ… Staging workflow triggered: RC branch push triggers build and deploy
βœ… Development begins: Feature branches cut from main

3. Active Development Phase

πŸ‘₯ Engineers create: Feature branches from main (feature/EN-1234-cool-thing)
πŸ“ Work flows through: PRs back to main
πŸ”„ Each main merge: Triggers staging workflow β†’ cut_rc.sh --replace (automatic)
πŸ“¦ RC train advances: rc.0 β†’ rc.1 β†’ rc.2... (each deletes previous)
πŸ§ͺ Each RC deployment: Tests the cumulative changes on staging

4. Ready for Next Release

βœ… Latest RC: Contains all merged features (e.g., release/2.12.0-rc.8)
πŸš€ Engineer promotes:

  • ../cliq-rc-scripts/promote_rc.sh β†’ creates v2.12.0 tag and GitHub Release
  • ../cliq-rc-scripts/promote_rc.sh --auto-next-rc β†’ promotes + automatically starts next RC train πŸ“¦ Production deployment: Release triggers production workflow
    πŸ”„ Cycle repeats: Production workflow bumps main to 2.13.0, ready for next development cycle
    πŸ†• Automatic continuation: With --auto-next-rc, the next RC train (release/2.13.0-rc.0) is created automatically

πŸ”§ Hotfix Lifecycle

Starting with cutting hotfix branch

πŸ“Š View Interactive Flow Diagram β†’

1. Production Issue Identified

🚨 Critical bug found in production v2.11.0
πŸ“ Current state: Main is ahead at 2.12.0-rc.5, production is behind

2. Hotfix Branch Creation

πŸ”§ Engineer cuts: git checkout -b hotfix/critical-bug v2.11.0 (from production tag)
πŸ› οΈ Fix applied: Minimal change to address the issue
πŸ“¦ Version bumped: package.json β†’ 2.11.1 (patch increment)

3. Hotfix Release

🏷️ Tag created: v2.11.1 directly from hotfix branch (no RC process)
πŸ“¦ GitHub Release created: Published via gh release create or GitHub UI
πŸš€ Production deploys: Hotfix goes live immediately
βœ… Production workflow: Detects hotfix β†’ deploys only (no main version bump)

4. Integration Back to Main

πŸ“ Engineer creates PR: Merge hotfix/critical-bug β†’ main
πŸ‘€ Team reviews: Visible integration of production fix
βœ… PR merged: Hotfix code now in main alongside ongoing development

5. Staging Picks Up Hotfix

πŸ”„ Staging workflow: Triggered by main merge
πŸ“¦ Continues RC: release/2.12.0-rc.5 β†’ release/2.12.0-rc.6 (now includes hotfix)
πŸ§ͺ Staging testing: Validates hotfix works with new features


🎯 Key Insights

Normal Development:

  • Linear progression: Each cycle builds on the last
  • Predictable: Version bumps and RC creation follow pattern
  • Hybrid automation: First RC after production release is manual, subsequent RCs are automatic via staging workflow
  • Collaborative: Multiple features flow through main

Hotfix Process:

  • Branch from production: Not from main (which may be ahead)
  • Direct tagging: Hotfix is tagged directly (v2.11.1) without RC process
  • Manual integration: Visible via PR process for team awareness
  • Non-disruptive: Doesn't interfere with ongoing development train
  • Eventually consistent: Hotfix gets into next release automatically when merged to main

Scripts Overview

The release management workflow consists of three main scripts that support both normal development and hotfix processes:

  1. cut_rc.sh - Creates or advances release candidate branches
  2. promote_rc.sh - Promotes an RC branch to a production release tag
  3. status_rc.sh - Shows current release state and recommends next actions

These scripts enforce a structured release workflow:

  • Development happens on main
  • Release candidates are cut to release/X.Y.Z-rc.N branches
  • After testing, RCs are promoted to production tags vX.Y.Z
  • Hotfixes branch from production tags and integrate back to main

Setup

Making Scripts Executable

Before you can run these scripts from anywhere in your filesystem, you need to pull down the repo and make them executable:

git clone git@github.com:adsupnow/cliq-rc-scripts.git
chmod +x ../cliq-rc-scripts/scripts/cut_rc.sh
chmod +x ../cliq-rc-scripts/promote_rc.sh  
chmod +x ../cliq-rc-scripts/status_rc.sh

Or to make all scripts in the directory executable at once:

chmod +x ../cliq-rc-scripts/scripts/*.sh

Script Documentation

Used in the staging and prod github actions or by the engineer managing the production release or hotfix.

cut_rc.sh

Purpose: Creates or advances release candidate branches from the main branch.

Usage:

./cut_rc.sh [options]

Key Options:

  • --version X.Y.Z - Force specific target version
  • --bump <patch|minor|major> - Start a new train with semantic version bump
  • --base <ref> - Base ref for cutting RC (default: origin/main)
  • --replace - Delete previous RC branch for the same version
  • --dry-run - Preview actions without making changes

Examples:

# Start new development cycle after production release
./cut_rc.sh --version 2.12.0 --replace

# Continue existing RC train (rc.0 β†’ rc.1 β†’ rc.2...)  
./cut_rc.sh --replace

promote_rc.sh

Purpose: Promotes a tested release candidate branch to a production release tag, with optional automatic creation of the next RC train.

Usage:

./promote_rc.sh [options]

Key Options:

  • --rc <branch> - RC branch to promote (defaults to current branch)
  • --message "<text>" - Custom annotated tag message
  • --auto-next-rc - After promotion, automatically create next RC train from updated main branch
  • --dry-run - Preview actions without making changes

Examples:

# Promote latest RC to production
./promote_rc.sh

# Promote specific RC branch  
./promote_rc.sh --rc release/2.12.0-rc.8

# Promote with custom message
./promote_rc.sh --message "Release v2.12.0 - New features and bug fixes"

# Promote and automatically create next RC train (streamlined workflow)
./promote_rc.sh --auto-next-rc

# Dry run with auto-next-rc to preview full workflow
./promote_rc.sh --auto-next-rc --dry-run

Auto Next RC Feature: When --auto-next-rc is used, the script will automatically:

  1. Checkout main branch and pull latest changes
  2. Read version from package.json
  3. Run cut_rc.sh --version $(node -p "require('./package.json').version") --replace
  4. Create the new RC train (e.g., release/X.Y.Z-rc.0)

This eliminates the manual step of switching branches and creating the next RC after promotion.

status_rc.sh

Purpose: Displays the current state of release management and provides intelligent recommendations.

Usage:

./status_rc.sh [options]

Key Options:

  • --commits - Show commits since last release
  • --verbose - Show additional details like authors and commit counts
  • --max <n> - Maximum commits to display (default: 10)

Examples:

# Check current release state
./status_rc.sh

# See what commits are ready for next release  
./status_rc.sh --commits

# Detailed status for team reviews
./status_rc.sh --verbose --commits --max 20

Workflow Examples

Normal Development Lifecycle Example

Starting New Development Cycle (After Production Release)

# Production v2.11.0 was just released
# Production workflow automatically bumps main to 2.12.0

# Engineer manually creates first RC:
./cut_rc.sh --version 2.12.0 --replace
# Creates: release/2.12.0-rc.0
# Pushes to remote β†’ staging workflow builds and deploys automatically

Active Development Phase

# Engineer merges feature PR to main
# Staging workflow automatically runs: cut_rc.sh --replace
# Creates: release/2.12.0-rc.1 (deletes rc.0)
# Staging workflow builds and deploys automatically

# Another feature merged to main
# Staging workflow automatically runs: cut_rc.sh --replace
# Creates: release/2.12.0-rc.2 (deletes rc.1)
# Staging workflow builds and deploys automatically

# Continue until ready for production...
# Latest RC: release/2.12.0-rc.8

Ready for Production

# All tests pass on release/2.12.0-rc.8

# Option 1: Standard promotion
./promote_rc.sh
# Creates: v2.12.0 production tag
# Publishes GitHub Release
# Production workflow deploys and bumps main to 2.13.0
# Engineer manually creates next RC train later

# Option 2: Streamlined promotion (recommended)
./promote_rc.sh --auto-next-rc
# Creates: v2.12.0 production tag
# Publishes GitHub Release
# Production workflow deploys and bumps main to 2.13.0
# Automatically creates: release/2.13.0-rc.0 (next development train ready)

Promotion Workflow Comparison

Traditional Workflow (Manual Next RC Creation)

# 1. Promote RC to production
./promote_rc.sh
# βœ… Creates v2.12.0 tag and GitHub Release
# βœ… Production deploys and bumps main to 2.13.0

# 2. Engineer manually starts next development cycle (later)
git checkout main
git pull origin main  # Get updated package.json with 2.13.0
./cut_rc.sh --version $(node -p "require('./package.json').version") --replace
# βœ… Creates release/2.13.0-rc.0

# Problem: Manual step, easy to forget, workflow gap

Streamlined Workflow (Automatic Next RC Creation)

# Single command handles promotion + next RC train
./promote_rc.sh --auto-next-rc
# βœ… Creates v2.12.0 tag and GitHub Release
# βœ… Production deploys and bumps main to 2.13.0
# βœ… Automatically creates release/2.13.0-rc.0
# βœ… Next development cycle immediately ready

# Benefit: No manual steps, no workflow gaps, seamless transitions

Hotfix Lifecycle Example

Critical Bug in Production

# Production is on v2.11.0, main is ahead with 2.12.0-rc.5
git checkout -b hotfix/critical-security-fix v2.11.0
# Apply minimal fix
# Update patch in package.json to 2.11.1
git commit -am "fix: critical security vulnerability"
git push origin hotfix/critical-security-fix

Release Hotfix Directly

# Tag the hotfix directly (no RC process for hotfixes)
git tag -a v2.11.1 -m "Hotfix: critical security vulnerability"
git push origin v2.11.1

# Create GitHub Release (triggers production deployment)
gh release create v2.11.1 --title "Hotfix v2.11.1" --notes "Critical security vulnerability fix"
# OR create release via GitHub UI

# Production workflow detects hotfix (v2.11.1 < v2.12.0 on main) and deploys without bumping main

Integrate Back to Main

# Create PR: hotfix/critical-security-fix β†’ main
# Team reviews and merges

# Staging automatically picks up hotfix in next RC
# (CI/CD runs cut_rc.sh --replace after main merge)
# Creates: release/2.12.0-rc.6 (includes hotfix + ongoing features)

Using status_rc.sh for Decision Making

# Check current state before any action
./status_rc.sh --commits

# Example output guides next steps:
# Latest Production: v2.11.0
# Active RC: release/2.12.0-rc.5  
# Commits since v2.11.0: 25 commits
# Recommendation: Test RC or continue development

Troubleshooting

Common Issues

Working Tree Not Clean

# Error: working tree not clean
git status
git stash  # or commit your changes

Tag Already Exists

# Error: tag vX.Y.Z already exists
# Could be a failed promotion or the version was already released

# If promotion failed, delete the tag and retry:
git tag -d v2.10.0                    # delete local tag
git push origin :refs/tags/v2.10.0    # delete remote tag
# Fix any issues in RC, then re-run:
./promote_rc.sh

# If version was already released, continue RC train or start new version:
./cut_rc.sh --replace  # continue current train
# or 
./cut_rc.sh --version X.Y.Z+1 --replace  # start new version

Wrong Branch for Promotion

# Error: branch 'xxx' must match pattern: release/X.Y.Z-rc.N  
git checkout release/2.12.0-rc.8  # switch to correct RC branch
./promote_rc.sh

Recovery Commands

Undo RC Branch (if not yet promoted)

git push origin :release/X.Y.Z-rc.N  # delete remote branch
git branch -D release/X.Y.Z-rc.N     # delete local branch

Undo Production Tag (⚠️ coordinate with team first)

git push origin :refs/tags/vX.Y.Z    # delete remote tag  
git tag -d vX.Y.Z                    # delete local tag

Check Current State

./status_rc.sh --commits              # see what's ready for release
git tag -l 'v*' --sort=-version:refname | head -5  # recent production tags

Best Practices

  • Always use --dry-run first when learning the scripts
  • Use ./status_rc.sh before taking any action
  • Coordinate with team - only one person should manage releases at a time
  • Use --replace to keep branch history clean
  • Test RCs thoroughly before promoting to production