🙌

reg-suitでpushイベントとpull_requestイベントそれぞれでVRTレポートを出すとどちらかしか出力されなくなる問題の対応

2024/10/29に公開

こんにちは!CastingONEの大沼です。

始めに

以前弊社ではstorycap + reg-suitでVRTを行っていることを紹介しました。

https://zenn.dev/castingone_dev/articles/2f3bfe9712c621

基本的には問題なく動いていますが、qaブランチに修正PRを出す際にdevブランチのコードでVRTされているような挙動がおきました。弊社ではQA期間中に修正を行う時は、以下のgitグラフのようにqaブランチからqafix用のブランチを作ってqaブランチへマージし、devブランチにも取り込みます。この運用で、具体的には 009 のマージコミットを作るPRで起きました。qaブランチへPRを出しているのにも関わらず、devブランチのコードと比較しているようなVRT結果が出ました。

これの原因と対処法について記事にまとめました。

devのコードでVRTの比較している原因

結論を言うと、pushイベントとpull_requestイベントを同じコミットで実行していたことが問題でした。GCSに保存するキー名はreg-keygen-git-hash-pluginで取得されたactual keyを見ますが、コミットが同じ場合は同じキーが算出されるため、上書きされる結果になっていました。

pushイベントでは確かにqaブランチのコードで実行されていますが、その後にdevへのPRによってdevのコードが取り込まれた上でのVRTを行った結果が上書きされていたため、最初に見せたgitグラフでいう 005 のコミットハッシュのスクリーンショットがdevブランチものが入っていた状態になっていました。

同じコミットハッシュでpushイベントとpull_requestイベントのVRTレポートを保存できるようにする

上記の問題はGCSへの保存するキーがpushイベントとpull_requestイベントで同じものが使われていたことなので、キーを自前で生成して被らないように調整します。自前で生成したキーをreg-simple-keygen-pluginに渡すことで元々の挙動に影響なく動かせそうです。
このプラグインでは基本的には現在のコミットハッシュをactual keyに、比較対象のコミットハッシュをexpected keyに渡すと良くて、actual keyをPRの時は pr_ というプレフィックスをつけるだけでpushイベントとの衝突を回避できそうです。expected keyはPRに更にPRを作る時は注意が必要で、比較対象となるキーがコミットハッシュに pr_ をつけたキーを指定する必要があります。
これらを踏まえると、以下のようなGitHub Actionになりました。

./.github/actions/get-reg-key
name: Get Reg Key
description: reg-suitで差分チェックするためのキーを取得する

outputs:
  expected-key:
    description: "期待値のデータを持つスナップショットキー"
    value: ${{ steps.get-reg-key.outputs.expected-key }}
  actual-key:
    description: "実際のデータを持つスナップショットキー"
    value: ${{ steps.get-reg-key.outputs.actual-key }}

runs:
  using: composite

  steps:
    - name: Get Reg Key
      id: get-reg-key
      run: |
        if [[ "$GITHUB_EVENT_NAME" = "pull_request" ]]; then
          case "${{ github.event.pull_request.base.ref }}" in
            dev|qa|stg|main)
              echo "expected-key=${{ github.event.pull_request.base.sha }}" >> $GITHUB_OUTPUT
              ;;
            # 上記以外のブランチにマージする場合はPRした上で更にPRを出している可能性が高いので、キー名にpr_を付与する
            *)
              echo "expected-key=pr_${{ github.event.pull_request.base.sha }}" >> $GITHUB_OUTPUT
              ;;
          esac
          echo "actual-key=pr_${{ github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT
        else
          PREV_SHA=$(git rev-parse HEAD^)
          echo "expected-key=$PREV_SHA" >> $GITHUB_OUTPUT
          echo "actual-key=${{ github.sha }}" >> $GITHUB_OUTPUT
        fi
      shell: bash

後はこのActionを実行してexpected keyとactual keyを取得し、それをregconfigに渡したら完了です。

expected keyとactual keyを取得して環境変数に渡す
 jobs:
   vrt:
     # 省略

     steps:
       # 省略

+      - name: Get Reg Key
+        id: get-reg-key
+        uses: ./.github/actions/get-reg-key

       - name: Run VRT
         run: npm run vrt
         env:
+          EXPECTED_KEY: ${{ steps.get-reg-key.outputs.expected-key }}
+          ACTUAL_KEY: ${{ steps.get-reg-key.outputs.actual-key }}
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           GITHUB_REPO_OWNER: ${{ github.repository_owner}}
           GITHUB_REPO_NAME: ${{ github.event.repository.name }}
           GITHUB_PR_NUMBER: ${{ github.event.number }}
reg-simple-keygen-pluginに差し替え
 {
   // 一部省略
   "plugins": {
-    "reg-keygen-git-hash-plugin": true,
+    "reg-simple-keygen-plugin": {
+      "expectedKey": "${EXPECTED_KEY}",
+      "actualKey": "${ACTUAL_KEY}"
+    }
   }
 }

終わりに

以上がreg-suitでpushイベントとpull_requestイベントそれぞれで衝突せずにVRTレポートを保存する方法でした。あまり出会わないケースだと思いますが、同じコードを他のブランチにも取り込んでいてVRTの結果がおかしい場合はこちらの方法を試してみると解決する可能性があるので参考になれば幸いです。

Discussion