Files
turbovault-app/docs/CI_PIPELINE.md
2026-03-29 02:37:49 -04:00

308 lines
6.0 KiB
Markdown

# CI/CD Pipeline Documentation
TurboVault uses GitHub Actions for continuous integration and quality assurance.
## Pipeline Overview
The CI pipeline runs on:
- ✅ Every push to `main` or `develop` branches
- ✅ Every pull request to `main` or `develop`
## Jobs
### 1. Linting & Security 🔍
**Purpose:** Code style and security checks
**Steps:**
1. **RuboCop** - Ruby style guide enforcement
- Uses `rubocop-rails-omakase` (Rails official style guide)
- Runs with `--parallel` for speed
- **Fails build** if style violations found
2. **Brakeman** - Security vulnerability scanner
- Scans for Rails security issues
- `continue-on-error: true` (warnings don't block PRs)
**Run locally:**
```bash
task lint # Check style
task lint:fix # Auto-fix issues
task security # Run Brakeman
```
### 2. Type Checking 🔷
**Purpose:** Static type checking with Sorbet
**Steps:**
1. Generate RBI files for gems and Rails DSLs
2. Run Sorbet type checker
3. **Fails build** if type errors found
**Run locally:**
```bash
task tapioca:all # Generate RBI files
task typecheck # Run type checker
```
**Note:** RBI generation can take 1-2 minutes in CI.
### 3. Tests 🧪
**Purpose:** Run test suite
**Services:**
- PostgreSQL 15 database
**Steps:**
1. Set up PostgreSQL service
2. Install system dependencies
3. Create test database
4. Load schema
5. Run test suite
**Run locally:**
```bash
task test # Run all tests
```
### 4. Docker Build 🐳
**Purpose:** Verify Docker image builds successfully
**Steps:**
1. Set up Docker Buildx
2. Build production Docker image
3. Test that image runs
**Run locally:**
```bash
docker build -t turbovault:test .
docker run --rm turbovault:test bundle exec ruby --version
```
## CI Workflow File
Location: `.github/workflows/ci.yml`
## Status Badges
Status badges in `README.md`:
```markdown
![CI](https://github.com/YOUR_USERNAME/turbovault/workflows/CI/badge.svg)
[![RuboCop](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop)
[![Sorbet](https://img.shields.io/badge/types-sorbet-blue.svg)](https://sorbet.org)
```
**Don't forget** to replace `YOUR_USERNAME` with your actual GitHub username!
## What Fails the Build?
| Check | Fails Build? | Why |
|-------|--------------|-----|
| RuboCop style issues | ✅ Yes | Code style should be consistent |
| Brakeman security warnings | ❌ No | Some warnings are false positives |
| Sorbet type errors | ✅ Yes | Type safety is important |
| Test failures | ✅ Yes | Tests must pass |
| Docker build failure | ✅ Yes | Must be deployable |
## Fixing CI Failures
### RuboCop Failures
```bash
# Auto-fix most issues
task lint:fix
# Check what's left
task lint
# Commit fixes
git add .
git commit -m "Fix RuboCop style issues"
```
### Sorbet Type Errors
```bash
# Regenerate RBI files (if gems changed)
task tapioca:all
# Check for errors
task typecheck
# Fix type errors in code
# See docs/SORBET.md for patterns
```
### Test Failures
```bash
# Run tests locally
task test
# Run specific test
rails test test/models/game_test.rb
# Fix tests and re-run
```
### Docker Build Failures
```bash
# Build locally to debug
docker build -t turbovault:test .
# Check build logs for errors
# Usually missing dependencies or incorrect Dockerfile
```
## CI Performance
Typical run times:
- **Linting & Security:** ~30-60 seconds
- **Type Checking:** ~2-3 minutes (RBI generation)
- **Tests:** ~1-2 minutes
- **Docker Build:** ~3-5 minutes
**Total:** ~7-11 minutes per run
## Optimizations
### Caching
We use `bundler-cache: true` in Ruby setup to cache gems:
```yaml
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
```
This speeds up runs by ~1-2 minutes.
### Parallel Execution
Jobs run in parallel, not sequentially:
- Linting, Type Checking, Tests, and Docker Build all run simultaneously
- Total time = slowest job (usually Docker Build)
### RuboCop Parallel
RuboCop uses `--parallel` to check files concurrently:
```bash
bundle exec rubocop --parallel
```
## Local Development Workflow
Before pushing:
```bash
# 1. Fix style
task lint:fix
# 2. Check types
task typecheck
# 3. Run tests
task test
# 4. Commit
git add .
git commit -m "Your changes"
git push
```
This ensures CI will pass!
## Skipping CI
To skip CI on a commit (e.g., documentation only):
```bash
git commit -m "Update README [skip ci]"
```
## CI for Pull Requests
When someone submits a PR:
1. CI runs automatically
2. All jobs must pass before merge
3. Status shown in PR page
4. Merge button disabled until CI passes
## Viewing CI Results
**On GitHub:**
1. Go to repository
2. Click **Actions** tab
3. Click on a workflow run
4. View each job's logs
**In Pull Requests:**
- See status checks at bottom of PR
- Click "Details" to view logs
## Troubleshooting
### "RBI generation failed"
**Cause:** Tapioca couldn't generate RBI files
**Fix:** Usually transient - retry workflow. If persistent, check Gemfile.lock is committed.
### "Database connection failed"
**Cause:** PostgreSQL service not ready
**Fix:** Already handled with health checks:
```yaml
options: >-
--health-cmd pg_isready
--health-interval 10s
```
### "Bundler version mismatch"
**Cause:** Different Bundler versions locally vs CI
**Fix:** Run `bundle update --bundler` locally
## Advanced: Matrix Builds (Future)
To test multiple Ruby versions:
```yaml
strategy:
matrix:
ruby-version: ['3.2', '3.3', '3.4']
```
Currently we only test Ruby 3.3.
## Security
### Secrets
We use GitHub Secrets for sensitive data:
- `RAILS_MASTER_KEY` (optional, for encrypted credentials)
- No other secrets needed for tests
### Dependabot
Consider enabling Dependabot to auto-update dependencies:
- Settings → Security → Dependabot
## Resources
- [GitHub Actions Docs](https://docs.github.com/en/actions)
- [RuboCop](https://github.com/rubocop/rubocop)
- [Sorbet](https://sorbet.org/)
- [Brakeman](https://brakemanscanner.org/)
---
**Questions?** Check the workflow file: `.github/workflows/ci.yml`