GitHub Actions で MySQL + Rails の構成で Annotateを実行してPRを作成する

2021/11/08に公開

概要

MySQL + Railsの構成の時 GitHub Actionsで Annotateを使ってモデルにコメントをつけたので、その備忘録です。

Gist

これ見れば特に
https://gist.github.com/junara/99df854e984ae283c38117c865bf2845

背景

Annotate。コメントつけてくれるので便利ですよね。とくに modelにコメントがついているととても便利。
modelを見るときはカラムに意識がある時だと思いますが、素のままだと当然カラムがわからない。schema.rbをみればいいのですがそこへの動線も特にない。
ベタですが、modelにschema書かれているとやっぱ便利なのですよ。

で、このschemaですが、migrationと同時に追加するように設定していることが多いとおもいます。
Annotate: Configuration in Rails

    'skip_on_db_migrate'   => 'false',

しかしこれを忘れることもままあります。頻度も多くないでしょうから、気づいたときにやればよいです。

実際、僕も以下のコマンドをたまーに打ってたりします。

bundle exec annotate --models

これで十分事足りています。

・・・でも、エンジニアなのでできればこの作業もボタン一発で自動化したい、ですよね。ですよね。

ということでGitHub Actionsを作りました。

実現したこと

Annotateでモデルにコメントをつけて、Pull Requestを作成するというのを任意のタイミングでGitHub Actionsでできるようにする。

環境

Rails(6.1で試しましたが、annotateが動けばなんでも良いです。)
Annotate

方法

Annotateはデータベースのschemaを見ています。(ただしくは、データベースをmigratonしていないと全くコメントが作られなかったので、そういうふうに考察しています。)

なので、コメントつけるだけですが、データベースのmigrationが必要です。

選択肢としては下記2つ。

  • 動的にdatabase.ymlをsqlite3に対応する似ように書き換えてmigrationする
  • GitHub Actions内でMySQLコンテナを用意してmigrationする

今回CIでGitHub Actionsを作っていればMySQLコンテナも読めるようになっているだろうと思うのでGitHubActions内でMySQLコンテをたてる方法をとりました。

一方Pull Requestの作成は https://github.com/peter-evans/create-pull-request を使いました。 上記ページのサンプルをそのままです。

具体的なコード共に説明します。

database.yml

下記の様なdatabase.ymlを作りました。ポイントというほどではないですが、パラメータを環境変数としています。CIを導入している場合はきっと同じような感じになっているかと思います。

今回は、test環境のみ使います。

config/database.yml

default: &default
  adapter: mysql2
  host: <%= ENV['MYSQL_HOST'] || '127.0.0.1' %>
  port: <%= ENV['MYSQL_PORT'] || 3306 %>
  encoding: utf8mb4
  charset: utf8mb4
  collation: utf8mb4_unicode_ci
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  database: <%= ENV['MYSQL_DATABASE'] || 'junara_annotate_development' %>
  username: <%= ENV['MYSQL_USER'] || 'root' %>
  password: <%= ENV['MYSQL_PASSWORD'] || 'password' %>

test:
  <<: *default
  database: junara_annotate_test
  username: root
  password: password

production:
  <<: *default
  database: junara_annotate_production

GitHub Actions 用 yaml

GitHub Actionsを定義します。

MySQL+RailsでGitHub ActionsでCIを組んでいる場合は定番の構成です。

Pull Request作成も https://github.com/peter-evans/create-pull-request に書かれているものから削ったものです。

ポイントは、git checkout db/schema.rb です。データベースの構成が完全に一致させていないのでschema.rbに差分が出てしまいます。しかし、今回の着目はshcema.rbではないので、差分をなかったことにします。

.github/workflows/main.yml

name: Annotate
on:
  workflow_dispatch: # Actionsタブから実行できるようにする。

jobs:
  createAnnotatePullRequest:
    services:
      mysql:
        image: mysql:5.7
        env:
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: junara_annotate_test
        ports:
          - 3306:3306
        options: --health-cmd "mysqladmin ping" --health-interval 10s --health-timeout 5s --health-retries 10

    strategy:
      fail-fast: false
      matrix:
        os: [ ubuntu-latest ]
        ruby: [ 3.0 ] # ruby version指定。matrixでなくても可。

    env:
      ENV: test
      MYSQL_HOST: 127.0.0.1 # localhostだとつながらない
      MYSQL_PORT: 3306
      MYSQL_DATABASE: junara_annotate_test # servicesの MYSQL_DATABASEと合わせる
      MYSQL_USER: root
      MYSQL_PASSWORD: password # servicesの MYSQL_ROOT_PASSWORDとあわせる
    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v2
      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby }}
          bundler-cache: true # cacheする。

      - name: Run annotate
        run: |
          bundle exec rails db:migrate:reset # annotateが読み取れるようにmigrationし直す
          bundle exec annotate --models --with-comment # annotateを実行する

      - name: Skip db/schema.rb
        run: |
          git checkout db/schema.rb # mysqlの起動設定が、異なるといつもとことなる schema.rbがcommitされてしまうので、commitされないようにする。

      - name: set datetime_str to env
        run: |
          echo "DATETIME_STR=$(date '+%Y%m%d%H%M%S')" >> $GITHUB_ENV # PRのTITLEに日付を入れるため

      - name: Create Pull Request
        id: cpr
        uses: peter-evans/create-pull-request@v3 # GitHub ActionsでPull requestを作る時の定番
        with:
          token: ${{ secrets.GITHUB_TOKEN }} # committerがGitHubならこれでOK
          commit-message: Update annotate # コミットメッセージ
          committer: GitHub <noreply@github.com>
          author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> # ここら辺変更する場合は tokenの変更も必要そう(未確認)
          signoff: false
          branch: create-pull-request/annotate/${{ env.DATETIME_STR }} # ブランチ名。
          delete-branch: true
          title: '[Annotate] annotate --models --with-comment'
          body: |
            - Update model annotations
            - Auto-generated by [create-pull-request][1]

            [1]: https://github.com/peter-evans/create-pull-request
          draft: false
          base: development # PRを作成するベースブランチ。このGitHub Actionsを実行する時にここからbranchを作成し、ここに(developmentブランチに)PRを作成する。

Discussion