Skip to content
Latchkey

CI/CD for a Phoenix LiveView App with GitHub Actions

Format-check, test, and build your Phoenix LiveView app on every push.

A Phoenix LiveView app pairs server-rendered, stateful views with an Ecto/Postgres data layer. This recipe checks formatting, runs Credo and the test suite against Postgres, builds assets, and assembles a release.

What the pipeline does

  • install deps with mix deps.get
  • check formatting with mix format --check-formatted
  • lint with mix credo
  • test against Postgres with mix test
  • build assets and assemble a mix release

The workflow

A Postgres service container backs Ecto during tests; erlef/setup-beam installs Elixir and Erlang. mix assets.deploy builds and digests static assets for the release.

.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: postgres
        ports: ['5432:5432']
        options: >-
          --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
    env:
      MIX_ENV: test
      DATABASE_URL: ecto://postgres:postgres@localhost/app_test
    steps:
      - uses: actions/checkout@v4
      - uses: erlef/setup-beam@v1
        with:
          otp-version: '27'
          elixir-version: '1.17'
      - run: mix deps.get
      - run: mix format --check-formatted
      - run: mix credo --strict
      - run: mix test

Caching and speed

Cache deps and _build with actions/cache keyed on mix.lock to skip recompiling dependencies. The Postgres service and compile dominate first-run time; cheaper managed runners such as Latchkey keep frequent runs affordable and auto-retry transient Hex fetch failures.

Deploying

Run mix assets.deploy then MIX_ENV=prod mix release to build a self-contained release, containerize it, and push to GHCR or ECR. Run Ecto migrations via the release eval step before traffic, then deploy to Fly, Kubernetes, or a VM.

Key takeaways

  • Back Ecto tests with a Postgres service container.
  • Cache deps and _build on mix.lock to skip recompiles.
  • mix release produces a self-contained deployable artifact.

Related guides

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