Skip to content
Latchkey

CI/CD for NestJS with GitHub Actions

NestJS ships unit and e2e test suites out of the box, and both belong in CI before a build and deploy.

This recipe wires a NestJS app into GitHub Actions. It runs lint, unit tests, and e2e tests against a Postgres service, then builds the app with nest build and deploys on main.

What the pipeline does

  • npm ci
  • Lint
  • Unit tests (jest)
  • e2e tests against Postgres
  • nest build
  • Deploy on main

The workflow

NestJS scaffolds test:e2e separately from test, so run both.

.github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: nest_test
        ports: ["5432:5432"]
        options: >-
          --health-cmd "pg_isready -U postgres"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    env:
      DATABASE_URL: postgres://postgres:postgres@localhost:5432/nest_test
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: npm
      - run: npm ci
      - run: npm run lint
      - run: npm run test
      - run: npm run test:e2e
      - run: npm run build
  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    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
      - run: npm run deploy

Testing against a database

The e2e suite typically boots the full Nest application, so it needs a live database. The postgres service container is reachable at localhost:5432; set DATABASE_URL and let TypeORM or Prisma run migrations during app bootstrap or a pretest step. Use a dedicated nest_test database so e2e runs never collide with unit-test fixtures.

Deploying

After nest build emits dist/, deploy that bundle. Common targets are a container image pushed to a registry, a serverless adapter (Lambda via @nestjs/platform-express), or a PaaS. Keep secrets in GitHub secrets and inject them at deploy time.

Key takeaways

  • Run both npm run test and npm run test:e2e - Nest separates them.
  • e2e tests need a real Postgres service container.
  • Build with nest build and deploy the dist/ output on main.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →