Skip to content

Enforce staging-first deployments by verifying commit ancestry and minimum soak time before production.

License

Notifications You must be signed in to change notification settings

codad5/verify-branch-ancestry

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

6 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Verify Branch Ancestry πŸ›‘οΈ

GitHub Marketplace CI License: MIT

Enforce staging-first workflows by ensuring commits come from specified branches before deployment

This GitHub Action helps maintain deployment discipline by verifying that commits in your main branch actually originated from your staging or development branches. Perfect for preventing direct pushes to production and enforcing proper code review workflows.

✨ Features

  • πŸ” Smart Merge Detection - Automatically handles GitHub merge commits from pull requests
  • ⏰ Minimum Age Enforcement - Ensure code has "soaked" in staging for a specified time
  • 🎯 Multi-Branch Support - Verify against multiple required branches (staging, dev, etc.)
  • ⚑ Fast & Reliable - Uses native Git commands with comprehensive error handling
  • πŸ› οΈ Highly Configurable - Customize behavior for your specific workflow
  • πŸ“Š Detailed Outputs - Get verification results and metadata for downstream jobs
  • πŸ”§ Debug Mode - Verbose logging to troubleshoot complex scenarios

πŸš€ Quick Start

Basic Usage

name: Deploy to Production
on:
  push:
    branches: [main]

jobs:
  verify-staging:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Required for proper branch comparison
          
      - name: Verify commit came from staging
        uses: codad5/verify-branch-ancestry@v1
        with:
          required-branches: 'staging'

Staging with Minimum Soak Time

Ensure code has been stable in staging for at least 1 hour before production:

- name: Verify staging with soak time
  uses: codad5/verify-branch-ancestry@v1
  with:
    required-branches: 'staging'
    minimum-age: '1h'           # Must be in staging for 1 hour
    fail-on-missing: true

Advanced Configuration

- name: Verify staging-first workflow
  uses: codad5/verify-branch-ancestry@v1
  with:
    required-branches: 'staging,development'  # Multiple branches
    minimum-age: '30m'                        # 30 minute soak time
    check-merge-commits: true                 # Handle PR merges
    fail-on-missing: true                     # Fail workflow if not found
    verbose: true                             # Enable debug output
    timezone: 'America/New_York'              # Time calculations timezone

πŸ“– Use Cases

1. Staging-First Deployment

Ensure all production deployments come through your staging environment:

name: Production Deploy
on:
  push:
    branches: [main]

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          
      - name: Ensure staging-first workflow
        uses: codad5/verify-branch-ancestry@v1
        with:
          required-branches: 'staging'
          
  deploy:
    needs: verify
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to production
        run: ./deploy.sh

2. Multi-Environment Validation

Verify commits passed through development AND staging:

- name: Verify multi-stage workflow
  uses: codad5/verify-branch-ancestry@v1
  with:
    required-branches: 'development,staging'
    fail-on-missing: true

4. Enterprise Soak Time Requirements

Perfect for organizations requiring stability periods before production:

name: Production Deploy with Soak Time
on:
  push:
    branches: [main]

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          
      - name: Ensure 2-hour staging soak time
        uses: codad5/verify-branch-ancestry@v1
        with:
          required-branches: 'staging'
          minimum-age: '2h'
          verbose: true
          
  deploy:
    needs: verify
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to production
        run: ./deploy.sh

5. Weekend Deploy Protection

Prevent fresh code from going to production on Fridays:

- name: Weekend deploy protection
  uses: codad5/verify-branch-ancestry@v1
  with:
    required-branches: 'staging'
    minimum-age: '1d'  # Must be in staging for 1 day
    fail-on-missing: true

Use outputs to create conditional deployment logic:

- name: Check branch ancestry
  id: verify
  uses: codad5/verify-branch-ancestry@v1
  with:
    required-branches: 'staging'
    fail-on-missing: false

- name: Deploy if verified
  if: steps.verify.outputs.verified == 'true'
  run: ./deploy.sh

- name: Send alert if not verified
  if: steps.verify.outputs.verified == 'false'
  run: ./alert-team.sh "Direct push detected!"

βš™οΈ Configuration

Inputs

Input Description Required Default
required-branches Comma-separated list of branches that must contain the commit βœ… staging
current-branch Current branch being checked (auto-detected if not provided) ❌ Auto-detected
fail-on-missing Whether to fail workflow if commit not found in required branches ❌ true
check-merge-commits Whether to validate merge commits by checking their parents ❌ true
verbose Enable detailed logging for debugging ❌ false
minimum-age Minimum time commit must exist in required branches (e.g., "1h", "30m", "2d") ❌ 0m
timezone Timezone for time calculations (e.g., "UTC", "America/New_York") ❌ UTC
github-token GitHub token for API access ❌ ${{ github.token }}

Outputs

Output Description
verified Whether the commit verification passed (true/false)
commit-sha The commit SHA that was verified
source-branch The branch from which the commit originated
commit-age Age of the commit in the source branch (human readable, e.g., "2h 15m")
minimum-age-met Whether the minimum age requirement was met (true/false)

⏰ Time Format Support

The minimum-age input supports flexible time formats:

minimum-age: '30m'     # 30 minutes
minimum-age: '1h'      # 1 hour  
minimum-age: '2h30m'   # 2 hours 30 minutes
minimum-age: '1d'      # 1 day
minimum-age: '1w'      # 1 week
minimum-age: '2d4h'    # 2 days 4 hours

Supported units: s (seconds), m (minutes), h (hours), d (days), w (weeks)

Regular Commits

For regular commits, the action uses git merge-base --is-ancestor to verify the commit exists in the specified branch(es).

Merge Commits (PR Merges)

When GitHub merges a pull request, it creates a merge commit with two parents:

  1. Parent 1: The previous HEAD of the target branch (e.g., main)
  2. Parent 2: The HEAD of the source branch (e.g., staging)

The action intelligently detects merge commits and verifies that at least one parent originated from your required branches.

πŸ“‹ Prerequisites

  • Your workflow must use fetch-depth: 0 to ensure full Git history is available
  • Required branches must exist and be accessible
  • Proper permissions for the GitHub token (usually automatic)

πŸ› οΈ Troubleshooting

Common Issues

❌ "Failed to fetch branch 'staging'"

  • Ensure the branch exists in your repository
  • Check that the branch name is spelled correctly
  • Verify repository permissions

❌ "Commit not found in any required branches"

  • This usually means the commit was pushed directly to main
  • Use verbose: true to get detailed debugging information
  • Check that your staging branch is up to date

❌ "shallow repository" errors

  • Add fetch-depth: 0 to your checkout action
  • This ensures the full Git history is available

Debug Mode

Enable verbose logging to troubleshoot issues:

- uses: codad5/verify-branch-ancestry@v1
  with:
    required-branches: 'staging'
    verbose: true

This provides detailed information about:

  • Branch heads and commit SHAs
  • Merge base calculations
  • Parent commit analysis
  • Step-by-step verification process

🀝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

  1. Clone the repository
  2. Make your changes to action.yml
  3. Test with the provided workflow examples
  4. Submit a pull request

Testing Locally

# Test the action in a local repository
git checkout main
export GITHUB_SHA=$(git rev-parse HEAD)
export GITHUB_REF=refs/heads/main
bash -c "$(cat action.yml | yq '.runs.steps[0].run')"

πŸ“ Examples & Workflows

Check out our examples directory for complete workflow configurations:

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Inspired by the need for better deployment discipline
  • Thanks to the GitHub Actions community for best practices
  • Built with ❀️ for developers who care about code quality

Like this action? ⭐ Give it a star and share with your team!

Need help? πŸ’¬ Open an issue or start a discussion

About

Enforce staging-first deployments by verifying commit ancestry and minimum soak time before production.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Languages