9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub ActionsのPHPStan実行でLibXL関連のエラーを解消する方法

Last updated at Posted at 2025-12-31

はじめに

  • YUZURIHAの松村です。
  • 現在私が担当しているPHPのプロジェクトでは、GitHub ActionsにてPHPStanを実行してコードの静的解析を行っています。
  • その中で発生した問題と対応した方法について、ご紹介します。

LibXLの導入

  • 私が担当しているプロジェクトでは、Excelを扱うためにPHP拡張モジュールのLibXLを導入しています。
  • このLibXLは、composerなどのライブラリ管理ツールではなく、makeコマンドによってLinuxに直接インストールしています。
    • ※ 具体的にLibXLをどのようにインストールしてどのように使っているかは、本稿の趣旨からは逸れるため割愛します。
  • Dockerで用意しているローカル開発環境でもLibXLを使えるように、Dockerfile上でmakeコマンドによってインストールしています。

GitHub Actionsの設定

  • GitHub ActionsでPHPStanを実行するためのワークフローは、以下のように設定しています。
.github/workflows/phpstan.yml
jobs:
  phpstan:
    runs-on: ubuntu-latest

    steps:
      # リポジトリにあるソースコードをGitHub Actions Runnerに持ってくる
      - name: Checkout code
        uses: actions/checkout@v6

      # PHPのセットアップ
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'

      # Composer Install
      - name: Composer Install
        run: composer install --prefer-dist --no-progress

      # PHPStanを実行
      - name: Run PHPStan
        run: ./vendor/bin/phpstan analyze -c phpstan.neon

※ 実際にはcomposerのキャッシュの設定や各コマンドのオプションなどもありますが、こちらも本稿の趣旨から逸れるため割愛しています。

PHPStan実行時に発生した問題

  • このような状態でGitHub ActionsにてPHPStanを実行すると、LibXLで定義しているExcelBookExcelFormatといったクラスが存在しないため、エラーが発生してしまいました。
 ------ ---------------------------------------------------------------------------------------- 
  Line   Services/HogeService.php                                            
 ------ ---------------------------------------------------------------------------------------- 
  XXX    Call to method loadFile() on an unknown class ExcelBook.                                
         🪪 class.notFound                                                                       
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols                                     
  XXX    Access to constant COLOR_BLACK on an unknown class ExcelFormat.                         
         🪪 class.notFound                                                                       
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols 
  • ローカル開発環境にてPHPStanを実行すると、ちゃんとLibXLをインストールしているのでこのエラーは発生しません。
  • そのため、GitHub Actionsとローカル開発環境でPHPStan実行時の挙動が異なるという少し困った状況になってしまいました😩

対応した方法

  • 以下の方法で対応して、解決することができました😄
    • ghcr.io(GitHub Container Registry)に、ローカル開発環境のdockerイメージをbuild & pushする。
    • そのdockerイメージを使って、GitHub Actions上でPHPStanを実行する。
  • では、具体的にどのように対応したのかを詳しく説明して行きます。

ghcr.ioにdockerイメージをbuild & push

  • 新たなワークフローimage-build-push.ymlを追加します。
  • ワークフロー実行のトリガーを指定するon:は割愛していますが、各々のプロジェクトの運用に応じて設定するのが良いと思います。
.github/workflows/image-build-push.yml
permissions:
  # リポジトリのソースコードを読み取る権限を付与
  contents: read
  # GitHub Actionsの標準トークン(GITHUB_TOKEN)に、ghcr.ioへイメージを書き込む権限を付与
  packages: write

jobs:
  image-build-and-push:
    runs-on: ubuntu-latest
    env:
      IMAGE_NAME: ghcr.io/${{ github.repository }}/php
      IMAGE_TAG: ${{ github.sha }}
    steps:
      # リポジトリにあるソースコードをGitHub Actions Runnerに持ってくる
      - uses: actions/checkout@v6

      # GitHub Actions専用の高速キャッシュ(type=gha)を使うために、標準のdocker buildよりも高機能なBuildxを有効にする
      - name: Set up Buildx
        uses: docker/setup-buildx-action@v3

      # ghcr.ioへログイン
      - name: Login to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      # メタデータの自動生成(手動でタグを管理する手間を省く)
      - name: Docker metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.IMAGE_NAME }}
          tags: |
            type=raw,value=${{ env.IMAGE_TAG }}
            type=ref,event=branch
            type=ref,event=tag
            type=raw,value=latest

      # ghcr.ioへBuild & Push
      - name: Build & Push
        uses: docker/build-push-action@v6
        with:
          # リポジトリ上のDockerfileのパスを指定
          file: ./docker/php/Dockerfile
          # php.iniなどを配置しているディレクトリパスを指定
          context: ./docker/php
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          platforms: linux/amd64
          # GitHub Actionsのキャッシュストレージに保存して高速化する
          cache-from: type=gha
          cache-to: type=gha,mode=max
  • このワークフロー実行後に、イメージがorganizationのPackagesに表示されていればBuild & Pushは成功です!
    • スクリーンショット 2025-12-30 23.40.36.png

ghcr.io上のdockerイメージを使ってPHPStanを実行

  • 次に、PHPStan実行のワークフローを以下のように改修します。
.github/workflows/phpstan.yml
jobs:
  phpstan:
    runs-on: ubuntu-latest
    permissions:
      # リポジトリのソースコードを読み取る権限を付与
      contents: read
      # ghcr.ioからイメージをPullする権限を付与
      packages: read

    # stepsを実行するDockerコンテナを指定
    container:
      # 最新のイメージを指定
      image: ghcr.io/${{ github.repository }}/php:latest
      # イメージが保存されているghcr.ioにアクセスするための実行ユーザと一時パスワードを指定
      credentials:
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}

    steps:
      # リポジトリにあるソースコードをGitHub Actions Runnerに持ってくる
      - name: Checkout code
        uses: actions/checkout@v6

      # Composer Install
      - name: Composer Install
        run: composer install --prefer-dist --no-progress

      # PHPStanを実行
      - name: Run PHPStan
        run: ./vendor/bin/phpstan analyze -c phpstan.neon
  • PHPのインストールはDockerfile内で行っているため、従来のワークフローで行っていたSetup PHPは不要になります。

最後に

  • 以上の対応を行ってから数ヶ月間チーム内でワークフローを運用していますが、特に問題は起こっていません。
  • ghcr.ioからイメージをPullする分ワークフローの実行時間が遅くなることを懸念していましたが、高速キャッシュ(type=gha)を使っているためか遅くなりませんでした。

スタブを使う

  • そして、記事を書きながらいろいろ調べていたのですが、スタブを使う方法でも対応できそうです。
  • LibXL(php-excel)のための静的解析用スタブパッケージというのがありました。
  • このパッケージの各クラスのスタブをphpstan.neonに指定することで、エラーを回避できそうです。
  • というわけで、以下のようなケースではスタブを使う方が良いかもしれません。
    • GitHub Packagesでかかる料金が気になる
    • GitHub Actionsでは静的解析(PHPStan)を行うだけで、テストは実行しない
  • もし他にも「こういう方法が良い」とかあれば、教えていただけると嬉しいです。
9
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?