GitHub Actions の on.push でマージする PR についたラベルを取得する

2024-09-28

github オブジェクトの中身を知る

on.pull_requeston.push で取得できるオブジェクトが異なるため、具体的にどのようなものが取得できるのか確認したくなった。

以下のような action を作ることで main に push してオブジェクトの中身を確認できる。

on:
  push:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 1
    steps:
      - name: checkout
        uses: actions/checkout@v4

      - name: echo github
        run: echo '${{ toJSON(github) }}'

github オブジェクトの commit id から Pull Request を検索する

前述の方法をオブジェクトを確認すると、元の Pull Request のコミットハッシュが github.event.commits[0].id に入っていたので、これを元に Pull Request number を検索する。

  - name: pass PR's commit hash as id
    id: commit_id
    run: |
      echo "id=${{ github.event.commits[0].id }}" >> $GITHUB_OUTPUT      

  - name: get pull-request number
    uses: actions/github-script@v7
    id: get_pr_number
    env:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    with:
      script: |
        if ( context.issue.number ) {
          return context.issue.number;
        } else {
          return (
            await github.rest.repos.listPullRequestsAssociatedWithCommit({
              commit_sha: "${{ steps.commit_id.outputs.id }}",
              owner: context.repo.owner,
              repo: context.repo.repo,
            })
          ).data[0].number;
        }        
      result-encoding: string

  - name: issue number
    run: echo "${{ steps.get_pr_number.outputs.result }}"

GitHub Actions で commit から PR 番号を取得する で使った octokit.js の listPullRequestsAssociatedWithCommit を使っている。引数の commit_sha を 今回取得した github.event.commits[0].id に置き換えただけだ。

これで result として Pull Request number が取得できるので、あとは gh コマンドで labels を取得する。

gh pr view $PRnum --json labels を使ってラベルを取得する

以下のような step を足して、gh pr view $PRnum で Pull Request の情報を取得する。今回は labels だけが取得目的なので --json labels をつけている。

on:
  push:
    branches:
      - main

permissions:
  pull-requests: read
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 1
    steps:
      # ... 中略 ...
      - name: issue number
        run: echo "${{ steps.get_pr_number.outputs.result }}"

      - name: get labels from pr
        id: include-tag
        env:
          GH_NUM: ${{ steps.get_pr_number.outputs.result }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          echo $( gh pr view $GH_NUM --json labels | jq -r '.labels // empty | .[] | .name' )          

--jq オプションが gh pr view 自体にあるが、jq の中で | を使うときにどうするんだっけ?となったのと、 -r オプションと組み合わせられるのかわからなかったため、はじめから jq を | で使うことを選択した。

なお、gh pr view $GH_NUM --json labels すると以下のような結果がえられる。

{
  "labels": [
    {
      "id": "LA_kwDOLhZ3D88AAAABwLNCEA",
      "name": "story",
      "description": "",
      "color": "0B4FA0"
    },
    {
      "id": "LA_kwDOLhZ3D88AAAABwLNPFA",
      "name": "release",
      "description": "",
      "color": "E58975"
    }
  ]
}

.labels が取れない (設定していない) 場合も想定して // empty をつけている。empty があることで labels が設定されていなくてもそれ以降の処理がエラーにならない。

jq コマンドで取得できたラベル名の情報は以下のような改行つなぎのテキストとして取得できたため、あとは好きなように加工して使うことができる。

story
release