内部で GitHub API を用いる GitHub Actions を、 github.com と GitHub Enterprise の両方に対応させる
Created: 2021-03-17
Series: label_timer
- 2021-03-17 内部で GitHub API を用いる GitHub Actions を、 github.com と GitHub Enterprise の両方に対応させる
- 2021-03-11 Issue, Pull Request のリードタイムを計測できる GitHub Action「Label timer」をリリースした
この記事は Label timer を開発したことで得られた知見。
GitHub Enterprise と github.com で異なる API エンドポイント
例えば GitHub API の https://api.github.com/foo に相当するものが GitHub Enterprise では https://[独自ドメイン]/api/v3/foo となるので、同一の Action を両者間で使いまわそうと思うと多少の工夫が必要だ。個人や社内で使う目的ならエンドポイントを固定してしまうのも良いだろうが、OSS として考えれば両方で使えたほうが嬉しいはずだ。
共通化させる方法
おそらくいろいろなやり方があると思う。パッと思いついたものとしては、エンドポイントを .github/workflows/foo.yml の中で記す方法などが考えられる。action.yml と .github/workflows/foo.yml の記述は以下のように。
inputs:
api_endpoint:
description: If you use GitHub Enterprise, specify the endpoint.
# GitHub を使う場合には指定する必要がないように
default: https://api.github.com/
jobs:
foo::
runs-on: ubuntu-latest
steps:
- name: test_run
uses: foo/bar@1
id: test_run
with:
api_endpoint: https://[your_domain]/api/v3/
さて、今回 Issue_timer を作るにあたっては GITHUB_EVENT_PATH
を用いてワークフローをトリガするイベントを取得し、その中に記載のある API エンドポイントにアクセスする方法を採用した。この方法だと workflows/foo.yml でエントリーポイントを指定する必要もない。
ワークフローをトリガーするイベント - GitHub Docs
Actions のスクリプト中では GITHUB_EVENT_PATH
を用いて上記ドキュメント中の ${{ github.event }}
に相当する内容の json ファイルを取得することができる。たとえば Python なら以下のように。Pull Request にラベルが付いたことをトリガとするものであれば、 action
には labeled
が代入される。
with open(environ.get('GITHUB_EVENT_PATH')) as f:
events = json.load(f)
action = events['action']
この events
には API エンドポイントや各種 URL も含まれている。例として Pull Request に対する何らかのアクションがトリガであれば以下のようなコードでトリガとなった Pull Request の URL や Pull Request のコメントを操作する API エンドポイントを取得できる。
url = events['pull_request']['_links']['html']['href']
api_url = events['pull_request']['_links']['comments']['href']
今回は github.com の Marketplace で公開することをを目標にしつつ社内の GitHub Enterprise でも使えることを考えていたので、このような工夫が必要だった。単に Marketplace に公開する場合にはそのような配慮は必要ないかもしれないが、少しの工夫で多くの人が使えるようになれば、その方が面白いと思う。