CI/CD Pipeline
We're using GitHub Actions for CI/CD and other automations. We've got the following workflows:
- CI - Checks everything is kosher. Runs when a PR is opened
- Deploy - Deploys Pixelflare to production. Runs when
mainbranch is updated
CI Workflow
The CI workflow (in .github/workflows/ci.yml) runs whenever a pull request is opened/updated, and runs tests and quality checks, to ensure code is good to go.
This works as a matrix, since we have multiple packages, so checks (like lint, format, typecheck, test, code QL, security, etc) need to run in parallel.
graph TD
A[Push/PR] --> B[Setup & Install]
A --> R[Dependency Review]
B --> C[Build]
B --> D[Lint]
B --> E[Format]
B --> F[i18n Checks]
C --> G[TypeCheck]
C --> H[Tests]
C --> I[CI Summary]
D --> I
E --> I
F --> I
G --> I
H --> I
R --> I
I --> J{All Required Passed?}
J -->|Yes| K[Ready to Merge]
J -->|No| L[Blocked]
style A fill:#E0E0E0,stroke:#616161,color:#000
style B fill:#81D4FA,stroke:#01579B,color:#000
style C fill:#64B5F6,stroke:#1565C0,color:#000
style D fill:#64B5F6,stroke:#1565C0,color:#000
style E fill:#64B5F6,stroke:#1565C0,color:#000
style F fill:#FFF176,stroke:#F57F17,color:#000
style G fill:#64B5F6,stroke:#1565C0,color:#000
style H fill:#64B5F6,stroke:#1565C0,color:#000
style R fill:#90CAF9,stroke:#1976D2,color:#000
style I fill:#CE93D8,stroke:#7B1FA2,color:#000
style J fill:#E1BEE7,stroke:#8E24AA,color:#000
style K fill:#81C784,stroke:#2E7D32,color:#000
style L fill:#EF9A9A,stroke:#C62828,color:#000Caching Strategy
We cache aggressively to keep CI fast:
- pnpm store - Shared package cache
- node_modules - Installed dependencies (keyed by commit SHA)
- Build artifacts - Compiled packages (keyed by commit SHA)
Jobs restore these caches so they don't reinstall or rebuild unnecessarily.
Checks Covered
| Check | Packages | Command | Required | Description |
|---|---|---|---|---|
| Build | All | pnpm run build | ✅ | Compiles TypeScript and builds all packages |
| TypeCheck | All (9) | pnpm --filter <pkg> run type-check | ✅ | Validates TypeScript types with tsc or svelte-check |
| Lint | All (9) | pnpm --filter <pkg> run lint | ✅ | Runs ESLint across all packages |
| Format | All (9) | pnpm --filter <pkg> run format:check | ✅ | Checks Prettier formatting |
| Tests | @pixflare/api | pnpm --filter <pkg> run test | ✅ | Runs Vitest test suites |
| Dependency Review | N/A | GitHub Action | ⚠️ | Scans for vulnerable dependencies (PRs only) |
| i18n Checks | @pixflare/i18n | node scripts/stats.js | ⚠️ | Translation coverage and quality |
Legend: ✅ = Required (blocks PR) | ⚠️ = Optional (warnings only)
graph LR
A[Setup] --> B[Build]
A --> C[Lint]
A --> D[Format]
A --> E[i18n]
B --> F[TypeCheck]
B --> G[Tests]Deploy Workflow
The deploy workflow (in .github/workflows/deploy.yml) automatically deploys Pixelflare to production whenever code is merged to main, or can be triggered manually via workflow dispatch.
This is a sequential deployment pipeline that handles infrastructure provisioning, building, and deploying all components of the CDN platform to Cloudflare.
Deployment Steps
The workflow runs a series of Make targets in a specific order to ensure safe, reliable deployments:
- Setup - Configures Node.js, pnpm, and Terraform with caching
- Secrets - Generates
.envfile from GitHub secrets - Pre-flight - Validates environment and dependencies
- Infrastructure - Applies Terraform changes for Cloudflare resources
- Non-Terraform Resources - Sets up resources that can't be managed by Terraform
- Build - Installs dependencies and builds all packages
- Database - Runs D1 migrations
- Deploy - Deploys Workers, frontend (Pages), and docs
- Secrets - Sets Worker environment variables
- Smoke Tests - Validates deployment health
Why Make?
We use Make targets instead of inline scripts because:
- Deployment logic can be tested locally (
make deploy-*) - Same commands work in CI and on developer machines
- Better organization and reusability
- Easier to maintain and debug
graph TD
A[Push to main] --> B[Setup Tools]
B --> C[Generate .env]
C --> D[Pre-flight Checks]
D --> E[Generate TF Vars]
E --> F[Apply Terraform]
F --> G[Non-Terraform Setup]
G --> H[Generate Wrangler Config]
H --> I[Install Dependencies]
I --> J[Build Packages]
J --> K[Migrate Database]
K --> L[Deploy Workers]
L --> M[Deploy Frontend]
M --> N[Deploy Docs]
N --> O[Set Worker Secrets]
O --> P[Smoke Tests]
P --> Q{Tests Pass?}
Q -->|Yes| R[Deployed ✓]
Q -->|No| S[Rollback Alert]
style A fill:#E0E0E0,stroke:#616161,color:#000
style B fill:#81D4FA,stroke:#01579B,color:#000
style C fill:#CE93D8,stroke:#7B1FA2,color:#000
style D fill:#90CAF9,stroke:#1976D2,color:#000
style E fill:#64B5F6,stroke:#1565C0,color:#000
style F fill:#64B5F6,stroke:#1565C0,color:#000
style G fill:#64B5F6,stroke:#1565C0,color:#000
style H fill:#64B5F6,stroke:#1565C0,color:#000
style I fill:#90CAF9,stroke:#1976D2,color:#000
style J fill:#90CAF9,stroke:#1976D2,color:#000
style K fill:#FFB74D,stroke:#E65100,color:#000
style L fill:#BA68C8,stroke:#6A1B9A,color:#FFF
style M fill:#BA68C8,stroke:#6A1B9A,color:#FFF
style N fill:#BA68C8,stroke:#6A1B9A,color:#FFF
style O fill:#CE93D8,stroke:#7B1FA2,color:#000
style P fill:#FFF176,stroke:#F57F17,color:#000
style Q fill:#E1BEE7,stroke:#8E24AA,color:#000
style R fill:#81C784,stroke:#2E7D32,color:#000
style S fill:#EF9A9A,stroke:#C62828,color:#000