tbsmcd.net index, archives, tags, search, profile

内部で GitHub API を用いる GitHub Actions を、 github.com と GitHub Enterprise の両方に対応させる

2021-03-17 01:12:39 +0900 JST

Series: 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 に公開する場合にはそのような配慮は必要ないかもしれないが、少しの工夫で多くの人が使えるようになれば、その方が面白いと思う。

Tags: GitHub Actions