Last Updated: December 2, 2025
Purpose: Define continuous integration workflows for automated testing and deployment gating.
main without passing the full Minitest suiteWhy GitHub Actions:
ruby/setup-rubyNo existing CI configuration found — we’ll create from scratch.
| Environment | Runner |
|---|---|
| All workflows | ubuntu-latest |
| Service | Purpose | Version |
|---|---|---|
| PostgreSQL | Test database | 14+ |
| Ruby | Application runtime | 3.2.3+ (from .ruby-version) |
| Node.js | Asset compilation | 18+ (from package.json) |
┌─────────────────────────────────────────────────────────────────────────┐
│ CI/CD Pipeline │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Pull Request │───▶│ CI │───▶│ Merge │ │
│ │ Created │ │ (tests) │ │ to main │ │
│ └──────────────┘ └──────────────┘ └──────┬───────┘ │
│ │ │ │
│ │ Must pass │ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Block merge │ │ Deploy to │ │
│ │ if failing │ │ Staging │ │
│ └──────────────┘ └──────┬───────┘ │
│ │ │
│ │ Smoke tests │
│ ▼ │
│ ┌──────────────┐ │
│ │ Deploy to │◀── Manual │
│ │ Production │ or tag │
│ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
File: .github/workflows/ci.yml
| Trigger | Behavior |
|---|---|
push to any branch |
Run tests |
pull_request to main |
Run tests, block merge if failing |
Jobs:
.ruby-version)bundle install, npm install)rails testEstimated Duration: 3-5 minutes
File: .github/workflows/deploy-staging.yml
| Trigger | Behavior |
|---|---|
push to main (after merge) |
Deploy to staging |
| Manual dispatch | Deploy to staging on demand |
Jobs:
Dependencies:
HEROKU_API_KEY secretFile: .github/workflows/deploy-production.yml
| Trigger | Behavior |
|---|---|
Git tag (v*) |
Deploy tagged release to production |
| Manual dispatch with approval | Deploy on demand |
Jobs:
Safety Gates:
environment: production (enables GitHub protection rules)| Requirement | Enforcement |
|---|---|
| All tests pass | GitHub branch protection rule |
| PR reviewed (optional for solo) | GitHub branch protection rule |
| No conflicts | Git |
Setup: Configure branch protection on main to require CI passing.
| Requirement | Enforcement |
|---|---|
Tests pass on main |
CI workflow |
| Build succeeds | Heroku |
| Migrations run cleanly | Heroku release phase |
Automatic: Deploys trigger on merge to main.
| Requirement | Enforcement |
|---|---|
| Tests pass | CI workflow |
| Staging smoke tests pass | Deploy workflow |
| Tag created OR manual approval | Workflow trigger |
Semi-Automatic: Create tag to deploy, or manually trigger with approval.
Based on TESTING_GUIDE.md and TODO_BUGS.md:
| Category | Test File | Description |
|---|---|---|
| Authentication | sessions_controller_test.rb |
Login/logout, session security |
| User Management | users_controller_test.rb |
Admin-only access, profile security |
| Model Validations | alumni_test.rb, user_test.rb |
Data integrity |
| Category | Test File | Description |
|---|---|---|
| Alumni Search | alumni_controller_test.rb |
Core search functionality |
| Engagement | engagement_score_calculator_test.rb |
Scoring accuracy |
| Champion Signup | champion_signup_test.rb |
External-facing flow |
| Permissions | *_controller_test.rb |
Role-based access |
| Category | Test File | Description |
|---|---|---|
| Settings | settings/*_controller_test.rb |
Admin CRUD operations |
| Affinities | alumni_affinities_controller_test.rb |
Affinity management |
| Mailers | *_mailer_test.rb |
Email content/delivery |
| Category | Description |
|---|---|
| Edge cases | Unusual input handling |
| Performance | Query optimization (not currently tested) |
From TODO_BUGS.md:
| Issue | Area | Test Impact |
|---|---|---|
| Modal flow edge case | Alumni affinities | Low — JavaScript path is primary |
| Activity code validation | Engagement activities | Medium — could add validation test |
ci.yml)# .github/workflows/ci.yml
name: CI
on:
push:
branches: ['**']
pull_request:
branches: [main]
env:
RAILS_ENV: test
DATABASE_URL: postgres://postgres:postgres@localhost:5432/alumni_lookup_test
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:14
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: alumni_lookup_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install Node dependencies
run: npm ci
- name: Build CSS
run: npm run build:css
- name: Setup database
run: |
bin/rails db:create
bin/rails db:schema:load
- name: Run tests
run: bin/rails test
- name: Upload test results (on failure)
if: failure()
uses: actions/upload-artifact@v4
with:
name: test-results
path: tmp/test-results/
retention-days: 7
deploy-staging.yml)# .github/workflows/deploy-staging.yml
name: Deploy to Staging
on:
push:
branches: [main]
workflow_dispatch:
env:
HEROKU_APP_STAGING: alumni-lookup-staging
jobs:
test:
uses: ./.github/workflows/ci.yml
deploy:
needs: test
runs-on: ubuntu-latest
environment: staging
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Deploy to Heroku
uses: akhileshns/heroku-deploy@v3.13.15
with:
heroku_api_key: $
heroku_app_name: $
heroku_email: $
- name: Run migrations
run: |
heroku run rails db:migrate --app $
env:
HEROKU_API_KEY: $
smoke-test:
needs: deploy
runs-on: ubuntu-latest
steps:
- name: Wait for deploy
run: sleep 30
- name: Check lookup portal
run: |
curl -f https://staging-lookup.bualum.co/users/sign_in || exit 1
- name: Check champions portal
run: |
curl -f https://staging-champions.bualum.co/ || exit 1
deploy-production.yml)# .github/workflows/deploy-production.yml
name: Deploy to Production
on:
push:
tags:
- 'v*'
workflow_dispatch:
env:
HEROKU_APP_PRODUCTION: alumni-lookup
jobs:
test:
uses: ./.github/workflows/ci.yml
deploy:
needs: test
runs-on: ubuntu-latest
environment: production # Enables approval requirement
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Deploy to Heroku
uses: akhileshns/heroku-deploy@v3.13.15
with:
heroku_api_key: $
heroku_app_name: $
heroku_email: $
- name: Run migrations
run: |
heroku run rails db:migrate --app $
env:
HEROKU_API_KEY: $
verify:
needs: deploy
runs-on: ubuntu-latest
steps:
- name: Wait for deploy
run: sleep 30
- name: Verify lookup portal
run: |
curl -f https://lookup.bualum.co/users/sign_in || exit 1
- name: Verify champions portal
run: |
curl -f https://champions.bualum.co/ || exit 1
.github/workflows/ci.ymlmain requiring CI to passHEROKU_API_KEY to GitHub secretsHEROKU_EMAIL to GitHub secrets.github/workflows/deploy-staging.yml.github/workflows/deploy-production.yml| Secret | Purpose | How to Get |
|---|---|---|
HEROKU_API_KEY |
Deploy to Heroku | heroku auth:token |
HEROKU_EMAIL |
Heroku account email | Your Heroku login email |
Add secrets at: https://github.com/<owner>/<repo>/settings/secrets/actions