CI/CD

Continuous integration and deployment pipelines.

Pipeline Architecture

The CI/CD system is built on GitHub Actions with self-hosted runners deployed on the EKS cluster. This gives you the flexibility of GitHub Actions workflows with the performance and security of runners inside your own infrastructure.

Pipeline flow
text
Push / PR                Build                    Deploy
─────────── ──────────────────────────── ──────────────────────
│ Commit  │ → │ Lint → Test → Build  │ → │ ECR Push → Helm  │
│ to main │   │  (self-hosted runner) │   │  upgrade (bot)   │
───────────   ────────────────────────    ──────────────────────

Pull requests trigger the build and test stages, while merges to the main branch trigger the full pipeline including Docker image builds and deployment.

GitHub Actions

Workflows are defined in .github/workflows/ and use reusable workflow templates for consistency across repositories. Self-hosted runners in the ci namespace provide fast build times with access to shared build caches.

.github/workflows/ci.yaml
yaml
name: CI
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
 
jobs:
  build:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "yarn"
 
      - run: yarn install --immutable
      - run: yarn lint
      - run: yarn test
      - run: yarn build

Self-hosted runners use persistent volumes for Yarn and Docker layer caches, significantly reducing build times compared to GitHub-hosted runners.

Build Process

The build process follows a standardized pipeline that ensures code quality before any image is published:

  • Lint — ESLint with flat config validates code style and catches common issues.
  • Test — Jest (TypeScript) or pytest (Python) runs unit and integration tests.
  • Docker Build — Multi-stage Dockerfile creates an optimized production image.
  • ECR Push — The built image is tagged and pushed to the private ECR registry.
Dockerfile (multi-stage)
dockerfile
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json yarn.lock .yarnrc.yml ./
COPY .yarn .yarn
RUN yarn install --immutable
COPY . .
RUN yarn build
 
# Production stage
FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]

Deployment Pipeline

After a successful build, the deployment pipeline handles rolling out the new image to the target environment. Deployments are performed as Helm upgrades, ensuring atomic rollouts with automatic rollback on failure.

Deployment flow
bash
# 1. Tag and push image
docker tag my-service:latest \
  <account>.dkr.ecr.us-east-1.amazonaws.com/my-service:v1.2.3
docker push <account>.dkr.ecr.us-east-1.amazonaws.com/my-service:v1.2.3
 
# 2. Helm upgrade (handled by riven-github-bot)
helm upgrade my-service ./charts/js-service-base \
  --namespace dev-center \
  --set image.tag=v1.2.3 \
  --wait --timeout 5m
 
# 3. Verify deployment
kubectl rollout status deployment/my-service -n dev-center

The --wait flag ensures the Helm upgrade only succeeds if all pods become healthy within the timeout. If the rollout fails, Helm automatically rolls back to the previous release.

riven-github-bot

The riven-github-bot is a custom CI/CD bot that orchestrates the deployment process. It runs as a service in the cluster and reacts to GitHub webhook events to automate the full build-deploy lifecycle.

Key capabilities of the bot include:

  • Workspace detection — Automatically detects which services changed in a monorepo and triggers builds only for affected packages.
  • Proto sync — Detects changes to .proto files and triggers codegen across dependent services.
  • Automated deployments — Performs Helm upgrades after successful builds, with configurable approval gates for production.
  • Status reporting — Posts build and deployment status back to GitHub PRs as check runs and comments.

Production deployments require manual approval through the GitHub PR review process. The bot will not auto-deploy to production without at least one approved review.

Next Steps