何かやってみるブログ

興味をもったこと、趣味のこと、技術について色々書きます。

GithubActionsで特定のディレクトリ配下での変更があるPRがトリガーになる場合、関連するissueに特定のlabelを付与したい。

お仕事で偉い人から特定のディレクトリ配下に変更があった場合は特定のlabelをつけてくれって言われたものの、手動だと忘れてしまう事案が発生してしまうのでGitHub Actionsで解決するようにしたい。 仕事で使う前にいつもの通り自分のsandboxのプロジェクトのリポジトリで試した。

動かすと以下のようなlabelが追加されたり、取り除かれている。(rspecが落ちているのでそれはいつか直したい。)

github.com

設定は以下の通り。全体の流れとしては以下のようになる。

  • checkout
  • PRの元になったブランチ名を取得する。そこからissueの番号をgrepして取得する。例) feature/1234というブランチからmasterのPRであればfeature/1234というブランチ名を取得して1234 というissue番号を取得するような感じになる。
  • tj-actions/changed-files@v37というアクションを使ってPRで変更のあったファイルを取得
  • github-scriptを使って lib/tasks/**配下に変更だった場合はlabelsに taskというラベルを追加。
  • github-scriptを使って lib/tasks/**配下に変更がなかった場合はlabelsに taskというラベルを取り除く。
name: Manage Label
on:
  pull_request:

jobs:
  apply-label:
    runs-on: ubuntu-latest
    steps:
      - name: Check out
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Set issue number
        run: |
          issue_number=$(echo ${{github.head_ref}} | grep -o "[0-9]\+")
          echo "ISSUE_NUMBER=${issue_number}" >> $GITHUB_ENV
      - name: Get chnaged files
        uses: tj-actions/changed-files@v37
        id: changed-files
        with:
          files_yaml: |
            task:
              - lib/tasks/**
      - name: Add label
        uses: actions/github-script@v6
        if: steps.changed-files.outputs.task_any_changed == 'true'
        env:
          ISSUE_NUMBER: ${{ env.ISSUE_NUMBER }}
        with:
          script: |
            const { ISSUE_NUMBER } = process.env
            github.rest.issues.addLabels({
              issue_number: ISSUE_NUMBER,
              owner: context.repo.owner,
              repo: context.repo.repo,
              labels: ['task']
            })
      - name: Remove label
        uses: actions/github-script@v6
        if: steps.changed-files.outputs.task_any_changed == 'false'
        env:
          ISSUE_NUMBER: ${{ env.ISSUE_NUMBER }}
        with:
          script: |
            const { ISSUE_NUMBER } = process.env
            github.rest.issues.removeLabel({
              issue_number: ISSUE_NUMBER,
              owner: context.repo.owner,
              repo: context.repo.repo,
              name: 'task'
            })

Add labelとRemove labelのstepはリファクタリングできそうな感じがするので、いつかやりたい。