はじめに
はじめまして。 新規事業開発チームのエンジニア櫻田です。
私たちのチームではGitHub ActionsとGitHub apiを活用して色んな作業を自動化しているので少しずつ紹介していきたいと思います。
今回はプルリクエスト開設時にレビュワーを自動設定する方法を紹介します。
初回なので構文の解説も行なっていきます!
実現すること
- プルリクエスト開設時にレビュワーを自動設定する
- チームメンバーが変わってもコードを変更せずに対応する
急いでいる人向け 完成ファイル
name: PR Reviewer Auto Assignment
on:
pull_request:
types: [opened, reopened, ready_for_review]
jobs:
reviewer-assign:
if: |
# お好きな条件分を設定ください
github.event.pull_request.base.ref != 'main' && startsWith(github.head_ref, 'feature')
runs-on: ubuntu-latest
env:
API_BASE_URL: "https://api.github.com"
ACCEPT_HEADER: "Accept: application/vnd.github+json"
VERSION_HEADER: "X-GitHub-Api-Version: 2022-11-28"
AUTH_HEADER: "Authorization: Bearer ${{ secrets.PULL_REQUEST_API_TOKEN }}"
ORG: "organization" # githubの組織名を設定してください
TEAM: "team" # レビュワーに設定したいチーム名を設定してください
steps:
- name: Get Members List
id: get-members-list
run: |
response=$(curl -X GET \
-H "$ACCEPT_HEADER" \
-H "$VERSION_HEADER" \
-H "$AUTH_HEADER" \
$API_BASE_URL/orgs/$ORG/teams/$TEAM/members)
members=$(echo $response | jq '[.[].login | select(. != "${{ github.actor }}")]')
echo ::set-output name=members::$members
- name: Set Reviewers
id: set-reviewers
run: |
reviewers=$(curl -X GET \
-H "$ACCEPT_HEADER" \
-H "$VERSION_HEADER" \
-H "$AUTH_HEADER" \
$API_BASE_URL/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers)
reviewr_count=$(echo $reviewers | jq '.users | length')
if [ $reviewr_count -eq 0 ]; then
curl -X POST \
-H "$ACCEPT_HEADER" \
-H "$VERSION_HEADER" \
-H "$AUTH_HEADER" \
$API_BASE_URL/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers \
-d '{ "reviewers": ${{ steps.get-members-list.outputs.members }} }'
fi
ワークフローの設定
.github/workflows
配下にymlファイルを作成します。
まずはnameとonまで記載します。
name: PR Reviewer Auto Assignment
on:
pull_request:
types: [opened, reopened, ready_for_review]
name
ワークフローの名前
リポジトリの[アクション]タブに表示される。
省略するとファイルのパスになる
on
ワークフロー実行のトリガーとなるイベントを定義する。
設定できるイベント一覧
今回はプルリクエストを開設した時に実行したいのでpull_requestを設定しています。
types
のデフォルトは[ opened(PRオープン), synchronize(PRオープン後push), reopened(PR再オープン) ]
ですが今回はdraftで開設後readyにした場合も実行したい&PRオープン後pushでは実行したくない為明示的に指定しています。
続いてjobsを設定していきます。
jobs:
reviewer-assign:
if: |
github.event.pull_request.base.ref != 'main' && startsWith(github.head_ref, 'feature')
runs-on: ubuntu-latest
env:
API_BASE_URL: "https://api.github.com"
ACCEPT_HEADER: "Accept: application/vnd.github+json"
VERSION_HEADER: "X-GitHub-Api-Version: 2022-11-28"
AUTH_HEADER: "Authorization: Bearer ${{ secrets.PULL_REQUEST_API_TOKEN }}"
ORG: "organization" # githubの組織名を設定してください
TEAM: "team" # レビュワーに設定したいチーム名を設定してください
jobs
ワークフローで実行される一連の処理
必ず一つは設定する必要があり複数作成することもできる。
jobs.id
ジョブの一意の識別子
今回はreviewer-assign
とします。
jobs.id.name
ジョブに名前を分かりやすいつけることができる。
省略すると実行時にはidが表示されます。今回は省略しています。
jobs.id.if
条件文を使って、条件が満たされなければジョブを実行しないようにできる。
設定できる条件
今回はbaseブランチがmain以外かつheadブランチがfeatureから始まるブランチのみに限定する条件式を書いています。
startsWithなどを使用すれば部分一致なども実現することができます。
使用できる演算子やリテラル
また、ワークフローの中では様々な情報を取得することができます。(今回のbaseブランチ名やheadブランチ名など)頻繁に使用するので知っておくと便利です。
取得できるコンテキスト
jobs.id.runs-on
ジョブを実行するマシンの種類を定義できる。
今回はubuntu
を指定しています。
jobs.id.env
ジョブ中のすべてのステップで使うことができる変数を設定できる。
今回は以下を設定しています。
- API_BASE_URL
- github apiのurl
- ACCEPT_HEADER
- VERSION_HEADER
- AUTH_HEADER
- 共通のヘッダー。
${{ secrets.PULL_REQUEST_API_TOKEN }}
の解説は後で行います
- 共通のヘッダー。
- ORG
- 所属している組織名
- TEAM
- レビュワーに設定したいチーム名。チームの設定の解説は後で行います。
続いてstepsを設定していきます。
steps:
- name: Get Members List
id: get-members-list
run: |
response=$(curl -X GET \
-H "$ACCEPT_HEADER" \
-H "$VERSION_HEADER" \
-H "$AUTH_HEADER" \
$API_BASE_URL/orgs/$ORG/teams/$TEAM/members)
members=$(echo $response | jq '[.[].login | select(. != "${{ github.actor }}")]')
echo ::set-output name=members::$members
- name: Set Reviewers
id: set-reviewers
run: |
reviewers=$(curl -X GET \
-H "$ACCEPT_HEADER" \
-H "$VERSION_HEADER" \
-H "$AUTH_HEADER" \
$API_BASE_URL/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers)
reviewr_count=$(echo $reviewers | jq '.users | length')
if [ $reviewr_count -eq 0 ]; then
curl -X POST \
-H "$ACCEPT_HEADER" \
-H "$VERSION_HEADER" \
-H "$AUTH_HEADER" \
$API_BASE_URL/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers \
-d '{ "reviewers": ${{ steps.get-members-list.outputs.members }} }'
fi
jobs.id.steps
ジョブで実行される一連のタスクを定義できる。
複数設定することもできる。
様々な設定を行えます。公式ドキュメント
Get Members List
stepsの中のGet Members List
について解説していきます。
run内の以下の部分でgithub apiを使用してチームメンバーを取得しています。
api ドキュメント
response=$(curl -X GET \
-H "$ACCEPT_HEADER" \
-H "$VERSION_HEADER" \
-H "$AUTH_HEADER" \
$API_BASE_URL/orgs/$ORG/teams/$TEAM/members)
そして以下の部分でjqを使用しresponseからメンバーのusernameを整形し取り出しています。その中でpr開設者は省いています。
members=$(echo $response | jq '[.[].login | select(. != "${{ github.actor }}")]')
最後に以下の部分でメンバーのusername配列をoutputしています。outputすることで次のステップで値を参照できるようになります。
echo ::set-output name=members::$members
Set Reviewers
最後になりますがstepsの中のSet Reviewers
について解説していきます。
以下の部分で現在のレビュワーに設定されている人数を取得しています。たまに手動で設定したい場合があるので既に設定されている場合は自動設定をスキップする為に取得しています。
api ドキュメント
reviewers=$(curl -X GET \
-H "$ACCEPT_HEADER" \
-H "$VERSION_HEADER" \
-H "$AUTH_HEADER" \
$API_BASE_URL/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers)
reviewr_count=$(echo $reviewers | jq '.users | length')
以下の部分でレビュワーを設定しています。上に書いたように一人以上レビュワーが設定済みならスキップするようにしています。
if [ $reviewr_count -eq 0 ]; then
curl -X POST \
-H "$ACCEPT_HEADER" \
-H "$VERSION_HEADER" \
-H "$AUTH_HEADER" \
$API_BASE_URL/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers \
-d '{ "reviewers": ${{ steps.get-members-list.outputs.members }} }'
fi
やっと完成しました!
name: PR Reviewer Auto Assignment
on:
pull_request:
types: [opened, reopened, ready_for_review]
jobs:
reviewer-assign:
if: |
# お好きな条件分を設定ください
github.event.pull_request.base.ref != 'main' && startsWith(github.head_ref, 'feature')
runs-on: ubuntu-latest
env:
API_BASE_URL: "https://api.github.com"
ACCEPT_HEADER: "Accept: application/vnd.github+json"
VERSION_HEADER: "X-GitHub-Api-Version: 2022-11-28"
AUTH_HEADER: "Authorization: Bearer ${{ secrets.PULL_REQUEST_API_TOKEN }}"
ORG: "organization" # githubの組織名を設定してください
TEAM: "team" # レビュワーに設定したいチーム名を設定してください
steps:
- name: Get Members List
id: get-members-list
run: |
response=$(curl -X GET \
-H "$ACCEPT_HEADER" \
-H "$VERSION_HEADER" \
-H "$AUTH_HEADER" \
$API_BASE_URL/orgs/$ORG/teams/$TEAM/members)
members=$(echo $response | jq '[.[].login | select(. != "${{ github.actor }}")]')
echo ::set-output name=members::$members
- name: Set Reviewers
id: set-reviewers
run: |
reviewers=$(curl -X GET \
-H "$ACCEPT_HEADER" \
-H "$VERSION_HEADER" \
-H "$AUTH_HEADER" \
$API_BASE_URL/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers)
reviewr_count=$(echo $reviewers | jq '.users | length')
if [ $reviewr_count -eq 0 ]; then
curl -X POST \
-H "$ACCEPT_HEADER" \
-H "$VERSION_HEADER" \
-H "$AUTH_HEADER" \
$API_BASE_URL/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers \
-d '{ "reviewers": ${{ steps.get-members-list.outputs.members }} }'
fi
Tokenの設定
github apiを使用する為にtokenを設定します。
Fine-grained personal access tokensを生成
Fine-grained personal access tokensとは詳細に権限を設定できるbeta版の機能にです。ですが今後はこちらがメインになる可能性が高い?ようです。
参考
手順1
以下へアクセスします。
https://github.com/settings/tokens?type=beta
手順2
このような画面が表示されるのでお好きなToken nameとExpirationとDescriptionを設定してください。
手順3
Github Actionsを実行するリポジトリを選択してください。
手順4
Permissionsを設定していきます。
Repository permissions
の中からPull requests
をRead and write
に設定します。
Organization permissions
の中からMembers
をRead and write
に設定します。
Overviewが以下のような表示になっていればokです。
Generate token
を押下してください。
Tokenが生成されるので忘れないようにコピーしてください。
Actions secretsの設定
Github Actions内で使用できるように設定をしていきます。
以下へアクセスします。orgsは各自置き換えてください
https://github.com/{orgs}/mikiwame/settings/secrets/actions
New repository secret
を押下すると以下画面になるのでお好きなnameを設定し先ほど生成したtokenをペーストしてください。
これでactions内で
${{ secrets.PULL_REQUEST_API_TOKEN }}
のように使用できるようになりました!tokenの設定は以上です。