【GtiHub Actions】PR 作成時に作成者を自動アサインする【詳解】
はじめに
毎回 PR の assignees に自分を割り当てるのが面倒だったため、自動化しました。GitHub Actions で実現する方法を書いています。
後半では使用した GitHub Actions の API の解説を書いています。英語の記事を読むに当たり、よしなに DeepL や LLM を使用しています。
assignees に自動アサインする方法の調査
主に以下の方法がありそうでした。
- GitHub Actions でワークフローを作成 (本記事の内容)
- GtiHub Actions の公開 Action を利用 (assign-author)
- GitHub Bot を利用 (auto-assign)
今回は1を採用しました。今回のワークフローの単純さから、外部ライブラリを使用する学習コストよりも、ワークフローのメンテナンス・コストの方が低いと感じたためです。
コード
PR の assignees に作成者を自動アサインする GitHub Actions のコードは、以下のとおりです。
name: Auto PR Assign
on:
pull_request:
types: ["opened"]
permissions:
pull-requests: write
repository-projects: read
jobs:
assign:
# ボットが作成した PR をスキップする
if: endsWith(github.actor, '[bot]') == false
runs-on: ubuntu-latest
timeout-minutes: 1
steps:
- name: Add event actor to assignees
run: gh pr edit ${{ github.event.number }} --add-assignee ${{ github.actor }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
GITHUB_TOKEN
の割り当て方法
他の記事では以下の割り当て方をよく見かけました。
GH_TOKEN: ${{ github.token }}
自動トークン認証
の内容に合わせ、以下のように変更しています。
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
既にアサインされているかの判定
他の記事では以下の判定をよく見ましたが、排除しました。on.pull_request.types
で openned
を指定しており、PR 作成時にすでにアサインされているような状況がないと考えたためです。
if: github.event.pull_request.assignee == null
もし間違っていればコメントをお願いします。
解説
筆者はあまり GitHub Actions に詳しくなく、この機会に調べてみました。基本的に公式ドキュメントを参照し、内容を要約しています。
on.pull_request
- ワークフローの概要
- ワークフローのリポジトリにあるプルリクエストのアクティビティが発生したときに、ワークフローを実行する
- ワークフローのトリガー
- デフォルトは
open
,synchronize
,reopened
の3つのアクティビティタイプ - ワークフローを起動するアクティビティタイプを変更するには、types キーワードを使う
- デフォルトは
- マージ・コンフリクト
- PR にマージ・コンフリクトがある場合、ワークフローは実行されない
- マージ・コンフリクトは最初に解決されなければならない
- しかし、
pull_request_target
イベントを持つワークフローは、PR にマージ・コンフリクトがあっても実行される-
pull_request_target
トリガーを使用する前に、セキュリティリスクについて知っておく必要がある
-
- PR にマージ・コンフリクトがある場合、ワークフローは実行されない
on.pull_request.types
pull_request の項目の、Activity types にある値を指定できる。
以下に代表的なものを列挙する。
タイプ | 説明 |
---|---|
assigned |
ユーザーがプルリクエストに割り当てられる |
unassigned |
ユーザーがプルリクエストから解除される |
labeled |
ラベルがプルリクエストに適用される |
unlabeled |
ラベルがプルリクエストから削除される |
opened |
プルリクエストが作成される |
edited |
タイトル、本文、またはベースブランチが変更される |
closed |
プルリクエストが閉じられる(マージされない場合) |
reopened |
閉じたプルリクエストが再度開かれる |
synchronize |
コミットがプルリクエストにプッシュされる |
ready_for_review |
プルリクエストが下書きモードから解除される |
locked |
プルリクエストがロックされる |
unlocked |
プルリクエストのロックが解除される |
review_requested |
ユーザーにレビューをリクエストする |
review_request_removed |
ユーザーからのレビューリクエストを削除する |
permissions
- パーミッション
-
GITHUB_TOKEN
に付与されたデフォルトのパーミッションを変更できる - 必要に応じてアクセスを追加または削除することで、必要最小限のアクセスのみを許可することができる
- 詳細については、自動トークン認証 を参照
-
- スコープ
- トップレベル・キー
- ワークフロー内のすべてのジョブに適用する
- ジョブ・キー
- 特定のジョブに対してパーミッションを適用する
- ジョブ内で
GITHUB_TOKEN
を使用するすべてのアクションおよび実行コマンドが、指定したアクセス権を獲得する - 詳細は
jobs.<job_id>.permissions
を参照
- ジョブ内で
- 特定のジョブに対してパーミッションを適用する
- トップレベル・キー
- パーミッションの値
-
read
(該当する場合),write
,none
のいずれかのアクセスレベルを割り当てることができる
-
- パーミッションの種類
- 以下の表を参照
- これらのパーミッションのどれかにアクセスを指定すると、指定されていないパーミッションの値はすべて
none
に設定される
パーミッション | 説明 |
---|---|
actions |
GitHub Actionsのワークフローを操作します。例: actions: write でワークフローを作成、更新、削除できます。 |
checks |
チェックの操作を行います。例: GitHubのチェック API を使用してステータスチェックを生成します。 |
contents |
リポジトリのコンテンツ(ファイル)にアクセスします。例: ファイルの読み取り、作成、更新が可能です。 |
deployments |
デプロイメントの管理を行います。例: 環境へのデプロイを管理したり作成したりします。 |
discussions |
GitHub Discussions の操作を行います。例: ディスカッションの作成、変更が可能です。 |
issues |
GitHubのIssueの操作を行います。例: Issueを読み取り、コメント、または作成します。 |
packages |
GitHub Packagesを管理します。例: パッケージを公開またはインストールする操作が可能です。 |
pages |
GitHub Pages のコンテンツを管理します。例: ページのビルドとデプロイを行います。 |
pull-requests |
Pull Request の管理を行います。例: PRに対してコメントしたりラベルを追加したりします。 |
repository-projects |
GitHub プロジェクトの操作を行います。例: プロジェクトボードを読み取り、更新します。 |
security-events |
GitHubのセキュリティ関連イベントを操作します。例: Dependabotアラートへのアクセスを許可します。 |
statuses |
コミットに対するステータスの操作を行います。例: ステータスチェックを作成、更新します。 |
jobs
- 構成
- ワークフローの実行は 1 つ以上のジョブで構成される
- 並列実行と直列実行
- デフォルトではジョブは並行して実行される
- ジョブを連続して実行するには、
jobs.<job_id>.needs
キーワードを使用する- 他のジョブへの依存関係を定義する
- 実行環境
- 各ジョブは、
runs-on
で指定された実行環境で実行される
- 各ジョブは、
- ジョブの実行数・課金
- ワークフローの使用量制限内であれば、ジョブの実行数は無制限である
- GitHubホスト型ランナーについては 使用制限、課金、管理 を参照
- セルフホスト型ランナーについては セルフホスト型ランナーについて を参照
- ワークフローの使用量制限内であれば、ジョブの実行数は無制限である
jobs.<job_id>
- ジョブ ID
- ジョブに一意な識別子を付与する
- キー
job_id
は文字列である- 文字または
_
で始まる必要がある - 英数字,
-
,_
のみを使用できる
- 文字または
jobs.<job_id>.steps
- ステップ
- ジョブにはステップと呼ばれる一連のタスクが含まれる
- ステップでは以下のようなことができる
- コマンドを実行する
- セットアップタスクを実行する
- 自分のリポジトリや公開リポジトリ、Dockerレジストリで公開されているアクションを実行する
- 実行プロセス
- 各ステップは実行環境内の独自のプロセスで実行される
- ワークスペースとファイルシステムにアクセスできる
- ステップ間での環境変数の変更は保存されない
- 各ステップは実行環境内の独自のプロセスで実行される
- ビルドインステップ
- GitHub には、ジョブのセットアップと完了のためのビルトインステップが用意されている
- 表示制限
- GitHub には最初の 1,000 個のチェックしか表示されない
- ワークフローの使用量制限内であれば、ステップの数は無制限に実行できる
jobs.<job_id>.runs-on
-
runs-on
- ジョブを実行するマシンの種類を定義する
- マシンの種類
- GitHubホストランナー
- 大規模ランナー
- セルフホストランナー
- ランナーのターゲット方法
- ランナーに割り当てられたラベル
- グループメンバーシップ
- 上記の組み合わせ
-
runs-on
の有効な値- 文字列
- 文字列を含む変数
- 文字列の配列、文字列を含む変数、またはその両方の組み合わせ
-
group
、またはlabel
キーを使ったkey: value
ペア
- 変数と文字列の混合
- 以下のように、配列の中に変数と文字列を混ぜることができる
-
runs-on: [self-hosted, "${{ inputs.chosen-os }}"]
- より詳細なサンプルは 元記事 のコードを参照
-
- 以下のように、配列の中に変数と文字列を混ぜることができる
- 配列の指定
- ワークフローは指定された
run-on
の値の全てにマッチするランナー上で実行される - 例えば、以下の場合はジョブは
linux
,x64
,gpu
のラベルを持つセルフホストランナーのみで実行されるruns-on: [self-hosted, linux, x64, gpu]
- ワークフローは指定された
- 複数マシンでの実行
- ワークフローを複数のマシンで実行したい場合は、
jobs.<job_id>.strategy
を使用する
- ワークフローを複数のマシンで実行したい場合は、
jobs.<job_id>.steps[*].timeout-minutes
- タイムアウト分数
- プロセスを終了する前にステップを実行する最大分数
- 値は正の整数である必要がある
jobs.<job_id>.steps[*].name
- ステップ名
- GitHub で表示するステップの名前
jobs.<job_id>.steps[*].run
- run
- コマンドライン・プログラムをオペレーティング・システムのシェルを使用して実行する
- 上限値
- 21,000文字
- ステップ名
-
name
を指定しない場合、ステップ名はデフォルトでrun
コマンドで指定されたテキストになる
-
- シェルの変更
- 別のシェルを選択し、コマンドの実行に使用するシェルをカスタマイズすることがきる
- 詳細については、
jobs.<job_id>.steps[*].shell
を参照
- 書き方
- 単一行と複数行の書き方は以下を参照
# 単一行
- name: Install Dependencies
run: npm install
# 複数行
- name: Clean install dependencies and build
run: |
npm ci
npm run build
jobs.<job_id>.steps[*].env
- ステップの変数
- 実行環境で使用するステップの変数を設定する
- ワークフロー全体やジョブに対して変数を設定することもできる
- 詳しくは
env
とjobs.<job_id>.env
を参照
- 詳しくは
- 変数名の重複と優先度
- 複数の環境変数が同じ名前で定義されている場合、GitHub は最も具体的な変数を使用する
- 例えば、あるステップで定義された環境変数は、そのステップが実行されている間、同じ名前のジョブやワークフローの環境変数を上書きする
- ジョブに定義された環境変数は、ジョブが実行されている間、同名のワークフロー変数を上書きする
- 複数の環境変数が同じ名前で定義されている場合、GitHub は最も具体的な変数を使用する
- 公開アクションの変数へのアクセス
- 公開アクションでは、READMEファイルで期待される変数を指定することができる
- シークレット情報へのアクセス
- パスワードやトークンなどのシークレット値を設定する場合は、
secrets
コンテキストを使用して設定する必要がある- 詳細については、ワークフロー実行に関するコンテキスト情報へのアクセス を参照
- パスワードやトークンなどのシークレット値を設定する場合は、
steps:
- name: My first action
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FIRST_NAME: Mona
LAST_NAME: Octocat
終わりに
どうやら、GitHub Actions のトリガーには、 GitHub の Webhook イベントを利用しているようですね。ワークフローのトリガーとなるイベント には、冒頭に以下の記述がありました。
ワークフローのトリガーは、ワークフローを実行させるイベントです。イベントには複数のアクティビティタイプがあります。各アクティビティタイプの意味については、Webhook イベントとペイロード を参照してください。
また、最初は公式ドキュメントに出てくる README file
のことがよくわかりませんでした。調べたところ、カスタムアクションについて の内容が該当しそうでした。
- README.md ファイル
- アクションの使用方法を伝えるため、README ファイルを作成することをお勧めする
-
README.md
には、以下の情報を含めることができる- アクションが実行する内容の説明
- 必須の入力引数と出力引数
- オプションの入力引数と出力引数
- アクションが使用するシークレット
- アクションが使用する環境変数
- ワークフローにおけるアクションの使用例
これは公開するアクションの製作者向けですかね。
「GitHub Actions わからん」から「GitHub Actions 完全に理解した(理解していない)」まで進化できました。どこかで、GitHub Actions の基本についてまとめた記事も書きたいですね。
以上、GitHub Actions で PR の assignees に自動アサインする方法と、実現において使用した GitHub Actions の API の解説でした。
Discussion