VisasQ Dev Blog

ビザスク開発ブログ

GitHub Actions で特定ファイルの変更を含むプルリクにコメントする

GitHub Actionsを使って特定ファイルの変更を含むプルリクに自動でコメントを投稿する方法を紹介します。 弊社では特定ファイルを修正したときに必要な作業のリマインドに利用しています。

実装

以下のyamlファイルを .github/workflows に配置することで、hogeディレクトリ配下のファイルの変更を検知してプルリクエストにコメントを投稿できます。

name: workflow
on:
  pull_request:
    types: [ opened, synchronize, reopened ]
    paths:
      - hoge/*

jobs:
  comment-on-pull-request:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 100
          ref: ${{ github.head_ref }}
      - id: diff-check
        if: github.event.action == 'synchronize'
        run: echo "diff-count=$(git diff ${{ github.event.before }} ${{ github.event.after }} --name-only --relative=hoge | wc -l)" >> $GITHUB_OUTPUT
      - id: no-diff-check
        if: github.event.action != 'synchronize'
        run: echo "diff-count=1" >> $GITHUB_OUTPUT
      - uses: actions/github-script@v6
        if: steps.diff-check.outputs.diff-count > 0 || steps.no-diff-check.outputs.diff-count > 0
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `hoge ディレクトリ配下のファイルが編集されました。`
            })

プルリクエストにコメントされる条件は以下の通りです。

  • hogeディレクトリ配下のファイルの変更を含むプルリクエストをopenまたはreopenした時
  • hogeディレクトリ配下のファイルの変更を含むコミットをプルリクエストにプッシュした時

解説

ワークフローの実行条件

on:
  pull_request:
    types: [ opened, synchronize, reopened ]
    paths:
      - hoge/*

ワークフローの実行条件を定義しています。 synchronizeイベントはプルリクエストに新しいコミットがプッシュされたときに発火します。 paths に指定したファイルをプルリクエストの差分に含む場合、ワークフローが実行されます。

トピックブランチをチェックアウト

- uses: actions/checkout@v3
  with:
    fetch-depth: 100
    ref: ${{ github.head_ref }}

後に git diff を実行するために actions/checkout でプルリクエストのトピックブランチをチェックアウトします。

fetch-depth はHEADからどれだけコミットを遡るかを指定します。今回はプルリクエストに一度でプッシュされるコミット数は100以下と仮定して設定しています。fetch-depth: 0 とすれば全てのコミットを遡ることができますが、実行時間が長くなってしまいます。

プルリクエストにプッシュされた差分をチェック

- id: diff-check
  if: github.event.action == 'synchronize'
  run: echo "diff-count=$(git diff ${{ github.event.before }} ${{ github.event.after }} --name-only --relative=hoge | wc -l)" >> $GITHUB_OUTPUT

synchronizeイベントはプルリクエストに新しいコミットがプッシュされたときに発火します。 ワークフローの実行条件でpathsを指定するだけでは、該当ファイルの変更が含まれるプルリクエストにコミットをプッシュするたびにコメントが投稿されてしまいます。

そこでsynchronizeイベントの場合には新しくプッシュされたコミットに該当ファイルの変更が含まれる場合のみコメントを投稿します。新しくプッシュされたコミットに該当ファイルの変更が含まれるかどうかをdiff-countという変数に格納して、後のワークフローで参照可能にします。

差分のチェックをスキップ

- id: no-diff-check
  if: github.event.action != 'synchronize'
  run: echo "diff-count=1" >> $GITHUB_OUTPUT

openreopenイベントではプルリクエストに該当ファイルの差分が含まれればコメントが投稿されるようにしたいのでdiff-count=1とします。

プルリクエストにコメントを投稿

- uses: https://github.com/actions/github-script@v6
  if: steps.diff-check.outputs.diff-count > 0 || steps.no-diff-check.outputs.diff-count > 0
  with:
    script: |
    github.rest.issues.createComment({
        issue_number: context.issue.number,
        owner: context.repo.owner,
        repo: context.repo.repo,
        body: `hoge ディレクトリ配下のファイルが編集されました。`
    })

actions/github-script を利用してプルリクエストにコメントします。

終わりに

公式のActionが充実しているので実装は簡単でしたが、synchronizeイベント周りで少し工夫が必要でした。 参考になれば幸いです。