This guide covers the Continuous Integration and Continuous Deployment (CI/CD) pipelines for StudyQuest using GitHub Actions.
- Overview
- GitHub Actions Workflows
- Setting Up CI/CD
- Configuring Secrets
- Deployment Process
- Rollback Procedures
- Monitoring Deployments
- Troubleshooting
StudyQuest uses three main GitHub Actions workflows:
- Test Suite (
test.yml) - Runs on every push and PR - Deploy to Production (
deploy.yml) - Runs on pushes tomainbranch - Security Scan (
security.yml) - Runs weekly and on PRs
┌─────────────────────────────────────────────────────────────┐
│ Code Push/PR │
└────────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Test Suite Workflow │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Backend Tests │ │ Frontend Tests │ │
│ ├──────────────────┤ ├──────────────────┤ │
│ │ • pytest │ │ • ESLint │ │
│ │ • Coverage │ │ • TypeScript │ │
│ │ • pip-audit │ │ • Jest │ │
│ └──────────────────┘ │ • npm audit │ │
│ │ • Build check │ │
│ └──────────────────┘ │
└────────────────────┬────────────────────────────────────────┘
│
▼ (if main branch)
┌─────────────────────────────────────────────────────────────┐
│ Deploy to Production Workflow │
├─────────────────────────────────────────────────────────────┤
│ 1. Wait for Tests to Pass │
│ 2. Deploy Backend (Render) │
│ • Trigger deploy hook │
│ • Basic health check │
│ • Detailed health check │
│ • Verify dependencies │
│ 3. Deploy Frontend (Vercel) │
│ • Build and deploy │
│ • Frontend health check │
│ • Backend connectivity check │
│ • Smoke tests │
│ 4. Post-Deployment Verification │
│ 5. Notify Status │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Security Scan Workflow │
│ (Weekly + PRs) │
├─────────────────────────────────────────────────────────────┤
│ • Dependency vulnerability scan │
│ • Secret scanning │
│ • Code security analysis │
└─────────────────────────────────────────────────────────────┘
Triggers:
- Push to
mainordevelopbranches - Pull requests to
mainordevelopbranches
Backend Tests Job:
Steps:
1. Checkout code
2. Set up Python 3.11
3. Install dependencies (with caching)
4. Run pytest with coverage
5. Run pip-audit security scan
6. Upload coverage to CodecovFrontend Tests Job:
Steps:
1. Checkout code
2. Set up Node.js 18
3. Install dependencies (with caching)
4. Run ESLint
5. Run TypeScript type checking
6. Run Jest tests
7. Run npm audit security scan
8. Build check (verify production build works)Key Features:
- Parallel execution (backend and frontend run simultaneously)
- Dependency caching for faster builds
- Coverage reporting
- Security audits
- Build verification
Triggers:
- Push to
mainbranch - Manual trigger via
workflow_dispatch
Jobs:
Purpose: Wait for test workflow to complete successfully
- Waits for "Backend Tests" to pass
- Waits for "Frontend Tests" to pass
- Blocks deployment if tests failSteps:
1. Trigger Render deployment via webhook
2. Wait 60 seconds for deployment
3. Basic health check (/health endpoint)
- Retries up to 10 times
- 10-second intervals
4. Detailed health check (/health/detailed)
- Verifies overall status
- Checks Supabase dependency
- Checks OpenRouter dependency
5. Rollback notification if health checks fail
6. Generate deployment summarySteps:
1. Install Vercel CLI
2. Pull Vercel environment configuration
3. Build project for production
4. Deploy to Vercel
5. Wait 20 seconds for stabilization
6. Frontend health check
7. Verify backend connectivity
8. Run smoke tests (homepage, login page)
9. Rollback notification if checks fail
10. Generate deployment summaryPurpose: Final end-to-end verification
- Runs after both deployments succeed
- Comprehensive health checks
- Creates deployment summaryPurpose: Final status notification
- Checks all job results
- Reports overall deployment status
- Fails if any job failedTriggers:
- Weekly on Mondays at 9 AM UTC (cron schedule)
- Pull requests to
mainordevelop - Manual trigger via
workflow_dispatch
Jobs:
Steps:
1. Scan backend with pip-audit
- Generates JSON report
- Uploads as artifact
2. Scan frontend with npm audit
- Generates JSON report
- Uploads as artifact
3. Check for critical vulnerabilitiesSteps:
1. Run custom secret scanner (Python utility)
2. Run TruffleHog for verified secrets
3. Upload scan results as artifactsSteps:
1. Run Bandit on Python code
- Security issue detection
- JSON report generation
2. Run ESLint security scan on TypeScript/JavaScript
- Security-focused linting
- JSON report generation
3. Upload results as artifactsPurpose: Aggregate results
- Generates summary report
- Checks all scan statuses
- Reports any issues- GitHub Repository: Code hosted on GitHub
- Render Account: For backend deployment
- Vercel Account: For frontend deployment
- Supabase Project: Database and authentication
git clone <repository-url>
cd studyquestGitHub Actions are automatically enabled for repositories. Verify:
- Go to repository → Settings → Actions → General
- Ensure "Allow all actions and reusable workflows" is selected
- Create Render account at https://render.com
- Create new Web Service
- Connect GitHub repository
- Configure service:
- Name: studyquest-backend
- Environment: Python 3
- Build Command:
pip install -r requirements.txt - Start Command:
uvicorn main:app --host 0.0.0.0 --port $PORT - Root Directory:
backend
- Add environment variables (see Configuring Secrets)
- Get deploy hook URL:
- Settings → Deploy Hook
- Copy the webhook URL
- Create Vercel account at https://vercel.com
- Install Vercel CLI:
npm install -g vercel
- Link project:
cd frontend vercel link - Get Vercel token:
- Account Settings → Tokens
- Create new token
- Copy token value
Protect the main branch:
- Repository → Settings → Branches
- Add rule for
mainbranch - Enable:
- ✅ Require status checks to pass before merging
- ✅ Require branches to be up to date before merging
- ✅ Status checks: "Backend Tests", "Frontend Tests"
- ✅ Require pull request reviews before merging
GitHub Actions requires secrets for deployment and testing.
- Go to repository → Settings → Secrets and variables → Actions
- Click "New repository secret"
- Add each secret below
| Secret Name | Description | Where to Get |
|---|---|---|
SUPABASE_URL |
Supabase project URL | Supabase Dashboard → Settings → API |
SUPABASE_KEY |
Supabase anon key | Supabase Dashboard → Settings → API |
OPENROUTER_API_KEY |
OpenRouter API key | https://openrouter.ai/keys |
JWT_SECRET |
Supabase JWT secret | Supabase Dashboard → Settings → API → JWT Settings |
| Secret Name | Description | Where to Get |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Supabase project URL | Same as backend |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Supabase anon key | Same as backend |
| Secret Name | Description | Where to Get |
|---|---|---|
RENDER_DEPLOY_HOOK_URL |
Render deploy webhook | Render Dashboard → Settings → Deploy Hook |
RENDER_BACKEND_URL |
Deployed backend URL | Render Dashboard (e.g., https://studyquest-backend.onrender.com) |
VERCEL_TOKEN |
Vercel authentication token | Vercel Account Settings → Tokens |
After adding secrets, verify they're configured:
# List secrets (names only, values are hidden)
gh secret listFor staging vs production:
-
Use GitHub Environments:
- Settings → Environments
- Create "staging" and "production" environments
- Add environment-specific secrets
-
Update workflow to use environments:
deploy-backend: environment: production steps: # deployment steps
Deployments happen automatically when code is pushed to main:
# 1. Create feature branch
git checkout -b feature/my-feature
# 2. Make changes and commit
git add .
git commit -m "Add new feature"
# 3. Push and create PR
git push origin feature/my-feature
# Create PR on GitHub
# 4. Tests run automatically on PR
# Review test results in PR checks
# 5. Merge PR to main
# Deployment starts automatically
# 6. Monitor deployment
# Check Actions tab on GitHubTrigger deployment manually:
-
Via GitHub UI:
- Go to Actions tab
- Select "Deploy to Production" workflow
- Click "Run workflow"
- Select branch (usually
main) - Click "Run workflow"
-
Via GitHub CLI:
gh workflow run deploy.yml
- Wait for test suite to complete
- Verify all tests pass
- Block deployment if tests fail
- Trigger Render deployment
- Wait for deployment to complete
- Run health checks
- Verify dependencies
- Build Next.js application
- Deploy to Vercel
- Run health checks
- Verify backend connectivity
- End-to-end verification
- Generate deployment summary
- Send notifications
Total Time: ~10-15 minutes
- Go to repository → Actions tab
- Click on running workflow
- View real-time logs for each job
- Check deployment summary at bottom
# Watch workflow runs
gh run watch
# List recent runs
gh run list --workflow=deploy.yml
# View specific run
gh run view <run-id>Backend (Render):
# View logs in Render dashboard
# Or use Render CLI
render logs -s studyquest-backendFrontend (Vercel):
# View logs in Vercel dashboard
# Or use Vercel CLI
vercel logs studyquest-frontendThe deployment workflow includes automatic rollback triggers:
Backend Rollback Triggers:
- Basic health check fails (10 attempts)
- Detailed health check fails
- Supabase dependency unhealthy
- OpenRouter dependency unhealthy
Frontend Rollback Triggers:
- Frontend health check fails
- Backend connectivity check fails
- Smoke tests fail (homepage or login)
Option 1: Render Dashboard
- Go to Render Dashboard
- Select studyquest-backend service
- Click "Manual Deploy" tab
- Find previous successful deployment
- Click "Redeploy"
Option 2: Git Revert
# Find the commit to revert to
git log --oneline
# Revert to previous commit
git revert <commit-hash>
# Push to trigger new deployment
git push origin mainOption 1: Vercel Dashboard
- Go to Vercel Dashboard
- Select studyquest-frontend project
- Go to Deployments tab
- Find previous successful deployment
- Click "..." → "Promote to Production"
Option 2: Vercel CLI
# List deployments
vercel ls studyquest-frontend
# Promote previous deployment
vercel promote <deployment-url> --scope=<team-name>Option 3: Git Revert
# Revert to previous commit
git revert <commit-hash>
git push origin mainIf automated systems fail:
-
Disable Auto-Deploy:
# Temporarily disable workflow # Edit .github/workflows/deploy.yml # Change trigger to: workflow_dispatch only
-
Manual Intervention:
- Use platform dashboards (Render/Vercel)
- Redeploy last known good version
- Fix issues in separate branch
- Re-enable auto-deploy after fix
-
Database Rollback:
# If database migrations were applied # Connect to Supabase # Run rollback migrations manually
After rollback:
- Verify services are healthy
- Check health endpoints
- Test critical user flows
- Monitor error rates
- Review logs for issues
- Document rollback reason
- Create fix in separate branch
- Test fix thoroughly before redeploying
Monitor deployment health:
# Backend basic health
curl https://your-backend.onrender.com/health
# Backend detailed health
curl https://your-backend.onrender.com/health/detailed
# Frontend health
curl https://your-frontend.vercel.app/api/healthConfigure notifications:
-
Email Notifications:
- GitHub → Settings → Notifications
- Enable "Actions" notifications
-
Slack Integration:
# Add to workflow - name: Notify Slack uses: 8398a7/action-slack@v3 with: status: ${{ job.status }} webhook_url: ${{ secrets.SLACK_WEBHOOK }}
-
Discord Integration:
- name: Notify Discord uses: sarisia/actions-status-discord@v1 with: webhook: ${{ secrets.DISCORD_WEBHOOK }}
Track key metrics:
- Deployment Frequency: How often you deploy
- Lead Time: Time from commit to production
- Mean Time to Recovery (MTTR): Time to recover from failures
- Change Failure Rate: Percentage of deployments that fail
View in GitHub:
- Actions tab → Workflow runs
- Insights tab → Dependency graph → Deployments
Symptoms:
- Tests pass on local machine
- Tests fail in GitHub Actions
Solutions:
# Check environment differences
# Ensure secrets are configured in GitHub
# Run tests with same environment as CI
cd backend
SUPABASE_URL=<test-url> SUPABASE_KEY=<test-key> pytest
# Check Python/Node versions match
python --version # Should be 3.11
node --version # Should be 18Symptoms:
- Deployment workflow runs for >30 minutes
- No progress in logs
Solutions:
# Cancel workflow
gh run cancel <run-id>
# Check platform status
# Render: https://status.render.com
# Vercel: https://www.vercel-status.com
# Retry deployment
gh workflow run deploy.ymlSymptoms:
- Deployment completes but health checks fail
- Services show as unhealthy
Solutions:
# Check service logs
render logs -s studyquest-backend
vercel logs studyquest-frontend
# Verify environment variables
# Render Dashboard → Environment
# Vercel Dashboard → Settings → Environment Variables
# Test health endpoints manually
curl -v https://your-backend.onrender.com/health/detailed
# Check dependency status
# Verify Supabase is accessible
# Verify OpenRouter API key is validSymptoms:
- Workflow fails with "secret not found"
- Environment variables undefined
Solutions:
# Verify secrets are added
gh secret list
# Check secret names match workflow
# Secrets are case-sensitive
# Re-add secret if needed
gh secret set SUPABASE_URL
# For environment-specific secrets
# Ensure environment is specified in workflowSymptoms:
- Build step fails in workflow
- Dependency installation errors
Solutions:
# Clear cache and retry
# Edit workflow to add:
# cache: false
# Check dependency versions
# Ensure package.json and requirements.txt are up to date
# Test build locally
cd frontend
npm run build
cd backend
pip install -r requirements.txtSymptoms:
- Vercel deployment step fails
- "Invalid token" or "Project not found" errors
Solutions:
# Verify Vercel token
vercel whoami
# Re-link project
cd frontend
vercel link
# Check Vercel project settings
# Ensure build settings are correct
# Regenerate token if needed
# Vercel Dashboard → Settings → TokensSymptoms:
- Render webhook returns error
- Service doesn't start
Solutions:
# Check Render service logs
render logs -s studyquest-backend
# Verify deploy hook URL
# Should be: https://api.render.com/deploy/...
# Check service status
# Render Dashboard → studyquest-backend
# Verify environment variables
# Ensure all required vars are set
# Manual deploy from dashboard
# Render Dashboard → Manual DeployEnable debug logging in workflows:
# Add to workflow file
env:
ACTIONS_STEP_DEBUG: true
ACTIONS_RUNNER_DEBUG: true- Check workflow logs: Actions tab → Failed workflow → View logs
- Review platform status: Render/Vercel status pages
- Test locally: Reproduce issue on local machine
- Check documentation: Platform-specific docs
- Open issue: GitHub repository issues
# Never commit directly to main
git checkout -b feature/my-feature
# Make changes
git push origin feature/my-feature
# Create PR# Good
git commit -m "Add user authentication endpoint"
# Bad
git commit -m "fix stuff"- Run tests locally
- Verify CI passes on PR
- Review code changes
- Test in staging if available
- Watch deployment progress
- Check health endpoints after deploy
- Monitor error rates
- Review logs for issues
- Never commit secrets to code
- Rotate secrets regularly
- Use environment-specific secrets
- Limit secret access
- Update CHANGELOG
- Document breaking changes
- Update API documentation
- Notify team of deployments
- Review Docker Deployment Guide for containerized deployments
- Check Operations Runbook for monitoring and maintenance
- See Production Deployment Guide for detailed production setup