🐘

PHP のリファクタリングがテスト不要か判定するアクションを作りました [GitHub Actions]

2022/05/03に公開

目的

リファクタリングをしているとコードスタイルの変更やコメントの変更を加えることがあります。
これらの変更は PHP の動作に何ら影響を与えませんが、変更を加えたからには本当に動作に影響がないかテストをしないと不安です。(影響がないつもりが実はあったというのは残念ながらよくあることです)
しかしながら影響範囲が広すぎて人力でのテストが困難だったりそもそも影響範囲が分からないこともあります。
自動テストが充実していれば人力でのテストはしないという判断もできると思いますが全体を完璧に網羅できているプロジェクトはなかなか無いのではないかと思います。

では動作に影響がないことを保証できればどうでしょうか?
動作に影響がないのであればそのままリリースしてしまっても問題なさそうです。

https://tech-blog.monotaro.com/entry/2018/09/26/142451

こちらの記事では抽象構文木 (AST: Abstract Syntax Tree) の変更がないことで動作に影響がないことを保証しています。
「動作に影響がないことをテストした」とも言えますね。
面白いなーと思ったので GitHub Actions で手軽に実行できるようにアクションにしてみました。

PHP では

https://qiita.com/tetsunosukeito/items/c0e99a120414de226480

PHP では nikic/php-ast を使用すると AST を取得できます。
base, head それぞれのブランチで AST のハッシュ値を求めて比較します。

具体的なコード

作成したアクション

https://github.com/marketplace/actions/php-ast-changed

使い方

pull_request または pull_request_target イベントで使用します。
${{ steps.<step-id>.outputs.changed }}"true" または "false" が返ります。文字列であることに注意してください。
"false" の場合は AST に変更がないので テスト不要 ラベルを付けるなど出来るのではないかと思います。
ラベルは予め作成しておく必要があります。

.github/workflows/php-ast-changed.yml
name: PHP AST Changed

on:
  pull_request:
    paths:
      - '**.php'

  label-if-not-changed:
    runs-on: ubuntu-20.04
    timeout-minutes: 30

    steps:
      - uses: snow-actions/php-ast-changed@v1.0.0
        id: php-ast
      - name: Label
        run: |
          set -x
          label='テスト不要'
          if [ "${changed}" = 'false' ]; then
            gh pr edit ${pr_number} --add-label ${label}
          else
            gh pr edit ${pr_number} --remove-label ${label}
          fi
        env:
          GH_TOKEN: ${{ github.token }}
          pr_number: ${{ github.event.number }}
          changed: ${{ steps.php-ast.outputs.changed }}

アクション作成テンプレート

https://zenn.dev/snowcait/articles/787e83640746e1

以前作成したこちらを使用しました。

Discussion