This document describes the CI/CD pipeline for the MissionPulse monorepo.
pulse/
├── apps/extension/ # Chrome extension (tests, build)
├── apps/landing/ # Static landing page (no CI needed)
└── packages/tsconfig # Shared TypeScript config
All CI jobs run in the apps/extension/ workspace via Turborepo.
MissionPulse uses GitHub Actions for continuous integration and deployment. The pipeline consists of two main workflows:
| Workflow | Trigger | Purpose |
|---|---|---|
ci.yml |
Push to main, PRs | Lint, test, build, coverage |
release.yml |
Git tags (v*) |
Build, package, publish extension |
Runs on every push to main and on all pull requests.
Jobs:
┌─────────────────────────────────────────────────────────────┐
│ CI Pipeline │
├─────────────────────────────────────────────────────────────┤
│ │
│ setup ──► lint ──┐ │
│ │ │ │
│ └──► format ─┼──► test ──┬──► build │
│ │ │ └──► test-e2e (PRs only) │
│ └──► typecheck ┘ │
│ │
└─────────────────────────────────────────────────────────────┘
| Job | Description |
|---|---|
setup |
Compute pnpm cache path |
lint |
Run ESLint on all files |
format |
Check Prettier formatting |
typecheck |
TypeScript strict mode check |
test |
Run unit tests with coverage |
build |
Build extension artifact |
test-e2e |
Run E2E tests (PRs only) |
Features:
- pnpm cache for faster installs
- Coverage upload to Codecov
- Concurrency groups to cancel old runs
- E2E tests only on PRs (cost optimization)
- E2E runs in parallel with
build(no extension artifact required) - E2E bootstraps
@pulse/uiviapnpm --filter @pulse/extension test:e2e - CI excludes
@slowtests (performance, offline); runpnpm test:e2e:fulllocally for the full suite
Triggered by pushing a semantic version tag (e.g., v1.0.0).
Process:
┌─────────────────────────────────────────────────────────────┐
│ Release Pipeline │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. Extract version from tag │
│ 2. Verify manifest.json validity │
│ 3. Bump version in package.json & manifest.json │
│ 4. Build production extension │
│ 5. Create ZIP artifact │
│ 6. Generate changelog from git history │
│ 7. Create GitHub Release with ZIP attached │
│ 8. Publish to Chrome Web Store (if credentials set) │
│ │
└─────────────────────────────────────────────────────────────┘
Version Format:
- Stable:
v1.0.0→ Published to CWS - Pre-release:
v1.0.0-beta.1→ GitHub Release only (skips CWS)
Configure these secrets in your GitHub repository settings:
| Secret | Required For | How to Obtain |
|---|---|---|
CODECOV_TOKEN |
Coverage upload | codecov.io |
CHROME_CLIENT_ID |
CWS publish | Chrome Web Store API |
CHROME_CLIENT_SECRET |
CWS publish | Chrome Web Store API |
CHROME_REFRESH_TOKEN |
CWS publish | Chrome Web Store API |
CHROME_EXTENSION_ID |
CWS publish | Your extension ID |
-
Create OAuth Credentials:
- Go to Google Cloud Console
- Create OAuth 2.0 client ID
- Add authorized redirect URI:
https://oauth2.googleapis.com/token - Note the Client ID and Client Secret
-
Get Refresh Token:
- Use the Chrome Web Store API
- Follow OAuth flow to obtain refresh token
-
Get Extension ID:
- Found in your Chrome Web Store developer dashboard
- Format:
abcdefghijklmnopqrstuvwxyzabcdef
-
Add Secrets to GitHub:
- Go to repo Settings → Secrets and variables → Actions
- Add each secret individually
To skip Chrome Web Store publishing, simply don't configure the CWS secrets. The workflow will log a warning but continue successfully.
# Build for production
pnpm build
# Build with version bump
./scripts/build-extension.sh 1.0.0
# Verify manifest.json
pnpm tsx scripts/verify-manifest.ts
# Bump version only
pnpm tsx scripts/bump-version.ts 1.0.0# 1. Ensure you're on main
git checkout main
git pull
# 2. Create and push tag
git tag v1.0.0
git push origin v1.0.0
# 3. Monitor workflow
gh run watch# Trigger CI manually
gh workflow run ci.ymlConfiguration: .eslintrc.cjs
# Run linting
pnpm lint
# Fix auto-fixable issues
pnpm lint:fixKey Rules:
- No
anytypes - Functional Core isolation (no shell imports from core)
- Svelte 5 runes enforcement
- No Svelte stores (use $state runes)
Configuration: .prettierrc
# Check formatting
pnpm format:check
# Fix formatting
pnpm formatConfiguration: tsconfig.json (strict mode)
# Type check
pnpm tsc --noEmitCoverage is automatically uploaded to Codecov on every CI run.
- Badge: Add to README:
 - Reports: View detailed reports at codecov.io
- Check
pnpm-lock.yamlis committed - Run
pnpm installlocally and commit changes
- Run
pnpm tsc --noEmitlocally - Fix type errors before pushing
- Verify all CWS secrets are set correctly
- Check refresh token hasn't expired
- Ensure extension ID is correct
- All secrets are masked in logs
- No credentials in code or comments
- Workflow permissions use least-privilege principle
- Third-party actions are pinned to specific versions