私がプルリクレビュー時に使用している自作のGitHub Actions「action-repository-permission」について紹介します。利用シーンは限定されるActionsですが、GitHub Marketplaceにも公開していますので、OSSをメンテされている方をはじめ、本機能を必要と感じた方、興味がわいた方は試してみてもらえればと思います。
本Actionsが提供する機能
リポジトリに対するCollaboratorとしてのユーザ権限をチェックします。主に、writeまたはadminの権限を持っているかどうかをチェックするために使うケースを想定しています。
使い方
基本
下記はIssue書き込みしたユーザについて、Collaboratorとしてwrite以上の権限を持っているかどうかをチェックする例です。ユーザが権限を持っている場合には、ActionsワークフローのコンソールにA user trying to access is permitted
と表示されます。
on
issue_comment:
types:
- created
jobs:
steps:
- name: Check repository permission for user
id: permission
uses: sushichop/action-repository-permission@v1
with:
required-permission: write
- name: "The following will be executed if the permission is passed."
run: |
echo "A user trying to access is permitted"
応用例
本Actionsのオプション設定も使いつつ、ワークフロー記述内容に一手間加えることで、一定以上の権限を持つユーザのみが、コマンド入力感覚で特定処理を実行できるワークフローを作成できます。
下記はforkされたリポジトリからのプルリクレビュー時に、リポジトリに対してCollaboratorとしてwrite以上の権限を持つユーザが、Issueコメント欄に/danger
とコメント入力することで、レビューチェッカーであるdangerをCI実行させる記述例です。reaction-permitted
に設定された内容(下記ではrokcet)は、ワークフロー実行時にリアクションemojiとしてIssueコメント欄に反映されます。
一方、権限を持たないユーザが同じ内容をコメント入力した場合は、comment-not-permitted
に設定された内容がコメント欄に反映されてワークフローが終了します。
on:
issue_comment:
types:
- created
jobs:
danger:
name: Danger
if: |
github.event_name == 'issue_comment' && github.event.action == 'created'
&& github.event.issue.pull_request != null
&& startsWith(github.event.comment.body, '/danger')
runs-on: macos-11
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Check repository permission for user
uses: sushichop/action-repository-permission@v1
with:
required-permission: write
reaction-permitted: rocket
comment-not-permitted: Sorry, you don't have enough permission to execute `/danger`...
- name: Clone the PR source
uses: actions/checkout@v2
with:
ref: refs/pull/${{ github.event.issue.number }}/head
fetch-depth: 0
- name: Danger
run: |
bundle install
bundle exec danger
実際にどう使われているか知りたい場合は?
私がメンテしているOSS(CocoaLumberjack/CocoaLumberjack、sushichop/Puppyなど)で本Actionsを使っているので、過去のプルリクをいくつか覗いてみてもらえるとよいかと思います。/run_checks
や/danger
というコメント入力が見つかるはずです。不明点がある場合は、action-repository-permissionのIssueメニューから質問していだければ幸いです。
最後に
現在のところ、私がGitHub Marketplaceに公開しているActionsは今回紹介した1つのみなので、今回のアドカレ投稿を契機に、そろそろ新たなActionsを作ろうかなと考えています🙂
※ 補足(興味のある方のみ)
以下は長いので興味のある方のみお読みください。GitHub Actionsにおけるセキュリティに対する考え方やGITHUB_TOKEN
の権限に関する話です。
プルリクレビュー時において、わざわざ擬似的なコマンドを入力する形式でジョブを実行させているのは何故か?と疑問に思った方はいますでしょうか?本件について、私はセキュリティや使い勝手、その他いろいろなことを総合的に判断して考えるべき事項だと考えています。つまりケースバイスケースで考えるべきです。
実際のところ、私がメンテしているいくつかのOSSでは同じリポジトリからのプルリク(一般には悪意を持ったプルリクを出すことはないことが前提)に対してはプルリク時に全ジョブを自動実行させています。一方、forkされたリポジトリからのプルリクに対しては本Actionを使うことにより、一部のジョブについては自動実行させない(上記応用例のように、擬似的なコマンド入力によりワンクッションはさむ)ようにしています。これは第3者からのプルリク内容については、意識的に慎重にチェックする必要があると考えているためです。
興味が湧いた方は、DependabotにおけるGITHUB_TOKEN
への権限に関する投稿記事1を見ていただくとよいかもしれません。紆余曲折を経て現在の仕様になっていること__に加え、GITHUB_TOKEN
に関するデフォルト権限はReadであること__がポイントです。記事内容から、セキュリティと運用面における柔軟性の両方を考慮していることが垣間見えないでしょうか?
今回紹介したActionsは1年半ほど前につくったものですが、最終的に現在の仕様になっているDependabotと同様に、セキュリティと運用面における柔軟性の両方を考慮した上で、第3者からのプルリクレビュー時には上記応用例のワークフローを実行することを目的としてつくったActionです。
なお、GitHub Actionsのセキュリティに関してはpull_request_target
に関するこちらの記事2もあわせて読んでみると面白いかもしれません。