GitHub Actions で PHPUnit カバレッジレポートがアップロードできなくて無駄にハマった
はじめに
PHPUnit のカバレッジレポートを GitHub Actions で生成・アップロードしようとした時に無駄にハマってしまったので、似たような事態に遭遇した人のフォローとなるようにこの記事を書きました。
先に結論
- GitHub Actions のワークフローで PHPUnit によるカバレッジレポートを生成・アップロードする際に「ファイルが見つからない」という警告に遭遇しました。
- 原因は、
defaults.run.working-directory
の設定とactions/upload-artifact
アクションのpath
パラメータの解釈の違いでした。-
actions/upload-artifact
のpath
はデフォルトで${{ github.workspace }}
(ワークスペースのルート)からの相対パスとして解釈される。
-
本題
私が所属するプロジェクトでは Laravel & PHPUnit を利用しているので、 PHPUnit でテストカバレッジを計測し、その結果を CI/CD プロセスの一環として GitHub Actions 経由で保存・確認できるようにしたいと考えていました。しかし、ワークフローを組んで実行してみたところ、カバレッジレポートのアップロードステップで「ファイルが見つからない」という警告が出てしまい、アーティファクトが期待通りにアップロードされませんでした。
ログを詳細に追っていくと、カバレッジレポート自体は正しく生成されているように見えるのに、アップロードステップだけが失敗している状況でした。
想定されるディレクトリ構成例
以下に、今回の問題が発生した状況を想定したディレクトリ構成の例を示します。
your-repository/
├── .github/
│ └── workflows/
│ └── coverage_report.yml
└── your-laravel-project/ # working-directory で指定するディレクトリ
├── coverage/
│ └── coverage_report/ # PHPUnit が生成するカバレッジレポート
│ ├── index.html
│ └── ... # (その他のレポートファイル)
├── app/
│ └── ...
├── vendor/
│ └── ...
└── phpunit.xml
問題のあったワークフローの例
以下に、問題が発生していた GitHub Actions ワークフローファイル (coverage_report.yml
) の例を示します
※例なのでこのままでは動きません。
name: coverage report
on: push
jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./your-laravel-project # 各ステップのデフォルト作業ディレクトリ
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
php-extensions: # 必要な extension を指定
- name: Install Dependencies
run: composer install --prefer-dist --no-progress --no-suggest
- name: Generate PHPUnit coverage report
run: |
vendor/bin/phpunit --coverage-html coverage/coverage_report tests --filter "test"
ls -l coverage/coverage_report/
- name: Upload coverage reports
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: phpunit-coverage-report-${{ github.sha }}
path: coverage/coverage_report/
retention-days: 30
調査:パスの謎を解き明かす
問題が発生していたのは、 PHPUnit でカバレッジレポートを生成した後、actions/upload-artifact
を使ってそのレポートをアップロードするステップでした。
当初の Generate PHPUnit coverage report
ステップのログでは、ls -l coverage/coverage_report/
の結果から、カバレッジレポートの HTML ファイル群が期待通り生成されていることが確認できました。
PHPUnit 10.5.30 by Sebastian Bergmann and contributors.
Runtime: PHP 8.2.28 with Xdebug 3.4.2
Configuration: /home/runner/work/your-laravel-project/your-laravel-project/phpunit.xml
# (中略)
OK (122 tests, 668 assertions)
Generating code coverage report in HTML format ... done [00:10.338]
total 4812
# (中略)
-rw-r--r-- 1 runner docker 4712880 Jun 3 14:22 dashboard.html
-rw-r--r-- 1 runner docker 42979 Jun 3 14:22 helpers.php.html
-rw-r--r-- 1 runner docker 42567 Jun 3 14:22 index.html
しかし、続く Upload coverage reports
ステップでは、以下のような警告が出ていました。
Warning: No files were found with the provided path: coverage/coverage_report/. No artifacts will be uploaded.
ここで重要なのは、ワークフロー全体に defaults.run.working-directory: ./your-laravel-project
という設定がされていた点です。これにより、run
で実行されるコマンド(PHPUnit の実行や ls
コマンドなど)は、リポジトリルート直下の your-laravel-project
ディレクトリをカレントディレクトリとして実行されます。したがって、カバレッジレポートは ${{ github.workspace }}/your-laravel-project/coverage/coverage_report/
に生成されていました。
一方、actions/upload-artifact
アクションの path
パラメータは、デフォルトで ${{ github.workspace }}
(ワークスペースのルート)からの相対パスとして解釈されます。working-directory
の設定がこのアクションのパス解釈に直接影響するわけではなかったため、path: coverage/coverage_report/
は ${{ github.workspace }}/coverage/coverage_report/
を指そうとしており、実際のファイルパスと異なっていたのが原因でした。
具体的な解決策:ワークフローファイルの修正
この問題を解決するために、actions/upload-artifact
の path
指定を、ワークスペースルートからの正しい相対パスに変更しました。
修正前(問題があったコード):
- name: Upload coverage reports
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: phpunit-coverage-report-${{ github.sha }}
path: coverage/coverage_report/ # 間違い:your-laravel-project ディレクトリが考慮されていない
retention-days: 30
修正後(解決したコード):
- name: Upload coverage reports
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: phpunit-coverage-report-${{ github.sha }}
path: your-laravel-project/coverage/coverage_report/ # 正しいパス指定
retention-days: 30
この変更により、upload-artifact
アクションは正しくカバレッジレポートファイル群を見つけ、無事にアップロードできるようになりました。
まとめ
GitHub Actions のワークフローを構築する際には、各ステップがどのディレクトリを基準に実行されるのか、そして使用するアクションがパスをどのように解釈するのかを正確に把握することが重要だと改めて認識しました。一見単純に見えるファイルパスの問題も、working-directory
のような設定が絡むと少し複雑になることがあります。
新しいアクションを導入する際や、ワークフローの挙動が期待通りでない場合には、まず公式ドキュメントでパスに関する仕様を確認し、必要に応じてデバッグステップを挟んで確認する習慣が必要ですね💧
Discussion