このブログのビルドをGitHub Actionsで行っていますが、 その中でGistにアクセスしてコードを取得して表示する作業があり、 それが回数制限に引っかかることが多くなったのでそれを回避した話。
- REST APIへのアクセス制限
- GitHub ActionsのGITHUB_TOKENの権限
- トークンを作成してレポジトリに登録
- トークンを使ってGistへアクセス
- 以前やっていたこと
- リミットにかかる理由がよくわからない
REST APIへのアクセス制限
Gistなどを取得するためにREST APIにアクセスを行いますが、 トークンなしだと1時間に60回までに制限されています。
GitHubのアカウントを使ってTOKENを作れば通常ユーザーであれば1時間あたり5000回までのアクセスが可能になります。
また、GitHub Actionsでは、実行時に${{ secret.GITHUB_TOKEN }}
という値でトークンが自動で生成されますが、このトークンは
1つのレポジトリに付き1000回のアクセス制限になっています。
GitHub ActionsのGITHUB_TOKENの権限
GitHub Actionsの中で自動で作られるGITHUB_TOKENは下のGITHUB_TOKENのアクセス許可の表にある権限を持っています。
実行中のレポジトリへの読み書きの権限などを持っていますが、 Gistへのアクセス権限は持っていません。
無理やりこのGITHUB_TOKENを使ってGistへアクセスしようとすると
Resource not accessible by integration
なエラーが出ます。
トークンを作成してレポジトリに登録
というわけで別途作ってレポジトリのActions secretsに登録します。
作成は
Personal Access Tokens (Classic)
から(SettingsDeveloper settingsPersonal access tokensTokens (classic))。
新しいFine-grained tokens (Beta)というものができていて、こちらだと権限を与えるレポジトリを選択することが出来るようになってたりしますが、 今回はPublicなGistへのアクセスだけなのでclassicな方で作ります。
PublicなGistへのアクセスだけであればSelect scopesで何も選択しないで作成すればOKです。
作ったトークンを、GitHub Actionsを行うレポジトリのSettingsSecrets and variablesActionsへ行き、SecretsでNew Repository secretから登録します。
名前はGIST_GITHUB_TOKEN
とかなんとか。
ちなみにGITHUB_XXX
のようにGITHUB_
から始まる名前は使えないらしく、登録しようとすると、
Failed to add secret. Secret names must not start with GITHUB_.
とエラーが出ます。
トークンを使ってGistへアクセス
Gistを取得するのは以下のプラグインを使っています。
オリジナルのものを色々と調整したもの。
以下の部分で、{Authorization: Bearer <TOKEN>}
なヘッダー情報を渡しています。
https://github.com/rcmdnk/octogray/blob/40030ff3c5d7f1e9c13413a208b7b30a40cfb68c/plugins/gist_tag.rb#L134
GITHUB_TOKEN
という環境変数があればそれを使うようにしているため、
GitHub Actionsでビルドを行うstepに対して上のGIST_GITHUB_TOKEN
をGITHUB_TOKEN
というevnで渡してあげればOKです。
Octopressのビルドはrcmdnk/octopress-action というアクションで行っているので、
1 2 3 4 5 |
|
こんな感じのstepを作ってあげればOK。
以前やっていたこと
以前、これとは別にOAuth Appsを作ってclient_id/client_secretを使った認証でlimitを回避していて、 その設定も上のgist_tag.rbで出来るようになっています。
まだローカル環境でビルドを行っていた頃で、何度も手でビルドを行っているうちにリクエスト制限にかかってしまった事があり、 それが他の作業にも影響してしまうので入れてました。
その後、クラウド上でビルドするようになってからはそこまで連続で全ビルドすることはなくなったので特に設定してなかったようです。
今回もAppsを使っても良かったんですが、より簡単に出来る方法としてトークンを使うようにしました。
リミットにかかる理由がよくわからない
1時間に60回の制限ですが、実際には毎日ビルドを行っている中でほとんどのビルドは成功していて最近までは特にこの制限にかかることはありませんでした。
たまに続けてアップデートを繰り返して明らかに制限を超えてしまうことはありましたが、 少なくとも1回のビルドでは30個位のGistへのアクセスしかありません。
ここ2週間ほどでこのエラーが出るようになり、結構続いたので一旦Gistでなくても良いものは直接書いてしまうようにして、 Gistのexample的な感じで載せたものとか一部だけ、数個だけ残した形になりました。
が、それでも数日に1回失敗する感じになっています。
ジョブが始まった時点で60回を使い切ってしまっているようです。
たまたま他の人のジョブが前に同じIPのインスタンスで動いていて使い切ってしまった、とか?
いずれにしろ60回/時、という数をかならず使える状態ではなくなってしまったので 少しでも使う場合にはトークンとかを用意する必要がある状態になってしまっています。