概要
GitHub Actionsを使って、LaravelのプロジェクトをテストしてからAWSのEC2上にデプロイする方法を書いていきます。
テストDBにはMySQLを使用し、デプロイにはDeployerを使用します。各々の細かい説明はしません。
設定ファイル
GitHub Actionsの設定はYMLファイルです。
.github/workflows
ディレクトリに設定ファイルを置くとワークフローとして処理されます。
テストのjob
まずはテストが実行されるようにファイルを書いていきます。
on: push
jobs:
test:
name: phpunit test
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.0.19
ports:
- 3306:3306
options: --health-cmd "mysqladmin ping -h localhost" --health-interval 20s --health-timeout 10s --health-retries 10
env:
MYSQL_ROOT_PASSWORD: pass
MYSQL_DATABASE: test
env:
DB_CONNECTION: mysql
DB_HOST: 127.0.0.1
DB_PORT: 3306
DB_DATABASE: test
DB_USERNAME: root
DB_PASSWORD: pass
steps:
- uses: actions/checkout@v2
- name: cache vendor
id: cache
uses: actions/cache@v1
with:
path: ./vendor
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-composer-
- name: composer install
if: steps.cache.outputs.cache-hit != 'true'
run: composer install -n --prefer-dist
- name: copy .env
run: cp .env.ci .env
- name: generate key
run: php artisan key:generate
- name: migrate
run: php artisan migrate
- name: unit test
run: ./vendor/bin/phpunit
MySQL
今回はテストDBにMySQLを使用するのでMySQLを使いたいのですが、ワークフローが実行されるマシン(ランナー)であるubuntuには5系しか入っていないので、Dockerコンテナを立ててMySQLを使用します。
services内のimageでDockerのimageを指定でき、DockerHubからimageをpullできます。
執筆時点ではoptionを指定していないと、MySQLコンテナが立ち上がる前にPHPUnitが走ってしまいテストがコケてしまう現象がでたため、MySQLコンテナが立ち上がるまで待ちます。
envで環境変数を設定しています。jobs.<id>.env
の位置に書くことによって、このjob内で使える環境変数として設定できます。
注意点としては、今回はランナー上でコンテナをたてているのでDB_HOST: 127.0.0.1
にしてください。コンテナ名にしても接続はできません。
PHPUnit
毎回composer installをすると時間がかかってしまうので、キャッシュができるアクションがあるのでそれを指定しています。
使い方はここに書いてあるコードを書いておけばとりあえず大丈夫です。
.envに関しては今回は雛形(.env.ci)をコピーしてますが、APP_KEY
が設定できればどの方法でもOKです。
あとはmigrateなりphpunitなりのコマンドを叩けばテストが走るjobが完成します。
デプロイのjob
次はデプロイに関して設定をしていきます。
さきほどと同じファイルの続きに書いていきます。
jobs:
//...
deploy:
name: deploy
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/heads/master'
steps:
- uses: actions/checkout@v2
- name: cache vendor
id: cache
uses: actions/cache@v1
with:
path: ./vendor
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-composer-
- name: composer install
if: steps.cache.outputs.cache-hit != 'true'
run: composer install -n --prefer-dist
- name: ssh_key copy
run: |
mkdir -p /home/runner/.ssh
touch /home/runner/.ssh/id_rsa
echo "${{ secrets.SECRET_KEY }}" > /home/runner/.ssh/id_rsa
chmod 600 /home/runner/.ssh/id_rsa
- name: add known hosts
run: ssh-keyscan 【 ip or host_name 】 >> ~/.ssh/known_hosts
- name: deploy
run: ./vendor/bin/dep deploy master
まずテストと大きく違うところはneedsとifです。
GitHub Actionsではjobは並列に実行されるのでそのまま書いてしまうとテストとデプロイが一緒に走ってしまうことになります。
テストをパスしてからデプロイをしたいのでneedsでどのjobが終わってから実行するかを指定します。
またデプロイはどのブランチでもデプロイするわけではないので、ifを使ってmasterブランチのときに実行するようにします。
Deployer
Deployerでデプロイするには秘密鍵が必要になります。公開鍵はあらかじめサーバーにあげておいてください。
秘密鍵などの情報をそのまま書いてしまうとセキュリティ的にNGなので、GitHub ActionsではあらかじめGitHubに暗号化して登録しておきます。
(https://help.github.com/ja/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets)
登録した秘密鍵を適切な場所にコピーしてあげます。(Deployerだとhosts.yml
に秘密鍵のファイルを指定できるオプションがあります)
このままssh接続をしてしまうと接続時にコンソールでyes or no
を入力しないとすすめなくなってしまいエラーになってしまうので、known_hosts
にあらかじめ記述しておくことでこれを回避することができます。
最後にdeployコマンドを叩くようにするとデプロイが開始されます。
pushする
以上のファイルを保存してGitHubにpushすると、pushをトリガーにしてmasterだとテスト&デプロイが、それ以外だとテストが走ります。
Circle CIのようにGitHub Actionsのテストが通ったらPRをマージできるようにするなどの設定も可能です。
まとめ
Circle CIを使ったことがある人ならそこまで抵抗なくできると思います。
GitHub Actionsでは他の人が作ったものをActionとして利用できるので、それを利用することでより手軽に様々なことができるようになるかもしれません。
GitHub Actionsの検索
ちなみにSlackへの通知はこちらのアクションなどがあるので便利です。