CI/CD Pipelines
Deployments are fully automated through GitHub Actions. Each application has two workflows: a PR check (validation on pull requests) and a deploy (production deployment on merge to main).
Pipeline Flow
Developer pushes branch
│
v
Open Pull Request
│
v
pr-check-{app}.yml <-- Runs on PR to main
┌─────────────────┐ (path-filtered)
│ Checkout code │
│ Setup Node 20 │
│ npm ci │
│ npm run build │
└─────────────────┘
│
v
PR approved + merged
│
v
deploy-{app}.yml <-- Runs on push to main
┌─────────────────┐ (path-filtered)
│ Checkout code │
│ Setup Node 20 │
│ npm ci │
│ npm run build │
│ curl deploy hook│ ───────> Render builds + deploys
└─────────────────┘
Path Filtering
Each workflow only triggers when relevant files change:
| Workflow | Triggers On |
|---|---|
deploy-homepage.yml | apps/homepage/**, packages/shared/** |
deploy-docs.yml | apps/docs/**, packages/shared/** |
deploy-resume.yml | apps/resume/**, packages/shared/** |
Changes to packages/shared/** trigger all workflows since shared code affects every application.
Workflow Files
PR Check
Validates that the application builds successfully. Runs on pull requests targeting main.
name: PR Check — {App}
on:
pull_request:
branches: [main]
paths:
- "apps/{app}/**"
- "packages/shared/**"
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- run: npm run build
Production Deploy
Builds the application and triggers a Render deploy hook. Runs when changes are pushed to main.
name: Deploy {App}
on:
push:
branches: [main]
paths:
- "apps/{app}/**"
- "packages/shared/**"
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- run: npm run build
- name: Trigger Render Deploy
run: curl -X POST "${{ secrets.RENDER_{APP}_DEPLOY_HOOK }}"
Render Deploy Hooks
Deploy hooks are stored as GitHub repository secrets:
| Secret Name | Service |
|---|---|
RENDER_HOMEPAGE_DEPLOY_HOOK | Homepage (Web Service) |
RENDER_DOCS_DEPLOY_HOOK | Docs (Static Site) |
RENDER_RESUME_DEPLOY_HOOK | Resume (Web Service) |
When the deploy hook is called, Render pulls the latest code from the repository and runs its own build process.
Render Build Configuration
| Application | Build Command | Output |
|---|---|---|
| Homepage | npm install && npm run build | .next/ |
| Docs | npm install && npm run build | build/ |
| Resume | npm install && npm run build | .next/ |
Key Design Decisions
- Render auto-deploy is disabled — GitHub Actions controls all deployments for consistency and visibility
- Path filtering prevents unnecessary builds when unrelated apps change
- Squash merge keeps
mainhistory clean with one commit per feature onBrokenLinks: 'throw'in Docusaurus catches broken documentation links at build time, preventing deployment of broken docs