GitHub Actionを使って自前Docker内で自動テスト
GitHubで管理しているDockerとLaravel_PJがあります。そのLaravel_PJで作成されたプルリクをトリガーにDocker内でPHPUnitを回すというようなGitHub Actionを作成しました。
要はDocker内にLaravel_PJを突っ込んでPHPUnitを回してます。
Dockerは各環境によるので割愛
環境
- docker-compose v3
- [php-fpm] php:7.3.0-fpm-alpine3.8
- [db] mysql:5.7
- Laravel v6.0
- phpunit v8.3
作成手順
- 
リポジトリをクローン出来る様にPersonal access tokensを設定しておきます 
 権限はrepoにチェックで大丈夫です
 https://github.com/settings/tokens
- 
テスト対象のリポジトリのSettingタグからSecretsを選択し、 GITHUB_PATに先程のtokenを、SLACK_WEBHOOKに通知したいslackのwebhookを設定します
 参考:SlackのWebhook URL取得手順
- 
テスト対象のリポジトリに下記ファイルを保存します。 
- 
envには下記値を設定します 
 PJ_ACTOR: [GitHubのアカウント名]
 PJ_REPO: [テスト対象となるPJ]
 PJ_DOCKER_REPO: [テスト対象となるPJを動かしているDocker]
- 
.env.exampleにはAPP_KEY、Dockerのdbにアクセスするusername、password等を設定します 
github/workflows/main.yml
name: Test CI
on:
  pull_request:
    types: [opened, synchronize]
    branches:
      - 'master'
      - '!analysis-**' # StyleCIを除外
env:
  PJ_ACTOR: my-account
  PJ_REPO: test-project
  PJ_DOCKER_REPO: test-project-docker
  GITHUB_PAT: ${{ secrets.GITHUB_PAT }}
  SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Clone ${{ env.PJ_REPO }}
        uses: actions/checkout@v1
      - name: Clone ${{ env.PJ_DOCKER_REPO }}
        uses: actions/checkout@v1
        with:
          repository: ${{ env.PJ_ACTOR }}/${{ env.PJ_DOCKER_REPO }}
          ref: refs/heads/master
          token: ${{ env.GITHUB_PAT }}
      - name: Project copy
        run: |
          cd ${GITHUB_WORKSPACE} && cd ../
          cp -pr ./${PJ_REPO} ./${PJ_DOCKER_REPO}/www/${PJ_REPO}
      - name: Docker set up
        run: |
          cd ${GITHUB_WORKSPACE} && cd ../
          cd ./${PJ_DOCKER_REPO}
          docker-compose build php-fpm
          docker-compose up -d php-fpm
      - name: Project set up
        run: |
          cd ${GITHUB_WORKSPACE} && cd ../
          cd ./${PJ_DOCKER_REPO}/www/${PJ_REPO}
          composer install
          composer dump-autoload
          cp -p .env.example .env
      - name: Execute tests 
        run: |
          cd ${GITHUB_WORKSPACE} && cd ../
          cd ./${PJ_DOCKER_REPO}
          # mysql起動確認。起動していなければテスト実行不可。mysqlが立ち上がるまで20秒ほどかかる
          docker-compose exec -T db service mysql status
          docker-compose exec -T php-fpm sh -c "cd /var/www/${PJ_REPO}/vendor/bin/phpunit"
      - name: Slack Notification
        uses: homoluctus/slatify@master
        if: always()
        with:
          type: ${{ job.status }}
          job_name: '*[${{ env.PJ_REPO }}] Unit Test*'
          mention: 'here'
          mention_if: 'failure'
          channel: 'sys_ci'
          icon_emoji: ''
        env:
          SLACK_WEBHOOK: ${{ env.SLACK_WEBHOOK }}
ポイント
イベントについて
前提として、プルリクを投げたブランチ上でテストが走ります
- opend:プルリクが作成された時
- synchronize:プルリクしているブランチが更新された時
他にもイベントはありますが、自分が確認したところはこんな感じでした
- edited:プルリクのタイトルや、マージ向き先が変更になった時
- closed:プルリクが対象ブランチにマージ・クローズされた時
on:
  pull_request:
    types: [opened, synchronize]
envについて
yaml上で設定した変数を使用する場合は、${{ env.PJ_ACTOR }}のように、step内のbashで使用する場合は${PJ_ACTOR}のように(bashで変数を使用する時と同じ)する必要があります
参考
・環境変数の利用
・GitHub Actions のコンテキストおよび式の構文
DockerのMysqlについて
GitHub Actionsを使う以外にもCI/CDを作成する際のポイントだと思うのですが、Mysqlは立ち上がるのに20秒ほどかかるようなので、そこら辺を考慮します。(かなりハマった)立ち上がりまでsleepするとよいかもです。
Slack通知について
GitHub Actionには個別で使用できるaction機能があるのですが、Slack通知にslatifyを使わせて頂いております!まさに欲しかった機能通りで、痒いところに手が届く〜
参考:【GitHub Actions】Slack通知用のActionsをTypeScriptで開発してみた
感想
GitHibActionでDockerを使う場合はGitHub側が用意したものを使うべきなのか?Docker Hubで管理するべきなのか?どれがベストなんですかね。Dockerについても勉強していきたいです〜