PrismaのマイグレーションファイルをGitHub Actionsで自動検証する
はじめに
Prismaを使用してデータベースマイグレーションが可能ですが、構文エラーなど、不正なマイグレーションファイルが紛れ込んでしまうと、マイグレーション実行時にエラーが発生してしまいます。それを防ぐために、GitHub Actionsでマイグレーションファイルの整合性をチェックする仕組みを構築します。
準備:Prismaのインストールとスキーマファイル作成
このセクションはGitHub Actionsの設定に必要なファイルを用意するための手順です。すでにPrismaを導入済みの場合はスキップできます。
Prismaをインストールします。今回はマイグレーションの確認のみなので、Prismaクライアントはインストールしません。
npm install prisma --save-dev
以下のコマンドを実行し、初期セットアップをします。
npx prisma init --datasource-provider postgresql
.envファイルに接続文字列の設定をします。この設定は、マイグレーションファイルを生成するための接続先DBを指定するためのものです。
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres?schema=public"
prisma/schema.prismaファイルにusersテーブルを定義します。
model users {
id Int @id @default(autoincrement())
name String @db.VarChar(100)
email String @unique @db.VarChar(255)
created_at DateTime? @default(now()) @db.Timestamp(6)
}
マイグレーションファイルを作成します。ここでは、ローカルDBへの意図しない変更を防ぐため、適用はせず作成のみのオプションを指定します。マイグレーション名を聞かれるため、add_users_tableなどの名前を指定します。
npx prisma migrate dev --create-only
以下のようなマイグレーションファイルが作成されます。
-- CreateTable
CREATE TABLE "users" (
"id" SERIAL NOT NULL,
"name" VARCHAR(100) NOT NULL,
"email" VARCHAR(255) NOT NULL,
"created_at" TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
GitHub Actionsワークフロー作成
このGitHub Actionsでは、以下の3点をチェックします。
- スキーマファイルに構文エラーがないか
- マイグレーションファイルに構文エラーがないか
- マイグレーションファイルとスキーマファイルの整合性が取れているか
また、このGitHub Actionsでは実DBを使用せず、コンテナ内にDBを構築して、それをチェックに使用します。そのため、実DBとのドリフトチェックや、実DBへの適用は行いません。
ワークフロー用のYAMLファイル.github/workflows/prisma-check.yamlを作成します。
name: Prisma Check
# プルリクオープン/更新時に発動
on:
pull_request:
jobs:
prisma-check:
name: Prisma Check
runs-on: ubuntu-latest
services:
# PostgreSQLのコンテナを起動
postgres:
image: postgres:17
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: testdb
ports:
- 5432:5432
# PostgreSQLのヘルスチェックを10秒間隔で5回実行する
# 各ヘルスチェックのタイムアウトは5秒とする
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
# スキーマファイルの構文チェック
- name: Validate schema syntax
run: npx prisma validate
# マイグレーションファイルのSQL構文チェック
- name: Check migration SQL syntax
run: npx prisma migrate deploy
# スキーマファイルとマイグレーションファイルの整合性チェック(Prisma v7)
# migrate deployで適用済みのDBとスキーマを比較する
- name: Check schema / migration consistency
run: |
npx prisma migrate diff \
--from-config-datasource \
--to-schema ./prisma/schema.prisma \
--exit-code
GitHub Actionsがサービスコンテナ(専用のDockerコンテナ)を立ち上げ、その中にPostgreSQLをインストールします。インストール後、DBが接続可能な状態になっているかを確認するため、PostgreSQLのpg_isreadyコマンドをヘルスチェックとして指定します。
その後、3つのチェックを順番に実行します。
validateコマンドは、スキーマファイルの構文エラーをチェックします。
prisma validate | Validate Prisma Schema
migrate deployコマンドは、存在するマイグレーションファイルを適用します。migrate devと異なり、実DBとの差分を検出してマイグレーションファイルを作成することはしません。migrate devはインタラクティブな操作が発生するため、ここではmigrate deployを使用します。
マイグレーションファイルをDBに適用する過程で構文が検証されるため、構文エラーがあればここで検出できます。
prisma migrate dev | Create & Apply Migrations
prisma migrate deploy | Apply Migrations to Production
diffコマンドは、fromとtoを指定して、それらの差分を検出します。
prisma migrate diff | Compare Database Schemas
--from-config-datasourceオプションはPrisma v7から導入されたものです。v6以前の場合は以下のコマンドを使用します。
npx prisma migrate diff \
--from-schema-datasource ./prisma/schema.prisma \
--to-schema-datamodel ./prisma/schema.prisma \
--exit-code
v6以前では、--from-config-datasourceオプションが存在しないため、--from-schema-datasourceでスキーマファイルの接続先DBを参照し、--to-schema-datamodelでスキーマファイルのデータモデル定義と比較します。
動作確認:正常終了
まずはワークフローが正常終了することを確認します。
先ほど作成したusersテーブル追加のマイグレーションファイルをプルリクエストとして作成します。
ワークフローが起動し、以下のようにすべてのチェックが正常終了します。

動作確認:スキーマファイル構文エラー
続いて、schema.prismaを以下のように更新して同じブランチにプッシュします。Numberという型はサポートされていないため、これは構文エラーとなります。
model users {
id Number @id @default(autoincrement()) ← IntをNumberに変更
name String @db.VarChar(100)
email String @unique @db.VarChar(255)
created_at DateTime? @default(now()) @db.Timestamp(6)
}
このように、最初のValidate schema syntaxチェックでエラーになります。

動作確認:マイグレーションファイル構文エラー
schema.prismaを元に戻し、マイグレーションファイルを以下のように更新して同じブランチにプッシュします。
-- CreateTable
CREATE TABLE "users" (
"id" SERIAL NOT NULL,
"name" VARCHAR(100) NOT NULL,
"email" VARCHAR(255) NOT NULL,
"created_at" TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
), ← 文末のセミコロンをカンマに変更
-- CreateIndex
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
このように、2番目のCheck migration SQL syntaxチェックでエラーになります。

動作確認:スキーマファイルとマイグレーションファイルの整合性エラー
最後に、マイグレーションファイルを元に戻し、schema.prismaにpostsテーブルを作成します。スキーマファイルにはpostsテーブルが存在するのに、マイグレーションファイルにはないという状態です。
model posts {
id Int @id @default(autoincrement())
title String @db.VarChar(100)
}
プッシュすると、以下のように、3番目のCheck schema / migration consistencyチェックでエラーになります。

補足
前述の通り、このワークフローでは実DBとのドリフトチェックは行えません。
また、空のDBに対してマイグレーションを実行するため、既存データがある状態でのみ発生するエラーは検出できません。例えば、デフォルト値を指定せずにNOT NULLカラムを追加した場合、既存データがあればエラーになりますが、このワークフローでは検出できません。
おわりに
Prismaマイグレーションファイルのチェックを自動化する仕組みを構築しました。自動化することで、構文エラーや整合性など機械的に判断できる指摘をCIに任せ、要件の妥当性など本質的なレビューに注力することができます。
この記事がどなたかの参考になれば幸いです。







