henrik's little blog

Deploying Prisma Migrations via Github Actions

#databases #prisma

Do you use Prisma? Do you want to engage in proper practices? Well here’s a post for you! In this post, we will discuss how to automatically deploy Prisma migrations with Github Actions.

Why would this be necessary?

Generally speaking, it’s not a great idea to use a single database in production and development. However, with relational databases, this becomes tricky: How do we make sure that the schema matches what the program expects in any given environment? Prisma alone is a great help in this regard with the prisma migrate command which assures that schema migrations are safely performed. There is still a remaining issue though: When we change the schema and perform a migration, we also want that migration to be executed on the production database when the app is updated. Github Actions provides a perfect solution to this: we can create an action which runs on any given event when the folder prisma/migrations changes. This action can then run the prisma migrate deploy command to update the database.

Writing the Github Action

This mini-tutorial requires prerequisite knowledge about how to write an Action. We’ll just be going over the necessary elements for this tutorial.

on:
  push:
    branches: [main]
    paths:
      - "./prisma/**/*.*"

This example is simply saying “Run this action when a push is made to the main branch and when changes to the prisma folder are made.” I include the prisma folder as a whole because I also have a step that generates the Client as a test.

steps:
  - name: Setup Nodejs
    uses: actions/setup-node@v2
    with:
      node-version: 16.x
      cache: "yarn"

In this case, I am using the most recent LTS version of Nodejs and using the yarn caching setting. You can also set it to npm or pnpm.

- name: Deploy Migrations
  run: npx prisma migrate deploy
  env:
    DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}

I like to use npx for this task. Make sure to set the PROD_DATABASE_URL secret in your repository!

That’s pretty much it! This is one of those little automations that makes things easier and eliminates a point of failure. No more forgetting to deploy migrations and getting Prisma errors!

Just for reference,

this is what my actions file looks like.

name: Prisma Migrate

on:
  push:
    branches: [main]
    paths:
      - "./prisma/**/*.*"
  workflow_dispatch:
    branches: [main]

jobs:
  install:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Setup Nodejs
        uses: actions/setup-node@v2
        with:
          node-version: 16.x
          cache: "yarn"

      - name: Install
        run: yarn install
      - name: Rerun Install
        run: yarn install

  generate:
    runs-on: ubuntu-latest

    needs: install

    steps:
      - uses: actions/checkout@v2

      - name: Setup Nodejs
        uses: actions/setup-node@v2
        with:
          node-version: 16.x
          cache: "yarn"

      - name: Install
        run: yarn install

      - run: rm -rf node_modules/.prisma

      - name: Generate Prisma Client
        run: npx prisma generate

  migrate:
    runs-on: ubuntu-latest

    needs: install

    steps:
      - uses: actions/checkout@v2

      - name: Setup Nodejs
        uses: actions/setup-node@v2
        with:
          node-version: 16.x
          cache: "yarn"

      - name: Install
        run: yarn install

      - run: rm -rf node_modules/.prisma

      - name: Deploy Migrations
        run: npx prisma migrate deploy
        env:
          DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}

Note: The way that Markdown processes tabs is a little weird so not everything is indented correctly.