Skip to main content

CI/CD Pipeline

Kuviq uses GitHub Actions for continuous integration and deployment.

Current Metrics (March 2026):

  • 402 test suites
  • 6,805 passing tests, 0 skipped
  • Full CI run: ~5 minutes
  • Automatic deployment on push to main/master

Pipeline Overview

Push to main/master

┌─────────────────────────────────────┐
│ Parallel Jobs: │
│ - lint (ESLint) │
│ - typecheck (TypeScript) │
│ - test-unit │
│ - test-integration │
│ - test-api (MSW) │
│ - test-e2e (Playwright) │
└─────────────────────────────────────┘

build (after lint + typecheck)

lighthouse (performance audit)

ci-success (all checks passed)

deploy (only on main/master push)

Version bump + Firebase deploy

Jobs

Lint

Runs ESLint to check code quality and formatting.

Type Check

Runs TypeScript compiler (tsc --noEmit) to verify types.

Test Jobs

  • test-unit: Vitest unit tests
  • test-integration: Vitest integration tests
  • test-api: MSW-based API mocking tests
  • test-e2e: Playwright browser tests

Build

Builds the production application to verify it compiles successfully.

Lighthouse

Runs Lighthouse CI to audit:

  • Performance (budget-enforced LCP/FCP thresholds)
  • Accessibility (target: 95%)
  • Best Practices (target: 95%)
  • SEO (target: 95%)

Quality Gates

The CI pipeline enforces strict quality gates:

  • Bundle size budgets — fails if JS bundle exceeds configured limits
  • Core Web Vitals — LCP and FCP thresholds enforced
  • Zero lint errors — ESLint must pass with 0 warnings
  • Zero type errors — TypeScript strict mode, no errors
  • All tests passing — no skipped tests allowed in CI

Deploy

Only runs on pushes to main or master branch:

  1. Updates version using npm run version:date
  2. Builds the application
  3. Deploys to Firebase Hosting
  4. Pushes version commit back to repository

Local Hooks

Pre-commit Hook

Checks test files follow project standards (using renderWithTheme).

Pre-push Hook

Runs before every git push:

  1. TypeScript type check
  2. ESLint
  3. Unit tests

This catches issues locally before using CI minutes.

GitHub Secrets Required

SecretDescription
FIREBASE_SERVICE_ACCOUNTFirebase service account JSON for deployment

Setting up Firebase Service Account

  1. Go to Firebase Console → Project Settings → Service Accounts
  2. Click "Generate new private key"
  3. Download the JSON file
  4. Add to GitHub: Settings → Secrets → Actions → New repository secret
  5. Name: FIREBASE_SERVICE_ACCOUNT
  6. Value: Paste entire JSON contents

Workflow File

The CI configuration is in .github/workflows/ci.yml.

Skipping CI

To skip CI for a commit (e.g., documentation-only changes):

git commit -m "docs: update readme [skip ci]"

Scheduled Cloud Functions

Trial Processing

The following Cloud Functions run on a daily schedule to manage trial lifecycle:

FunctionScheduleDescription
processTrialExpirationsDailyChecks all trial orgs and transitions expired trials to subscriptionStatus = 'expired'
processAutoExtensionsDaily (within expiration processing)Evaluates pending extension requests against activity thresholds for auto-approval; proactively creates extensions for qualifying orgs with 1 day remaining
sendTrialExpirationEmailsDailySends 3-day warning, 1-day warning, and expired emails to organization owners; deduplicates via trialEmails subcollection
sendTrialOnboardingEmailsDailySends Day 1/3/7/10 onboarding emails with activity-based personalization

All email functions:

  • Support English, Finnish, and Swedish via resolveLanguage()
  • Use Brevo (Sendinblue) for transactional email delivery
  • Track sent emails in organizations/{orgId}/trialEmails subcollection to prevent duplicates
  • Continue processing remaining organizations if an individual send fails

Observability

Kuviq uses Sentry for error tracking and performance monitoring across the entire stack.

Frontend

  • ContextErrorBoundary wraps all context providers and reports errors to Sentry
  • Automatic error capture with user and organization context
  • Performance tracing for page loads and key interactions

Cloud Functions

  • All Cloud Functions are wrapped with Sentry error handlers
  • Captures unhandled exceptions with function name and trigger context
  • Performance monitoring for function execution time

Monitoring

  • View pipeline status: GitHub repo → Actions tab
  • Lighthouse reports: Available as artifacts on failed runs
  • Playwright reports: Available as artifacts on failed runs
  • Sentry dashboard: Real-time error tracking and performance