これは ゆめみ Advent Calendar 2019 の10日目の投稿です。
皆さんはもう GitHub Actions を使っていますでしょうか?便利ですよね。
CI(継続的インテグレーション)でテストしたりビルドしたりするのに利用することが多いかと思いますが、GitHub 上の作業を自動化するのにも使えたりします。
今回は、プルリクエストを作成したら自動で Assignees と Reviewers を設定するワークフローを紹介します。
(毎回これらが決まりきっている場合、プルリクエストを作る毎に設定するのは面倒ですよね。)
参考
Assignees の自動設定
assignees は基本的には当該プルリクエストの対応(レビューの対応)をする人になると思うので、プルリクエストを作成した本人とします。
ワークフローの設定は次のようになります。
name: Assign auto
on:
pull_request:
types: opened # プルリクを作成したタイミングだけで動かす
jobs:
assign:
name: Set assignees
runs-on: ubuntu-18.04
steps:
- name: Set assignees
env:
ASSIGNEES: "${{ github.actor }}" # 変えたければここを変える
run: |
assignee_count=$(cat ${{ github.event_path }} | jq '.pull_request.assignees | length')
if [[ 0 == $assignee_count ]]; then
assignees=$(echo "\"${ASSIGNEES// /}\"" | jq 'split(",")')
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-d "{ \"assignees\": $assignees }" \
https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/assignees
fi
${{ github.XXX }}
は公式ドキュメントを見てもらえば分かりますが、GitHub 上の情報(今回はプルリクエスト)を参照する構文です。勘違いしやすいのですが、環境変数ではありません。「実行前に静的に文字列置換される」という感覚が近いです。${{ secrets.GITHUB_TOKEN }}
も標準で利用できる構文で、GitHub API アクセス用のトークンに置き換えられます。
assignee_count
はプルリク作成と同時に設定された assignees の数です。これがゼロの場合に curl コマンドで GitHub API を叩いて assignees を設定します。
assignees=$(echo "\"${ASSIGNEES// /}\"" | jq 'split(",")')
の箇所が少し分かりづらいので補足します。仮に環境変数 ASSIGNEES
に設定されたアカウントが hoge, fuga
とすると、
-
${ASSIGNEES// /}
でスペースを削除 ..hoge,fura
-
"\"${ASSIGNEES// /}\""
でダブルクォートを付加しJSONの文字列とする(後続のjq
コマンドで扱えるようにする) .."hoge,fuga"
-
jq 'split(",")'
でjq
コマンドにより文字列をJSONの配列にする ..[ "hoge", "fuga" ]
といったことをしています。
Reviewers の自動設定
ワークフローの設定は次のようになります。
name: Assign auto
on:
pull_request:
types: opened
jobs:
assign:
name: Set reviewers
runs-on: ubuntu-18.04
steps:
- name: Set reviewers
env:
REVIEWERS: "hoge, fuga, piyo" # edit here
run: |
reviewer_count=$(cat ${{ github.event_path }} | jq '.pull_request.requested_reviewers | length')
if [[ 0 == $reviewer_count ]]; then
reviewers=$(echo "\"${REVIEWERS// /}\"" | jq 'split(",") | .-["${{ github.actor }}"]')
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-d "{ \"reviewers\": $reviewers }" \
https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers
fi
assignee の設定とあまり変わらないので説明は割愛しますが、プルリクを作成した本人は reviewers から除外している(レビュアに設定する必要がないし、GitHub API でもエラーになる)ことだけ注意です。
まとめると
上記2つのワークフローをまとめると次のようになります。
name: Assign auto
on:
pull_request:
types: opened
jobs:
assign:
name: Set assignees and reviewers
runs-on: ubuntu-18.04
steps:
- name: Set assignees
env:
ASSIGNEES: "${{ github.actor }}"
run: |
assignee_count=$(cat ${{ github.event_path }} | jq '.pull_request.assignees | length')
if [[ 0 == $assignee_count ]]; then
assignees=$(echo "\"${ASSIGNEES// /}\"" | jq 'split(",")')
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-d "{ \"assignees\": $assignees }" \
https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/assignees
fi
- name: Set reviewers
env:
REVIEWERS: "hoge, fuga, piyo" # edit here
run: |
reviewer_count=$(cat ${{ github.event_path }} | jq '.pull_request.requested_reviewers | length')
if [[ 0 == $reviewer_count ]]; then
reviewers=$(echo "\"${REVIEWERS// /}\"" | jq 'split(",") | .-["${{ github.actor }}"]')
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-d "{ \"reviewers\": $reviewers }" \
https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers
fi
もしブランチ毎に reviewers が異なる、という場合は、ワークフローの実行条件のところでブランチを指定するか(yamlファイルはブランチ分用意する)、
on:
pull_request:
branch:
- master
もしくは steps
内で
- name: Set reviewers
if: github.base_ref == 'master'
- name: Set reviewers
if: startsWith(github.base_ref, 'develop') # 前方一致
のようにして各ステップを実行するか否かを制御すればいいでしょう。
今回は固定メンバーを全員 reviewrs として設定していますが、スクリプトを工夫すればランダムに選択して設定、等もできると思います。
おわりに
いかがだったでしょうか。もし他に良い利用事例があれば、紹介いただけると幸いです。
それではよい GitHub Actions ライフを!
2020年10月26日 追記
上記の機能+αを、独立した GitHub の Action として切り出しました。
この Action を利用すると、次のようにシンプルに書けます
name: Review Assign
on:
pull_request:
types: [opened, ready_for_review]
jobs:
assign:
runs-on: ubuntu-latest
steps:
- uses: hkusu/review-assign-action@v0.1.0
with:
assignees: ${{ github.actor }}
reviewers: hoge, fuga, piyo