弊社では開発以外の部署もマーケティングや分析用のツールでDBを参照しています。 そのため、カラムの変更や削除があったときに影響してしまうことがあります。

そこでスキーマの変更を検知する仕組みを作りました。

アウトプット

  • schema.rb の変更が push された時に変更内容が Slack の通知用チャンネルに通知される

スキーマ変更Slack通知

Github Workflow の実装

name: Notify Slack on schema.rb change

on:
  push:
    branches:
      - master
    # db/schema.rb に変更を push した時
    paths:
      - "db/schema.rb"

jobs:
  notify:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
        with:
          fetch-depth: 2

      - name: Install jq
        run: sudo apt-get install -y jq

      - name: Get diff for schema.rb
        id: get-diff
        run: |
          # master ブランチの前の状態との db/migrate/* 配下の差分を取得
          DIFF=$(git diff HEAD~1 HEAD --unified=0 db/migrate/*)
          echo "$DIFF" > diff.txt

      - name: Get PR associated with commit
        id: get-pr
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          # Pull Reqest の URL を取得する
          PR_URL=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
            "https://api.github.com/repos/${{ github.repository }}/commits/${{ github.sha }}/pulls" \
            | jq -r ".[0].html_url")
          echo "PR_URL=$PR_URL" >> $GITHUB_ENV

      - name: Notify Slack
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        run: |
          PAYLOAD=$(jq -n \
            --arg repo "${{ github.repository }}" \
            --arg pr_url "$PR_URL" \
            --arg diff "$(cat diff.txt)" \
                                        '{text: ("`schema.rb` has changed in repository " + $repo + "\nPR: " + $pr_url + "\n```\n" + $diff + "\n```")}')

          curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" $SLACK_WEBHOOK_URL

他にも応用できそう

  • GraphQL のスキーマ変更の通知
  • その他、特定のファイルの変更を検知したい時に使えそう、、、?