Goのentでスキーマに変更があったときにGithub Actionsで自動的にマイグレーションファイルを作成するWorkflow

諸処の事情で不要になった代物ですが、自分の備忘録代わりに残しておきます。

## モチベーション
チーム開発でGo言語のORMツールであるEntを使っていると、わりと他人のマイグレーションを取り込み忘れて開発しちゃったテヘ！という事態に遭遇することがあります。
それをなるべく自動で回避するために、自分のPRがマージされたときに、Github Actionsを使って勝手に開発のベースブランチ（今回はdevelop）にマイグレーションファイルを作成・commit・pushしてしまおうというワークフローです。

## 前提条件

* Entのマイグレーションにはdbmateを使用
確かRuby on RailsのActiveRecordのmigrationぽく使える（マイグレーションとロールバック用のSQLどっちも生成される）という理由で採用したような記憶があります。TypeScriptのPrismaのマイグレーションファイルに移植しやすいからという理由もあったような気がします。

* 2022年くらいの実装
ちょっと情報が古いかもなので、適宜アップデートするともっと良いソリューションがあるかもしれない。

* 開発ブランチマージ時に発火する
もしPRのタイミングで自分のコミットに追加したいよ！という場合は発火条件（onの部分）を変えるだけで多分問題ないはず。


## GithubActions

以下、コードです。

```yaml:.github/workflows/develop-migration-ci.yml
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で議論されているものを参照してます。

https://github.com/orgs/community/discussions/26560

これでスキーマが修正されていてもマイグレーションファイルがなくて本番リリース時にエラーが出てしまう！とか、開発時に何度やっても他人の修正部分でコケて自分の処理が実行されない！という不測の事態を軽減することができるでしょう。
実際の運用では本番用のCIにマイグレーションファイルの過不足チェックとして `go generate ./ent` で差分が出ないことを追加で確認するともっと良いかと思います。