はじめに
QualiArts Advent Calendar 2020 - Qiita、7日目担当の鈴木光です
今回はGo言語とGitHub Actionsについてのお話をさせていただきます
自動生成
Go言語は言語仕様上、自動生成によるコード実装が多い言語です
例えば
自動生成したコードは普通にgit commit
しないといけません
ただ、そのうち自動生成コマンド自体の数が増えてくると、コミットの中に漏れが発生することがあります
もちろん、これらが漏れていたからといってアプリケーションが必ずしも動作しないわけではありません
テスト対象によってはmockコードがなくても通る場合はありますし、そもそもORMなどは漏れること自体があまりないでしょう
しかし、自動生成を忘れた人以外の人がそれらを生成した際に、自分の変更範囲外のものまで生成されるとちょっとアレじゃないでしょうか?
今回はその漏れを見逃さないようにGitHub Actionsを用いてチェックする方法をご紹介します
実装
今回は次の3つについて、GitHub Actions上で自動生成が漏れていないかチェックする実装を行っていきます
また、基本的に自動生成が漏れていないかチェックするだけなら
- コードを生成
git diff --quiet
でチェック(diffがある場合は終了コードが1になる)
だけで済みます
ORMのコード&単純なCRUD API
現在sqlboilerという既存DBから実装コードを生成するタイプのORMを利用しています
Go言語だとやはりgormをよく見かけますが、sqlboilerはタイプセーフなコードを生成できてパフォーマンスも良いのでお気に入りです
加えてマスターデータを操作する単純なCRUD APIを自動で生成しており、カラム追加時などにちょくちょく忘れてしまうのでチェックしたいと思います(むしろこちらがメイン)
また、DBマイグレーションのツールとしてdbmateを使っています。非常に使い勝手が良いのでぜひ使ってみてください
name: Check autogen db code on: pull_request: branches: - master - 'feature/**' paths: - 'db/migrations/*' # マイグレーションファイルに変更があった時だけ実行 jobs: check-autogen-db: runs-on: ubuntu-latest services: mysql: image: mysql:5.7 ports: - 3306:3306 env: MYSQL_ROOT_PASSWORD: root steps: - name: Checkout code uses: actions/checkout@v2 - name: Setup golang uses: actions/setup-go@v2 with: go-version: 1.14.10 - name: Cache Go Modules uses: actions/cache@v2.1.3 id: cache with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- - name: Download Modules if: steps.cache.outputs.cache-hit != 'true' run: go mod download - name: Migration database uses: docker://amacneil/dbmate:v1.10.0 env: DATABASE_URL: mysql://root:root@mysql:3306/hoge with: args: --wait --no-dump-schema up - name: Setup tools run: GO111MODULE=off go get github.com/volatiletech/sqlboiler github.com/volatiletech/sqlboiler/drivers/sqlboiler-mysql - name: Generate entity run: sqlboiler mysql --wipe - name: Check diff run: git add . && git diff --cached --quiet - name: Show diff if failure if: ${{ failure() }} run: git diff --cached - name: Generate master api run: make gen-masterapi # マスターデータ操作APIを自動生成する独自実装 - name: Check diff run: git add . && git diff --cached --quiet - name: Show diff if failure if: ${{ failure() }} run: git diff --cached
テストで使うmockコード
お次はmockコードの生成です
現在テストライブラリとしてアサーションにtestify、mock生成にmockeryを利用しています
自動生成コードなど一部のファイルをテスト対象から外しているケースでそこへ変更があった際に生成を忘れがちです(そもそも生成対象からはずせよっていう話でもありますがw)
name: Check autogen mock code on: pull_request: branches: - master - 'feature/**' paths: - 'pkg/**' jobs: check-autogen-mock: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Generate mock run: rm -rf mock && docker run -v ${PWD}:/src -w /src vektra/mockery:latest --all --dir=./pkg --keeptree --outpkg=mock --output=mock --disable-version-string # dockerコマンドも使える - name: Check diff run: git add . && git diff --cached --quiet - name: Show diff if failure if: ${{ failure() }} run: git diff --cached
APIドキュメント
最後はAPIドキュメントです
前提として現在のプロジェクトではコードに埋め込んだアノテーションからSwagger Specを生成する手法をとっており、go-swaggerを利用しています
GitHubのリポジトリにSwagger Specを置く運用をしているのですが、APIのリクエスト・レスポンスを更新した時に生成を忘れてしまうなどはよくあるユースケースです
そんな時はGitHub ActionsにSwaggerの生成とドキュメントのコミットまでやってもらいましょう
同一リポジトリ内にコミットするなら非常に簡単なのですが、今回はドキュメント専用の別リポジトリに対してコミットしたかったのでdeploy keysを利用します
こちらのリポジトリにはシークレット情報としてDOCS_REPO_DEPLOY_KEY
という名前で秘密鍵を設定します。ドキュメント側のリポジトリには公開鍵を登録しておきましょう
name: Generate Swagger Spec on: push: branches: - master paths: - 'pkg/presentation/http/router.go' - 'pkg/presentation/http/request/**' - 'pkg/presentation/http/response/**' jobs: generate-swagger: runs-on: ubuntu-latest env: DOCKER_WORKDIR: /github/workspace SPEC_PATH: spec/swagger.yaml steps: - name: Checkout code uses: actions/checkout@v2 - name: Swagger specを生成 uses: docker://quay.io/goswagger/swagger:latest with: args: generate spec -m -o ${{env.DOCKER_WORKDIR}}/${{env.SPEC_PATH}} - name: deploy keyをセットアップ env: DOCS_REPO_DEPLOY_KEY: ${{secrets.DOCS_REPO_DEPLOY_KEY}} run: | echo "$DOCS_REPO_DEPLOY_KEY" > ~/deploy_key.pem chmod 600 ~/deploy_key.pem - name: diffがあればdocs用リポジトリにcommit&push env: GIT_SSH_COMMAND: ssh -i ~/deploy_key.pem -o StrictHostKeyChecking=no -F /dev/null DOCS_REPO: hoge-server-docs run: | git clone git@github.com:hikyaru-suzuki/$DOCS_REPO.git ../$DOCS_REPO cd ../$DOCS_REPO mkdir -p ./spec rm -f ./${{env.SPEC_PATH}} cp $GITHUB_WORKSPACE/${{env.SPEC_PATH}} ./${{env.SPEC_PATH}} git add ./${{env.SPEC_PATH}} result=0 $(git diff --cached --quiet) || result=$? if [ $result -ne 0 ]; then git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git commit -m "update: swagger spec" git push origin master fi
まとめ
小さなことですが今回のCI設定で楽になりました
個別の作業はそれぞれ1分もかからないものですが、自動生成の確認は毎回しないといけないので地味にストレスになっていたのかもしれません
自動生成自体はGo言語に限ったことではないですし、何かの参考になれば幸いです