Skip to content

ci: PHP 8.5 を matrix に追加し、フォーマット検査を lint job に分ける - #92

Open
Javakky wants to merge 2 commits into
masterfrom
javakky/ci-php85
Open

ci: PHP 8.5 を matrix に追加し、フォーマット検査を lint job に分ける#92
Javakky wants to merge 2 commits into
masterfrom
javakky/ci-php85

Conversation

@Javakky

@Javakky Javakky commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

概要(What / Why)

CI に PHP 8.5 を追加します。

カリー化 (#76) で入るパイプ演算子のテストは #[RequiresPhp('>= 8.5')] が付いているため、8.4 だけの CI では一度も実行されません。手元の docker では確認していますが、CI で走らないと退行を検出できません。

変更点

strategy:
  fail-fast: false
  matrix:
    php: ['8.4', '8.5']
  • フォーマット検査は matrix から切り出して独立した lint job にしました。 php-cs-fixer 3.89 は PHP 8.5 の構文をまだサポートしておらず、8.5 で走らせると次を表示して検査せずに exit 0 で終わります。通すと偽の成功になります

    PHP CS Fixer currently supports PHP syntax only up to PHP 8.4, current PHP version: 8.5.8.
    Add Config::setUnsupportedPhpVersionAllowed(true) to allow executions on unsupported PHP versions.
    Such execution may be unstable and you may experience code modified in a wrong way.
    

    Config::setUnsupportedPhpVersionAllowed(true) を足す手もありますが、公式が「unstable / コードが誤って書き換えられる可能性がある」と明言しているので採りません

  • paths.github/workflows/check.yml / phpstan.neon / .php-cs-fixer.dist.php を追加しました。 workflow 自身の変更で CI が走らないと matrix が動くことをこの PR で検証できませんし、level: 10 を変えても Check が起動しない状態でした

  • fail-fast: false にしたので、片方が落ちてももう一方の結果が見えます

composer.jsonrequire.php>=8.4 のままです。カリー化した関数は callable を返すだけなので 8.4 で動き、パイプ構文を使うかは利用者側の PHP バージョン次第です。

動作確認

docker php:8.5-cli (PHP 8.5.8) で実際に走らせました。

コマンド 結果
composer install --no-progress --prefer-dist --no-interaction 成功 (55 packages)
vendor/bin/phpstan analyse -c phpstan.neon [OK] No errors
vendor/bin/phpunit tests OK (104 tests, 109 assertions)
vendor/bin/php-cs-fixer fix --dry-run --diff 未サポートで検査されず終了 (上記)

dev 依存は phpstan ^2.1 / phpunit ^12.4 / php-cs-fixer ^3.89 で、8.5 で問題があったのは php-cs-fixer だけです。

レビューへの対応

提案 対応
(中) php-cs-fixer を独立 job に 対応しました。 if: matrix.php == '8.4' は「matrix に '8.4' という文字列が存在すること」への暗黙依存で、将来 matrix を ['8.5', '8.6'] に更新すると if が全て偽になりフォーマット検査だけが警告なく消えます (CI は緑のまま)。独立 job なら matrix の中身と無関係に必ず 1 回走ります
(小) paths に設定ファイルが漏れている 対応しました。 phpstan.neon.php-cs-fixer.dist.php を追加
(小) この PR 単体では 8.5 限定テストが走ることは証明できない そのとおりです (このブランチに #[RequiresPhp] は 0 件)。インフラを先に入れる順序として変更しません。#76 マージ後に checks (8.5) のテスト件数が checks (8.4) より多いことを確認します
(nit) コメントに解除条件がない 独立 job にしたので if が消えました。コメントには「php-cs-fixer が 8.5 をサポートしたら php-version を上げる (この job を消す必要はない)」と書いてあります

注意

required status check の名前が変わります。 checkslint / checks (8.4) / checks (8.5)。ブランチ保護で checks を必須にしている場合は設定の更新が必要です。lint は matrix から独立しているので、今後 PHP バージョンを増減しても名前が変わりません。

🤖 Generated with Claude Code

パイプ演算子 (#76) のテストは 8.4 では RequiresPhp で skip されるため、 CI で一度も実行されていない。 8.5 を matrix に足して実際に走らせる。

php-cs-fixer は 8.4 の 1 回だけ実行する。 3.89 は PHP 8.5 の構文を まだサポートしておらず、 8.5 で走らせると「supports PHP syntax only up to PHP 8.4」と表示して検査せずに exit 0 で終わるため、 通すと偽の成功になる (docker php:8.5.8 で実測)。 フォーマット検査は 1 回で足りる。

paths に .github/workflows/check.yml を追加した。 workflow 自身の変更で CI が走らないと、 matrix が動くことを PR で検証できない。

docker php:8.5-cli (8.5.8) で composer install / phpstan / phpunit が通ることを確認済み ([OK] No errors / OK (104 tests, 109 assertions))。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown

Claude finished @Javakky's task in 2m 17s —— View job


レビュー結果

  • 差分の取得
  • check.yml / composer.json / composer.lock の確認
  • 他ワークフロー・設定ファイルへの影響確認
  • レビュー結果の投稿

結論: LGTM。 変更は妥当で、意図(8.5 限定テストを CI で回す / 偽の成功を作らない)も達成できています。ブロッカーはありません。以下は改善提案です。


良い点

  • fail-fast: false — 片方の失敗でもう一方が打ち切られないのは matrix の使い方として正しいです。
  • php-cs-fixer を通さない判断に同意します。 setUnsupportedPhpVersionAllowed(true) は公式が unstable と明言しており、--dry-run とはいえ検査結果が信用できない状態で緑になるほうが有害です。「exit 0 で終わるので通してしまうと偽の成功になる」という理由がコメントとしてワークフロー内に残っているのも良いです。
  • paths への check.yml 追加は、この PR 自身を検証可能にするために必須でした。
  • composer.lockplatform{"php": ">=8.4"} で、composer.jsonconfig.platform のピン留めもありません。8.5 でも依存解決は素直に通ります(実測どおり)。

提案 1(中): php-cs-fixer は matrix 依存のステップではなく独立ジョブにしたい

.github/workflows/check.yml:40-42

      - name: Run PHP CS Fixer
        if: matrix.php == '8.4'

いまフォーマット検査は「matrix に '8.4' という文字列が存在すること」に暗黙依存しています。将来 8.5 サポート後に matrix を ['8.5', '8.6'] へ更新すると、この if が全て偽になり、エラーも警告も出さずにフォーマット検査だけが消えます。 CI は緑のままなので気付けません。

独立した lint ジョブに切り出せば、

  • matrix の中身と無関係に必ず 1 回走る
  • required status check 名が lint として安定する(matrix 更新のたびにブランチ保護を触らずに済む)
  • 8.4 ジョブ内で直列実行されず並列化される

というメリットがあります。今回の PR スコープを超えるなら別 PR でも構いません。

Fix this →

提案 2(小): paths に設定ファイルが漏れている

.github/workflows/check.yml:7-12

check.yml を追加した理由(=その変更で CI が走らないと検証できない)は、.php-cs-fixer.dist.phpphpstan.neon にもそのまま当てはまります。現状、ルールレベルを level: 10 から変更しても、cs-fixer のルールを足しても、Check は起動しません。ついでに揃えておくと一貫します。

Fix this →

提案 3(小): この PR 単体では「8.5 限定テストが走ること」は証明できない

このブランチの tests/ を検索した限り #[RequiresPhp] は 0 件で、#76 はまだ未マージです。つまりこの PR の CI が緑になっても、確認できるのは「8.5 ジョブが 104 tests を完走する」ことまでで、8.5 でしか走らないテストが実際に実行されることは確認できません。

インフラを先に入れる順序自体は正しいので変更不要ですが、#76 マージ後に checks (8.5) のテスト件数が checks (8.4) より多いことを一度確認しておくと、ゲートが効いていることの実証になります。

提案 4(nit): コメントの解除条件と版数

.github/workflows/check.yml:37-39 のコメントは「なぜスキップするか」は説明できていますが、「いつ外すか」がありません。3.89 という具体的な版数も時間とともに陳腐化します。

      # php-cs-fixer は PHP 8.5 の構文をまだサポートしておらず(3.89 時点)、8.5 で実行すると
      # 「supports PHP syntax only up to PHP 8.4」と表示して検査せずに終了する (exit 0)。
      # 通してしまうと偽の成功になるので、フォーマット検査は 8.4 の 1 回だけ行う。
      # php-cs-fixer が 8.5 をサポートしたらこの if を削除する。

補足: required status check について

PR 本文の注意書きのとおりです。加えて、このワークフローは paths フィルタ付きなので、src/** 等に触れない PR では job 自体が起動せず、required に指定した check が Expected のまま止まります(既存の挙動)。matrix 化でその対象が 1 個から 2 個に増えるので、ブランチ保護を更新する際は両方の名前を登録するか、提案 1 のようにジョブ名を matrix から切り離すかを検討してください。


なお .github/workflows/ 配下は GitHub App の権限上わたしから直接コミットできないため、上記の修正が必要な場合はローカルまたは上記リンクからの適用をお願いします。
| ブランチ: javakky/ci-php85

if: matrix.php == 8.4 は「matrix に 8.4 という文字列が存在すること」への 暗黙依存だった。 将来 matrix を [8.5, 8.6] に更新すると if が全て偽になり、 エラーも警告も出さずにフォーマット検査だけが消える (CI は緑のまま)。 独立 job にすれば matrix の中身と無関係に必ず 1 回走る。

phpstan.neon と .php-cs-fixer.dist.php も paths に追加した。 check.yml を足した理由 (その変更で CI が走らないと検証できない) が そのまま当てはまる。 level を変えても Check が起動しない状態だった。

Refs #76

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown

Claude finished @Javakky's task in 2m 19s —— View job


レビュー結果(追加コミット 6c82e59 を反映)

  • 差分の取得(a50f58c + 6c82e59
  • check.yml 全体の確認
  • 前回指摘の反映状況を確認
  • 他ワークフロー・設定ファイルとの整合性確認
  • レビュー結果の投稿

結論: LGTM。マージして問題ありません。 前回の指摘はすべて適切に反映されています。以下は残りの小さな提案です(いずれもブロッカーではありません)。


前回指摘の反映確認

前回の提案 状態 備考
提案1: php-cs-fixer を独立 job に ✅ 反映 lint job として分離。php-version: '8.4' を直接指定しており、matrix の中身に依存しなくなった
提案2: paths に設定ファイル追加 ✅ 反映 phpstan.neon / .php-cs-fixer.dist.php を追加。phpstan.neonpaths: [src, tests] と cs-fixer の Finder->in([src, tests]) を確認したので、これで検査対象と paths が一致
提案3: 8.5 限定テストの実証 ⏳ 未(想定内) 後述
提案4: コメントの解除条件 ✅ 反映 「php-cs-fixer が 8.5 をサポートしたら php-version を上げる (この job を消す必要はない)」まで書かれており、将来 matrix に戻す誤りも防げている

lint を独立させたことで、matrix から '8.4' が消えてもフォーマット検査が黙って消えるという前回の懸念は解消されました。並列化されて総ウォールクロックも短くなります。


提案 A(小): concurrency がこのワークフローだけ無い

.github/workflows/check.yml:1-14

このリポジトリの他の 5 ワークフロー(agent.yml / agent-review.yml / agent-plan.yml / agent-breakdown.yml / sync_templates.yml)はいずれも concurrency を持っていますが、check.yml にはありません。既存の話ではあるものの、この PR で job 数が 1 → 3 に増えたため、連続 push 時の無駄な並走コストも 3 倍になります。

concurrency:
  group: check-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

Fix this →

提案 B(小): permissions が未指定

.github/workflows/check.yml:1-14

他ワークフローは permissions を明示していますが、check.yml は未指定のためリポジトリ既定値が使われます。このワークフローは checkout と静的解析しかしないので contents: read で足ります。権限の緩和ではなく最小化なので .claude/rules/30_security.md にも反しません。

permissions:
  contents: read

Fix this →

提案 C(小): composer install が 3 回走るのでキャッシュが欲しい

.github/workflows/check.yml:36-37, 61-62

分離の代償として composer install が 1 回 → 3 回になりました。composer.lock があるので素直にキャッシュが効きます。

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.4'
          tools: composer
          coverage: none

      - name: Install dependencies
        uses: ramsey/composer-install@v3

ramsey/composer-install@v3composer.lock のハッシュでキャッシュキーを作るので、PHP バージョンごとに勝手に分かれます。actions/cache を直書きする場合は キーに matrix.php を含めるのを忘れずに(8.4/8.5 で解決結果が変わりうるため)。

Fix this →

提案 D(nit): lintphp-versioncomposer.json の下限が連動しない

.github/workflows/check.yml:32

php-version: '8.4' はハードコードなので、将来 composer.jsonrequire.php>=8.5 に上げると lint job の composer install だけが解決に失敗します。いま直す必要はありませんが、下限を上げるときの TODO として覚えておくとよいです(コメントに一言足しておくのも手です)。

提案 E(小): PR 本文の「注意」が古くなっています

本文では checkschecks (8.4) / checks (8.5)2 つと書かれていますが、lint を切り出した結果、実際に登録すべき required status check は 3 つになります。

  • lint
  • checks (8.4)
  • checks (8.5)

lint の登録漏れは「フォーマット検査が必須でなくなる」という形で静かに効いてくるので、本文を更新しておくとマージ時の取りこぼしを防げます。なお paths フィルタ付きのため、src/** 等に触れない PR では job が起動せず required が Expected のまま止まる点も従来どおりです。

提案 F(小・再掲): この PR 単体では 8.5 限定テストの実行は証明できない

このブランチの tests/ を再検索しましたが #[RequiresPhp] は依然 0 件で、#76 は未マージです。この PR の CI が緑になっても確認できるのは「8.5 job が完走する」ところまでです。インフラを先に入れる順序自体は正しいので変更不要ですが、#76 マージ後に checks (8.5) のテスト件数が checks (8.4) より多いことを一度確認しておくと、ゲートが効いている実証になります。


確認したこと

  • composer.lockplatform{"php": ">=8.4"}composer.jsonconfig.platform のピン留めもなし → 8.5 での依存解決は素直に通ります(PR 本文の実測どおり)。
  • ロックされた php-cs-fixer は v3.89.1。コメント中の「3.89 時点」という記述と一致しています。
  • phpstan.neonphpVersion の指定がないため、PHPStan は実行中のランタイムを前提に解析します。つまり 8.4 / 8.5 の 2 回実行は冗長ではなく、バージョン依存の解析差分を拾えるので matrix に乗せる価値があります。
  • check.yml の YAML 構造(lint / checks の 2 job、fail-fast: false、step の入れ子)に破綻はありません。前コミットで checks job 内にあった PHPStan/PHPUnit step が正しく新 job 側へ移っており、lint 側に取り残されたステップもありません。

なお .github/workflows/ 配下は GitHub App の権限上わたしから直接コミットできないため、上記の修正が必要な場合はローカルまたは各リンクからの適用をお願いします。


ブランチ: javakky/ci-php85 |

@Javakky Javakky changed the title ci: PHP 8.5 を matrix に追加する ci: PHP 8.5 を matrix に追加し、フォーマット検査を lint job に分ける Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant