トレタ開発者ブログ

飲食店向け予約/顧客台帳サービス「トレタ」、モバイルオーダー「トレタO/X」などを運営するトレタの開発メンバーによるブログです。

GitHub ActionsとtblsでDBスキーマ変更に対応するER図の自動生成する

はじめに

こんにちは、サーバーサイドエンジニアの @shiroemons です。

プルリクエストにDBスキーマの変更が含まれた場合、ER図を自動生成するために、tblsとGitHub Actionsを組み合わせた設定を行いました。

DBスキーマの変更は開発プロセスにおいて頻繁に発生しますが、手動でER図やドキュメントを更新することは煩雑で効率が悪い作業です。 そこで、GitHub Actionsとtblsを使用することで、ER図の自動生成と更新を容易に実現できました。

今回は、設定したGitHub Actionsの設定ファイルを紹介します。

必要なツールと環境

今回紹介するツールと環境はこちらです。

  • CI: GitHub Actions
  • DB: PostgreSQL
  • マイグレーションツール: psqldef
  • テーブル定義書作成: tbls

tbls について

github.com

tblsは、データベースのスキーマ情報をドキュメント化するためのコマンドラインツールです。データベースからスキーマ情報を取得し、MarkdownやPlantUMLなどの形式で出力することができます。

このツールを使用することで、データベースのスキーマ情報をわかりやすく、自動化された形でドキュメント化することができます。tblsは、PostgreSQL, MySQL, SQLite, Microsoft SQL Server など、複数のデータベース管理システムに対応しています。

ディレクトリ構成と設定ファイルの説明

ディレクトリ構成

  • .github/workflows/tbls.yml
    • 今回解説するGitHubActionsのファイル
  • db/schema/*.sql
    • スキーマファイル群
  • db/dbdoc/
    • tblsのER図自動生成先
  • db/tbls.yml
    • tblsの設定ファイル
    • 設定ファイルの中身は後述

設定内容

.github/workflows/tbls.yml

こちらが今回作成したGitHub Actionsの内容です。

name: tbls
on:
  pull_request:
    types:
      - opened
      - synchronize
      - reopened
    paths:
      - db/schema/*.sql
      - db/tbls.yml
    branches-ignore:
      - production
      - staging

jobs:
  tbls:
    name: generate-and-push
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    services:
      postgres:
        image: postgres:15-alpine
        ports:
          - 5432:5432
        env:
          POSTGRES_HOST_AUTH_METHOD: trust
          POSTGRES_DB: sampledbname
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    env:
      TBLS_DSN: "postgres://postgres:@127.0.0.1:5432/sampledbname?sslmode=disable"
      TBLS_DOC_PATH: "db/dbdoc"
    steps:
      - uses: actions/checkout@v3
        with:
          repository: ${{ github.event.pull_request.head.repo.full_name }}
          ref: ${{ github.event.pull_request.head.ref }}
      - uses: actions/setup-go@v3
        with:
          go-version: ^1.20
      - name: Execute migration
        run: |
          go install github.com/k0kubun/sqldef/cmd/psqldef@latest
          psqldef --file schema.sql sampledbname
        working-directory: ./db/schema
      - name: Remove dbdocs
        run: |
          rm -rf ./*.md ./*.svg
        working-directory: ./db/dbdoc
      - uses: k1low/setup-tbls@v1
      - name: Run tbls for generate database document
        run: |
          tbls doc -c ./db/tbls.yml -f
      - name: Count uncommit files
        id: check_diff
        run: |
          git status --porcelain | wc -l
          file_count=$(git status --porcelain | wc -l)
          echo "file_count=$file_count" >> $GITHUB_OUTPUT
        working-directory: ./db
      - name: Commit ER graph
        if: ${{ steps.check_diff.outputs.file_count != '0' }}
        uses: EndBug/add-and-commit@v9
        with:
          default_author: github_actions
          message: "CI: ER diagram and markdown update triggered by actions"
      - name: Report commit on pull request
        if: ${{ steps.check_diff.outputs.file_count != '0' }}
        uses: actions/github-script@v6
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: 'CI: ER diagrams and markdown auto-committed by Actions 🤖'
            })

docs/tbls.yml

tblsのER図の自動生成ではデフォルトでコメントを出力しない設定となっています。

コメントも出力されるように設定ファイルに記載しています。

er:
  # Add table/column comment to ER diagram
  # Default is false
  comment: true

GitHub Actionsワークフローの解説

ワークフローのトリガーを設定する

プルリクエストが開かれた、同期された、再開された場合に、このGitHub Actionsがトリガーされます。また、db/schema/*.sql および db/tbls.yml の内容が変更されたときにのみ実行されます。

マージ先がstaging、productionブランチの場合、発火しないようにしています。

on:
  pull_request:
    types:
      - opened
      - synchronize
      - reopened
    paths:
      - db/schema/*.sql
      - db/tbls.yml
    branches-ignore:
      - production
      - staging

パーミッションを設定する

  • contents: write: リポジトリのコンテンツに対して書き込み権限を持ちます。これにより、github-actions[bot] がコミットおよびプッシュすることができます。
  • pull-requests: write: プルリクエストに対して書き込み権限を持ちます。これにより、プルリクエストにコメントを追加することができます。
    permissions:
      contents: write
      pull-requests: write

データベースを事前に起動する

今回は、以下のように宣言し、PostgreSQLを起動しておきます。

    services:
      postgres:
        image: postgres:15-alpine
        ports:
          - 5432:5432
        env:
          POSTGRES_HOST_AUTH_METHOD: trust
          POSTGRES_DB: sampledbname
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

環境変数を設定する

プロセスに必要な環境変数が設定されています。

データベース接続用のDSNやドキュメントのパスを指定しています。

    env:
      TBLS_DSN: "postgres://postgres:@127.0.0.1:5432/sampledbname?sslmode=disable"
      TBLS_DOC_PATH: "db/dbdoc"

コードをクローンしてGitHubの設定をする

      - uses: actions/checkout@v3
        with:
          repository: ${{ github.event.pull_request.head.repo.full_name }}
          ref: ${{ github.event.pull_request.head.ref }}

マイグレーションを実行する

  • Go言語をセットアップします。
    • マイグレーションツールとして、psqldefを使用しています。
    • psqldefはGo言語で作成されているため、Go言語をセットアップしておきます。
      - uses: actions/setup-go@v3
        with:
          go-version: ^1.20
  • マイグレーションを実行します。
    • psqldef を go install でインストールします。
    • その後にマイグレーションを実行します。
      - name: Execute migration
        run: |
          go install github.com/k0kubun/sqldef/cmd/psqldef@latest
          psqldef --file schema.sql sampledbname
        working-directory: ./db/schema

ER図関連のファイルを削除

スキーマの変更でテーブルの削除が含まれる場合は、ファイルを削除していないとそのまま残り続けることとなります。そのため、ER図を自動生成する前にファイルを削除しておきます。

      - name: Remove dbdocs
        run: |
          rm -rf ./*.md ./*.svg
        working-directory: ./db/dbdoc

tblsには、--rm-distというオプションが用意してあります。 今回、tblsには生成の責務に集中してもらうためオプションは使用せずに明示的に削除するようにしました。

tblsのセットアップと実行

  • tblsをセットアップする
    • tblsには、GitHub Actionsで簡単に使用できるためのActionが用意されています。
    • この一文を記載することで tbls を使用できるようになります。
      - uses: k1low/setup-tbls@v1

参照: k1low.hatenablog.com

  • tblsの実行し、ER図を生成する
    • tblsを実行する際、ER図にコメントを含めるためにtblsの設定ファイルを指定します。
      - name: Run tbls for generate database document
        run: |
          tbls doc -c ./db/tbls.yml -f

ER図に差分がある場合、プルリクエストに対してその差分をコミットする

  • 差分ファイル数を取得する
      - name: Count uncommit files
        id: check_diff
        run: |
          git status --porcelain | wc -l
          file_count=$(git status --porcelain | wc -l)
          echo "file_count=$file_count" >> $GITHUB_OUTPUT
        working-directory: ./db
  • 差分ファイルをコミットする
    • 差分ファイルがある場合のみコミットされるように条件を設定しています。
    • GitHub Actionで簡単にAdd と Commit ができる EndBug/add-and-commitを使用しました。 github.com
      - name: Commit ER graph
        if: ${{ steps.check_diff.outputs.file_count != '0' }}
        uses: EndBug/add-and-commit@v9
        with:
          default_author: github_actions
          message: "CI: ER diagram and markdown update triggered by actions"

プルリクエストにER図を更新した旨をコメントする

こちらも同様に、差分ファイルがある場合のみプルリクエストにコメントするように条件を設定しています。

      - name: Report commit on pull request
        if: ${{ steps.check_diff.outputs.file_count != '0' }}
        uses: actions/github-script@v6
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: 'CI: ER diagrams and markdown auto-committed by Actions 🤖'
            })

まとめ

ER図を自動生成してくれるGitHub Actionsの設定ファイルを紹介しました。

今回は、紹介した設定はGoプロジェクトですが、マイグレーションの設定部分を変更することで Ruby on Railsのプロジェクトでも応用が効きます。

GitHub Actionsとtblsの組み合わせによる自動化は、開発効率向上、品質保持、そして情報共有の容易化に貢献します。

また、柔軟なカスタマイズ性を持つため、チームのニーズに応じて機能拡張や改善が容易に実現可能です。

参考記事

大変参考になりました。ありがとうございます。

tblsとGitHub Actionsを使ってDBマイグレーションを含むPRには自動更新したER図を追加する - BASEプロダクトチームブログ

© Toreta, Inc.

Powered by Hatena Blog