諸処の事情で不要になった代物ですが、自分の備忘録代わりに残しておきます。
モチベーション
チーム開発でGo言語のORMツールであるEntを使っていると、わりと他人のマイグレーションを取り込み忘れて開発しちゃったテヘ!という事態に遭遇することがあります。
それをなるべく自動で回避するために、自分のPRがマージされたときに、Github Actionsを使って勝手に開発のベースブランチ(今回はdevelop)にマイグレーションファイルを作成・commit・pushしてしまおうというワークフローです。
前提条件
-
Entのマイグレーションにはdbmateを使用
確かRuby on RailsのActiveRecordのmigrationぽく使える(マイグレーションとロールバック用のSQLどっちも生成される)という理由で採用したような記憶があります。TypeScriptのPrismaのマイグレーションファイルに移植しやすいからという理由もあったような気がします。 -
2022年くらいの実装
ちょっと情報が古いかもなので、適宜アップデートするともっと良いソリューションがあるかもしれない。 -
開発ブランチマージ時に発火する
もしPRのタイミングで自分のコミットに追加したいよ!という場合は発火条件(onの部分)を変えるだけで多分問題ないはず。
GithubActions
以下、コードです。
name: develop-migration-ci
on:
push:
branches:
- develop
paths:
- "app/ent/schema/**"
- "app/ent/migrate/**"
- "app/go.mod" # go.modが編集された場合も実行
- ".github/workflows/*" # CIが変更されてもとりあえず実行
jobs:
# 共通処理
setup:
runs-on: ubuntu-latest
steps:
- name: set up
uses: actions/setup-go@v3 # すでにv5が出てる
with:
go-version: ^1.20
id: go
- name: check out
uses: actions/checkout@v3
# 処理を高速化するために環境をキャッシュ
# TODO: uses: actions/setup-go@v3だけでよいらしい
# 参考: https://trap.jp/post/1655/
- name: Cache
uses: actions/cache@v2.1.0
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
# dbmateでマイグレーションを実行
dbmate-migrate:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15.0-bullseye
# refer: https://hub.docker.com/_/postgres
env:
POSTGRES_PASSWORD: password
POSTGRES_USER: postgres
POSTGRES_DB: my-app-db
ports:
- 5432:5432
steps:
# 現状の状態でdbmateでマイグレーションを実行
- uses: actions/checkout@v3
- name: dbmate migrate
working-directory: ./app
env:
DATABASE_URL: postgres://postgres:password@127.0.0.1:5432/my-app-db?sslmode=disable
run: |
curl -fsSL -o /usr/local/bin/dbmate https://github.com/amacneil/dbmate/releases/latest/download/dbmate-linux-amd64
chmod +x /usr/local/bin/dbmate
dbmate -d ent/migrate/migrations up
# entのスキーマ定義からマイグレーションファイルを作成
# 生成されたファイルはGitHubActionsユーザーのコミットとしてpushされる
- uses: actions/checkout@v3
- name: generate ent files
working-directory: ./app
run: |
go generate ./ent
go run -mod=mod ent/migrate/main.go migrate_${{ github.sha }}
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git pull origin develop
git add ./ent/migrate/migrations
git commit -m "ent: generate files"
git push
Github Actionsのユーザーについては 41898282+github-actions[bot]@users.noreply.github.com
としていますが、これは以下のIssueで議論されているものを参照してます。
これでスキーマが修正されていてもマイグレーションファイルがなくて本番リリース時にエラーが出てしまう!とか、開発時に何度やっても他人の修正部分でコケて自分の処理が実行されない!という不測の事態を軽減することができるでしょう。
実際の運用では本番用のCIにマイグレーションファイルの過不足チェックとして go generate ./ent
で差分が出ないことを追加で確認するともっと良いかと思います。