Skip to main content

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:

WorkflowTriggers On
deploy-homepage.ymlapps/homepage/**, packages/shared/**
deploy-docs.ymlapps/docs/**, packages/shared/**
deploy-resume.ymlapps/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 NameService
RENDER_HOMEPAGE_DEPLOY_HOOKHomepage (Web Service)
RENDER_DOCS_DEPLOY_HOOKDocs (Static Site)
RENDER_RESUME_DEPLOY_HOOKResume (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

ApplicationBuild CommandOutput
Homepagenpm install && npm run build.next/
Docsnpm install && npm run buildbuild/
Resumenpm 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 main history clean with one commit per feature
  • onBrokenLinks: 'throw' in Docusaurus catches broken documentation links at build time, preventing deployment of broken docs