actions/github-script を使って Pull Request のレビュワーに自動アサインする
はじめに
Pull Request を作成するたびに手動で任意のレビュワーをアサインするのは面倒です。
では、コードオーナーを指定して常に一定の人をアサインすれば良いかというと、チームメンバー全員をアサインすることになったり、レビュワーが固定化されてしまう可能性があります。
ということで、Pull Request 作成時に、特定のグループから一人づつランダムに自動でアサインする GitHub Actions のワークフローを作成してみました。
actions/github-script とは
actions/github-script は GitHub API の呼び出しを JavaScript で書ける公式の Action です。
サードパーティの Action を使いたくないという時や GitHub のちょっとした操作を簡単に行いたいといった場合に有用です。
実態の処理は octokit/rest.js で行われているので、操作する時はこちらのドキュメントを参照すると使い方が分かりやすいです。
GitHub Actions の実装
今回の GitHub Actions の実装はこちらです。
assignees には Pull Request の作成者をアサイン、
reviewers にはグループとメンバーを定義して、それぞれのグループから一人ずつランダムに抽出してアサインしています。
その時、reviewers には Pull Request の作成者はアサインできないので除いています。
name: Auto assign pull requests
on:
pull_request:
types: [opened]
permissions:
pull-requests: write
issues: read
jobs:
assign:
name: Assign assignees and reviewers
runs-on: ubuntu-latest
steps:
- name: Assign Pull Request Author as Assignee
uses: actions/github-script@v6
if: ${{ toJSON(github.event.pull_request.assignees) == '[]' }} # Assignees を設定していない時だけ動かす
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { number, user } = context.payload.pull_request;
await github.rest.issues.addAssignees({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: number,
assignees: [user.login]
});
- name: Assign random reviewers
uses: actions/github-script@v6
if: ${{ toJSON(github.event.pull_request.requested_reviewers) == '[]' }} # Reviewers を設定していない時だけ動かす
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
// 任意のグループとメンバーを定義
const groups = {
group1: ['user1', 'user2', 'user3'],
group2: ['user4', 'user5', 'user6'],
group3: ['user7', 'user8', 'user9']
};
const author = context.payload.pull_request.user.login;
const reviewers = [];
for (const [group, members] of Object.entries(groups)) {
// Pull Request 作成者はアサインから除く
const filteredMembers = members.filter(user => user !== author);
if (filteredMembers.length > 0) {
const randomReviewer = filteredMembers[Math.floor(Math.random() * filteredMembers.length)];
reviewers.push(randomReviewer);
}
}
await github.rest.pulls.requestReviewers({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
reviewers
});
さいごに
actions/github-script
は octokit/rest.js
のドキュメントが分かりやすく、クライアントが素直に呼べるので直感的に書ける印象でした。
今回は対象のグループやメンバーを JavaScript 内で定義しましたが、別ファイルに切り出したり、CODEOWNERS から参照するなどが可能です。
この程度であれば shell でもそのまま書けますが、actions/github-script
を使用することで記述が短く、shell が苦手でも JavaScript が書ければ改修できます。
また、要件が変わった時、shell に比べてロジックも修正しやすいだろうと判断して使用してみました。
参考
GitHub Actions でプルリクエストの自動アサインをする
PR の assignees が空だったときに自動アサイン
actions/github-script
Discussion