Skip to content

Release Guide

This guide documents the complete release process for gbcms using git-flow workflow.

Pre-Release Checklist

Before starting a release, ensure:

  • All CI checks pass on develop
  • All features for the release are merged to develop
  • No blocking issues in milestone

Version Locations

All these files must be updated with the new version (5 references total):

File Lines Count Format
pyproject.toml 3 1 version = "X.Y.Z"
src/gbcms/__init__.py 11 1 __version__ = "X.Y.Z"
rust/Cargo.toml 3 1 version = "X.Y.Z"
nextflow/modules/local/gbcms/run/main.nf 7 1 container "ghcr.io/msk-access/gbcms:X.Y.Z"
CHANGELOG.md Top section ## [X.Y.Z] - YYYY-MM-DD (new entry)

Doc versions are now templated

Installation, quickstart, troubleshooting, and developer-guide docs use generic X.Y.Z notation. No doc version bumps needed during release.

Verify all references

After updating, run this to ensure no stale versions remain:

grep -rn "OLD_VERSION" --include="*.py" --include="*.toml" --include="*.nf" --include="*.md" . \
  | grep -v ".git/" | grep -v "site/" | grep -v "CHANGELOG"

Release Workflow

flowchart LR
    develop -->|1. Create release branch| release/X.Y.Z
    release/X.Y.Z -->|2. Update versions| release/X.Y.Z
    release/X.Y.Z -->|3. PR to main| main
    main -->|4. Tag triggers CI| CI
    CI --> PyPI
    CI --> Docker/GHCR
    CI --> gh-pages
    main -->|5. Merge back| develop
Use mouse to pan and zoom

Step-by-Step Instructions

1. Create Release Branch

# From develop
git checkout develop
git pull origin develop

# Create release branch
git checkout -b release/X.Y.Z

2. Update Version Numbers

Update all version locations listed above. Use this command to verify:

# Check current versions
grep -E "^version|^__version__" pyproject.toml src/gbcms/__init__.py rust/Cargo.toml
grep "container" nextflow/modules/local/gbcms/run/main.nf

3. Update CHANGELOG.md

Add new section at top:

## [X.Y.Z] - YYYY-MM-DD

### ✨ Added
- New feature description

### 🔧 Fixed
- Bug fix description

### 🔄 Changed
- Changes description

4. Run Pre-Release Checks

# Lint
make lint

# Format
make format

# Tests
make test

# Local build test
make docker-build

5. Commit and Push

git add -A
git commit -m "chore: bump version to X.Y.Z"
git push origin release/X.Y.Z

6. Create PR: release/X.Y.Z → main

  • Title: Release X.Y.Z
  • Describe changes from CHANGELOG
  • Wait for CI to pass

7. Merge to main (creates tag)

After PR approval: - Squash and merge to main - Create tag: git tag X.Y.Z && git push origin X.Y.Z

8. CI Release Pipeline

The tag triggers .github/workflows/release.yml:

  1. Build wheels (Linux x86_64, aarch64; macOS x86_64, arm64; Windows)
  2. Publish to PyPI (via maturin)
  3. Build Docker image → push to ghcr.io/msk-access/gbcms:X.Y.Z
  4. Deploy docs → GitHub Pages (versioned via mike as X.Y.Z / stable)

9. Merge main back to develop

git checkout develop
git pull origin develop
git merge main
git push origin develop

10. Cleanup

# Delete local release branch
git branch -d release/X.Y.Z

# Delete remote release branch (optional)
git push origin --delete release/X.Y.Z

Hotfix Workflow

For critical production fixes:

# Create hotfix from main
git checkout main
git checkout -b hotfix/X.Y.Z

# Fix, commit, push
git add -A
git commit -m "fix: critical issue description"
git push origin hotfix/X.Y.Z

# PR to main, then merge back to develop

Automation Scripts

git-flow-helper.sh

Interactive helper for git-flow operations:

./git-flow-helper.sh
# Options:
# 1) Create feature branch
# 2) Create release branch
# 3) Show git status
# 4) Cleanup merged branches

Makefile Targets

Target Description
make lint Run ruff and mypy
make format Run black and ruff --fix
make test Run pytest
make test-cov Run tests with coverage
make docker-build Build Docker image locally

CI Workflows

Workflow Trigger Purpose
test.yml Push to develop/main, PR Run tests
release.yml Tag push X.Y.Z Build wheels, publish PyPI, Docker
deploy-docs.yml Push to main or develop (docs/) Deploy versioned docs via mike (stable from main, dev from develop)

Troubleshooting

PyPI Upload Fails

  • Check if version already exists on PyPI (versions cannot be overwritten)
  • Verify PYPI_TOKEN secret is set in GitHub repository

Docker Build Fails

  • Check Dockerfile paths match the new folder structure
  • Verify rust/Cargo.toml version matches

Docs Build Fails

  • Verify mkdocs-mermaid2-plugin is installed in workflow
  • Check snippet paths are correct (relative to root)