Branching Strategy
Source:.github/BRANCHING_STRATEGY.md
This document describes the branching strategy and deployment workflow for the emburden R package.
Table of Contents
- Overview
- Branch Structure
- Promotion Workflows
- Developer Workflows
- Release Process
- Manual Override
- Troubleshooting
Overview
The emburden package uses a GitFlow-inspired branching model with controlled promotion workflows and approval gates to ensure code quality and stability through the deployment pipeline.
Key Principles
- Sequential flow only: Code flows in one direction: Feature → Dev → Staging → Main → Public → CRAN
- No bypassing: Each stage must be completed successfully before moving to the next
- Approval gates: Critical promotions require manual approval
- Automated validation: CI checks run at every stage
- Rollback capability: All changes are versioned and can be reverted
Deployment Pipeline
┌─────────────┐
│ Feature │ Developer creates feature branch
│ Branches │
└──────┬──────┘
│ PR + CI checks
↓
┌─────────────┐
│ Dev │ Integration branch (fast CI feedback)
└──────┬──────┘
│ promote-to-staging.yml (requires approval)
↓
┌─────────────┐
│ Staging │ Pre-production testing (multi-platform CI)
└──────┬──────┘
│ promote-to-main.yml (requires approval + version bump)
↓
┌─────────────┐
│ Main │ Production (private repo)
└──────┬──────┘
│ publish-to-public.yml (automatic)
↓
┌─────────────┐
│ Public │ Public repository (ericscheier/emburden)
│ Repo │
└──────┬──────┘
│ cran-release.yml (requires final approval)
↓
┌─────────────┐
│ CRAN │ Official R package repository
└─────────────┘
Branch Structure
main - Production Branch
Purpose: Production-ready code, synced to public repository
Protection: - Requires PR with approvals - Requires all status checks to pass (ubuntu, windows, macos) - Requires production-release environment approval - Linear history enforced - No direct commits allowed
Triggers: - Creates version tags (v*.*.*) - Triggers GitHub release creation - Syncs to public repository - Initiates CRAN submission workflow
Who can merge: Only via promote-to-main.yml workflow after manual approval
staging - Pre-Production Branch
Purpose: Final validation before production release
Protection: - Requires PR with approvals - Requires all status checks to pass (ubuntu, windows, macos) - Requires staging-promotion environment approval - Linear history enforced - No direct commits allowed
Validation: - Multi-platform R CMD check (Ubuntu, Windows, macOS) - Full test coverage - Workflow validation
Who can merge: Only via promote-to-staging.yml workflow after manual approval
dev - Development Branch
Purpose: Integration branch for active development
Protection: - Requires PR - Auto-approval for safe changes (docs, tests) - Manual review for code changes - Requires status checks to pass (Ubuntu only - fast feedback) - Linear history enforced
Validation: - R CMD check (Ubuntu, release R only) - Test coverage - Workflow validation
Who can merge: - Developers with approval - Auto-approved for docs/tests changes via auto-approve-safe-changes.yml
Promotion Workflows
1. Feature → Dev
Trigger: Manual PR creation
Process: 1. Developer creates PR from feature branch to dev 2. CI runs R CMD check (Ubuntu only) and tests 3. Auto-approval if only docs/tests changed 4. Manual approval required for code changes 5. PR merges automatically after approval + CI pass
Approval: - None for docs/tests (auto-approved) - Code owner review for R code changes
2. Dev → Staging
Workflow: .github/workflows/promote-to-staging.yml
Trigger: Manual (via GitHub Actions UI)
Process: 1. Maintainer triggers “Promote Dev to Staging” workflow 2. Workflow validates dev branch (R CMD check) 3. Creates promotion PR: dev → staging 4. Requires manual approval via staging-promotion environment 5. Auto-merges after approval 6. Creates promotion tag: staging/YYYYMMDD-HHMMSS
Approval: Repository maintainer via staging-promotion environment
When to promote: - After feature development complete - All dev CI checks passing - Ready for pre-production validation
3. Staging → Main (Production Release)
Workflow: .github/workflows/promote-to-main.yml
Trigger: Manual (via GitHub Actions UI)
Parameters: - version_bump: patch | minor | major | custom - custom_version: (if version_bump=custom)
Process: 1. Maintainer triggers “Promote Staging to Main” workflow 2. Workflow validates staging (multi-platform R CMD check) 3. Bumps version in DESCRIPTION, CITATION, .zenodo.json 4. Updates NEWS.md from git commits 5. Creates release PR: staging → main 6. Requires manual approval via production-release environment 7. Auto-merges after approval 8. Creates version tag: v*.*.* 9. Creates GitHub release with NEWS.md content 10. Triggers publish-to-public workflow 11. Triggers CRAN release workflow
Approval: Repository maintainer via production-release environment
When to promote: - After staging validation complete - Ready for public release - All stakeholders agree to release - CRAN submission desired
Version Bump Strategy: - patch (0.5.20 → 0.5.21): Bug fixes, minor improvements - minor (0.5.20 → 0.6.0): New features, enhancements - major (0.5.20 → 1.0.0): Breaking changes, major releases - custom: Specify exact version (e.g., for release candidates)
4. Main → Public Repo
Workflow: .github/workflows/publish-to-public.yml
Trigger: Automatic when GitHub release is published on main
Process: 1. Triggered automatically by GitHub release event 2. Full CRAN validation (with vignettes) 3. Requires cran-production environment approval 4. Cleans repository (removes private files, AI attributions) 5. Force-pushes to public repository: ericscheier/emburden 6. Pushes version tag to public repo 7. Creates GitHub release on public repo
Approval: Repository maintainer via cran-production environment
Automated cleaning: - Removes .private/ directory - Removes *.log files - Removes *_cache/ and *_files/ directories - Removes private workflow files - Strips AI attributions from commit messages
5. Public Repo → CRAN
Workflow: .github/workflows/cran-release.yml (on public repo)
Trigger: Automatic when version tag pushed to public repo
Process: 1. Builds source package with vignettes 2. Runs full CRAN checks 3. Provides instructions for manual CRAN submission 4. Uploads tarball to GitHub release
Note: CRAN submission requires manual interaction and cannot be fully automated
Developer Workflows
Release Process
Preparing a Release
1. Complete development on dev branch
2. Promote dev → staging
# Via GitHub Actions UI:
# Actions → "Promote Dev to Staging" → Run workflow
#
# Then approve the staging-promotion environment when PR is created3. Validate on staging
# Wait for multi-platform CI to complete
# Test the package manually if needed
# Verify all changes are ready for production4. Promote staging → main (production release)
# Via GitHub Actions UI:
# Actions → "Promote Staging to Main (Production Release)" → Run workflow
# version_bump: patch | minor | major
#
# Workflow will:
# - Validate staging
# - Bump version automatically
# - Create release PR
#
# Then approve the production-release environment5. Automatic publishing
# After merge to main, workflows automatically:
# - Create version tag (v*.*.*)
# - Create GitHub release
# - Publish to public repo
# - Trigger CRAN submission workflow6. CRAN submission
Hotfix Process
For critical bugs in production:
# 1. Create hotfix branch from main
git checkout main
git pull scheier main
git checkout -b hotfix/critical-bug
# 2. Fix the bug
# ... make changes ...
git commit -m "fix: Critical bug in production"
# 3. Create PR to staging (not dev)
gh pr create --base staging --head hotfix/critical-bug
# 4. After merge to staging, promote to main immediately
# Use promote-to-main workflow
# 5. Backport to dev if needed
git checkout dev
git cherry-pick <hotfix-commit-sha>
git push scheier devManual Override
Emergency Procedures
When to use: Critical production issues only
Process: 1. Identify the issue and severity 2. Get approval from repository owner 3. Create hotfix branch from affected branch 4. Apply minimal fix 5. Follow expedited promotion process 6. Document in post-mortem
Bypassing Workflows
NOT RECOMMENDED but possible in emergencies:
# Emergency push to main (requires admin)
# This bypasses all protections - use with extreme caution
git push --force scheier main
# Better: Use workflow_dispatch with skip_checks parameter
# Actions → promote-to-main → Run workflow → skip_checks: trueTroubleshooting
CI Checks Failing
Problem: R CMD check fails on PR
Solutions: 1. Check error message in GitHub Actions log 2. Run R CMD check locally: devtools::check() 3. Fix issues and push new commit 4. CI will re-run automatically
Promotion Workflow Stuck
Problem: Promotion workflow waiting for approval
Solutions: 1. Check GitHub Actions → Environments 2. Review and approve the pending deployment 3. Workflow will resume automatically
Version Bump Issues
Problem: Automated version bump created wrong version
Solutions: 1. Do NOT merge the release PR yet 2. Close the PR 3. Manually edit DESCRIPTION, CITATION, .zenodo.json 4. Commit to staging: git commit -am "fix: Correct version number" 5. Re-run promote-to-main workflow with custom version
Configuration Reference
GitHub Environments
| Environment | Purpose | Approvers | Required For |
|---|---|---|---|
staging-promotion |
Dev → Staging | Maintainer | Promotion to staging |
production-release |
Staging → Main | Maintainer | Production releases |
cran-production |
Final CRAN gate | Maintainer | CRAN submission |
Additional Resources
- CODEOWNERS - Code review requirements
- BRANCH_PROTECTION_SETUP.md - GitHub configuration
- DEPRECATED_WORKFLOWS.md - Migration notes
- CONTRIBUTING.md - Contribution guidelines
Questions or Issues?
- Workflow failures: Check GitHub Actions logs and adjust code
- Approval questions: Contact repository maintainer
- Feature requests: Open an issue on GitHub
- Emergency support: Email eric@scheier.org