こんにちは、株式会社ウイングドアの田上です。
弊社では開発業務にGitHubを使っています。
折角GitHubを使っているので、
GitHub Actionsを使ってCI(継続的インテグレーション)を実施したいなと思い、やってみました💪
今回は弊社で多いLaravel案件でも使えるように、
表題の通りGitHub Actions + LaravelでのCIを構築してみます。
GitHub Actionsとは
プッシュ、Issue、リリースなどのGitHubプラットフォームのイベントをトリガーとしてワークフローを起動しましょう。コミュニティが開発・保守し、ユーザが熟知・愛用しているサービスについて、対応するアクションを組み合わせて設定できます。
- 引用元:Actions | GitHub
はじめかた
GitHubにLaravelのリモートリポジトリを作成して、Actionsをクリックします。
GitHubにPHPのPJとしてサジェストされていると、[Workflows made for your PHP repository]欄に
Laravelのワークフローテンプレートが表示されているので、[Set up this workflow]を押します。
[Workflows made for your PHP repository]欄が表示されていない時は、
[Continuous integration workflows]欄の[More continuous integration workflows...]
を選択すると、Laravelのテンプレートが見つかります。
GitHub Actionsのワークフローのエディタが開くので、[Start commit] > [Commit new file]ボタンからコミットを実施。
/.github/workflows
配下にワークフローのyamlファイルが作られます。
Laravelテンプレートのワークフロー
Laravelテンプレートで作られるyamlについて解説していきます。
name
name: Laravel
ワークフローの名前です。Actionsの一覧に表示されます。
on
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
ワークフローの実行されるタイミングを記載します。
今回のテンプレートでは
- masterへのpush
- masterでのpull request作成
の二つのタイミングが記載されています。
jobs
jobs:
laravel-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: Create Database
run: |
mkdir -p database
touch database/database.sqlite
- name: Execute tests (Unit and Feature tests) via PHPUnit
env:
DB_CONNECTION: sqlite
DB_DATABASE: database/database.sqlite
run: vendor/bin/phpunit
ワークフローで実行されるジョブを記載します。
このテンプレートで行っていることは
- ubuntu-latestの仮想環境を指定
- リポジトリをcheckout
- Laravelの動作に必要なコマンドを実行
- .envの作成
composer install
- APP_KEYの生成
- ディレクトリのパーミッション設定
- データベースの作成(SQLite)
PHPUnit
を実行
となっています。
それぞれのステップにはname
のアトリビュートで名前がついており、
run
のアトリビュートで実行されるコマンドが記載されています。
実行
試しにREADME.mdを軽く編集してmasterにpushしてみました。
GitHub Actionsのページを見ると、ワークフローが実行されています。
実行されたワークフローの詳細画面を開くと、
無事に全てのstepが終了し、PHPUnit
まで実行されていることがわかります。
Laravel+MySQLの環境のテスト
既に運用中のLaravelのプロジェクトでは、
「RDBMS向けに書いたマイグレーションがSQLiteで上手く動かないよ〜🥺」
ということがあると思います。ありました😇
Laravel+MySQL用のワークフローを以下に記載しました。
設定方法については、主に以下の記事を参考にさせていただいております🙇♂️
GitHub Actions で LaravelのCI/CD環境を構築する(MySQL, Deployer)
name: UnitTest
on:
push:
branches:
- master
- 'fix/**'
- 'feature/**'
jobs:
laravel_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: password
MYSQL_DATABASE: testdatabase
env:
DB_CONNECTION: mysql
DB_HOST: 127.0.0.1
DB_PORT: 3306
DB_DATABASE: testdatabase
DB_USERNAME: root
DB_PASSWORD: password
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: composer dump autoload
run: composer dump-autoload
- name: generate key
run: php artisan key:generate --env=testing
- name: migrate
run: php artisan migrate
- name: unit test
run: ./vendor/bin/phpunit
MySQLのコンテナ
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: password
MYSQL_DATABASE: testdatabase
env:
DB_CONNECTION: mysql
DB_HOST: 127.0.0.1
DB_PORT: 3306
DB_DATABASE: testdatabase
DB_USERNAME: root
DB_PASSWORD: password
services
にMySQLのコンテナを記載します。
接続情報を仮想環境のenvにも追記し、LaravelのDBとして使用します。
composerのキャッシュ
- 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
ワークフロー実行の度にcomposer install
を実行するのは
時間がかかってしまいもったいないので、./vendor配下をキャッシュさせています。
2回目の実行からは画像のようにcomposer install
が行われず、
キャッシュされたライブラリを用いてワークフローが動きます。
composer dump-autoloadの実行
- name: composer dump autoload
run: composer dump-autoload
./vendor配下をキャッシュするようにしたので、
名前空間の変更に対応するため、composer dump-autoload
を実施します。
composer dump-autoload
を実施することで、新規に追加したファイルを見つけてくれるようになります。
感想
導入は本当に簡単でした。
メジャーなフレームワークだと既にテンプレートが用意されているので、
GitHubを使っていて、CI環境を構築したい場合はGitHub Actionsが一番スマートだと思います。
ワークフローはyamlで記載するので、docker-compose
を普段使いしていると馴染みやすかったです。
今回でLaravelのCIができたので次はCDにも挑戦したいです💪
どんどんワークフローを増やして手作業による属人性を減らしていけたらいいですね🤗
株式会社ウイングドアでは、Ruby on RailsやPHPを活用したwebサービス、webサイト制作を中心に、
スマホアプリや業務系システムなど様々なシステム開発を承っています。