GitHub Actions Integration
Automatically check for migration issues in your CI/CD pipeline using Rails Migration Guard with GitHub Actions.
Quick Start
Add this workflow to your repository to check for migration issues on every pull request:
# .github/workflows/migration-check.yml
name: Migration Check
on:
pull_request:
branches: [ main, master ]
jobs:
check-migrations:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:14
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for branch comparison
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Setup database
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test
RAILS_ENV: test
run: |
bundle exec rails db:create
bundle exec rails db:schema:load
- name: Check for migration issues
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test
RAILS_ENV: test
run: |
bundle exec rails db:migration:ci --strict
Pro Tip: Rails Migration Guard also includes a GitHub Action that provides additional features like automatic PR comments. Use uses: ./.github/actions/migration-guard
instead of the CLI command.
Configuration Options
Command Line Options
Option | Description | Default |
---|---|---|
--strict |
Fail on warnings | false |
--format |
Output format (text/json) | text |
Exit Codes
- 0 No issues found
- 1 Warnings found (orphaned migrations)
- 2 Errors found (missing migrations)
Database Services
PostgreSQL
services:
postgres:
image: postgres:14
env:
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
MySQL
services:
mysql:
image: mysql:8
env:
MYSQL_ROOT_PASSWORD: pass
MYSQL_DATABASE: test_db
ports:
- 3306:3306
SQLite
# No service needed
env:
DATABASE_URL: sqlite3:db/test.sqlite3
RAILS_ENV: test
Advanced Examples
Matrix Testing
Test across multiple Ruby and Rails versions
strategy:
matrix:
ruby: ['3.1', '3.2', '3.3']
rails: ['7.0', '7.1', '7.2']
steps:
- uses: ruby/setup-ruby@v1
with:
ruby-version: $
bundler-cache: true
- name: Check migrations
run: bundle exec rails db:migration:ci
Conditional Checks
Only run when migrations change
on:
pull_request:
paths:
- 'db/migrate/**'
- 'db/schema.rb'
- 'db/structure.sql'
Scheduled Monitoring
Check for drift in staging environments
on:
schedule:
- cron: '0 9 * * 1-5' # 9 AM UTC on weekdays
jobs:
check-drift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: main
- name: Check staging migrations
env:
RAILS_ENV: staging
DATABASE_URL: $
run: bundle exec rails db:migration:ci
JSON Output Parsing
Use JSON format for advanced workflows and automated processing:
Workflow Example
- name: Check migrations
id: migration_check
env:
DATABASE_URL: $
run: |
bundle exec rails db:migration:ci \
--format json > result.json || true
echo "orphaned_count=$(jq '.orphaned | length' result.json)" \
>> $GITHUB_OUTPUT
- name: Comment on PR
if: steps.migration_check.outputs.orphaned_count > 0
uses: actions/github-script@v6
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '⚠️ Found orphaned migrations'
})
JSON Output Format
{
"status": "warning",
"orphaned": [
{
"version": "20240115123456",
"name": "add_user_profiles",
"branch": "feature/profiles",
"author": "developer@example.com"
}
],
"missing": [],
"synced": [
"20240110111111",
"20240112222222"
]
}
Best Practices
Use fetch-depth: 0
The gem needs full git history to compare branches
Start with warnings
Use --strict only after your team is comfortable
Cache dependencies
Always use bundler-cache: true for speed
Secure credentials
Always use secrets for database URLs
Run in parallel
Migration checks can run alongside tests
Monitor drift
Set up scheduled checks for staging
Troubleshooting
"fetch-depth: 0 is required"
The gem needs full git history to compare branches:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Don't use shallow clone
Database connection errors
Ensure your database service is healthy:
- name: Wait for PostgreSQL
run: |
until pg_isready -h localhost -p 5432; do
echo "Waiting for PostgreSQL..."
sleep 1
done
Permission denied for PR comments
When using the built-in action with PR comments:
permissions:
contents: read
pull-requests: write