GitHub CLI を使って private repository から一つのファイルをダウンロードする
gh auth login
を実行して、gh
コマンドに認証情報を保存した状態にして
gh api \
-H "Accept: application/vnd.github.raw" \
/repos/OWNER/REPO/contents/PATH > OUTPUT_FILE
のコマンドを実行すると、https://github.com/OWNER/REPO/PATH
のファイルがOUTPUT_FILE
に保存されます。
この方法のメリットはgh
コマンドの認証情報を使うので、Personal Access Tokenを使う必要が無いことです。
詳細
コマンドラインで GitHub から一つのファイルをダウンロードしたい場合、 GitHub REST API を使って取得する方法があります。
この API へのリクエストでAccept
ヘッダーにapplication/vnd.github.raw
を追加することで、ファイルの内容を Raw 形式で取得できます。(Media types)
標準出力の結果をOUTPUT_FILE
にリダイレクトすることで、 GitHub 上のリポジトリから一つのファイルをダウンロード出来ます。
API へのアクセス
その API の叩くやり方として、 Personal Access Token を使って curl や wget で取得するやり方があります。
これは Personal Access Token をAuthorization
ヘッダーに対してBearer <YOUR-TOKEN>
のように追加します。
curl \
-H "Accept: application/vnd.github.raw" \
-H "Authorization: Bearer <YOUR-TOKEN>"\
https://api.github.com/repos/OWNER/REPO/contents/PATH
これの問題は Personal Access Token を使用していることです。
以前はこの方法は正しいやり方でしたが、gh
コマンドが整備された今では GitHub CLI または Git Credential Manager を使用が推奨されています。
警告: アクセス トークンは、パスワードと同様の扱いとしてください。
コマンド ラインから GitHub にアクセスするには、personal access tokenを作成する代わりに GitHub CLI または Git Credential Manager を使用することを検討してください。
GitHub CLI を使用する場合、api
というサブコマンドを使うことでも同様のことができます。
このコマンドは以下の用に使います。
gh api <endpoint> [flags]
Options は様々あるので、詳しくは公式ドキュメントを見てもらいたいのですが、実際自分が使ったものは--header
と--jq
ぐらいです。
このコマンドからリポジトリコンテンツを叩く場合、このようになります。
gh api \
-H "Accept: application/vnd.github.raw" \
/repos/OWNER/REPO/contents/PATH
curl を使用した方法との違いは、認証に Personal Access Token を使用していないことです。
参考
GitHub Actions での利用
GitHub Actions では${{ secrets.GITHUB_TOKEN }}
を使うことで自動トークン認証を行うことができます。
しかし、このトークンが持つアクセス権限( Repository contents の read 権限)は、その GitHub Actions が実行されているリポジトリ内のみ適応されます。そのため、たとえ同じ Organization 内であっても、別のプライベートリポジトリへのアクセスすることは出来ません。
GITHUB_TOKEN で利用できないアクセス許可を必要とするトークンが必要な場合は、 personal access token を作成し、それをリポジトリのシークレットとして設定するやり方を記載しています。
この記事では Personal Access Token を発行せず、プライベートリポジトリへアクセスすることが目的です。
これを達成するために GitHub Apps 経由で token を発行する方法があります。
詳しくは上記の参考記事を読んでもらいたいですが、これを設定すると workflow は以下のようになります。
on:
workflow_dispatch:
jobs:
use_api:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Generate github token
id: generate_token
uses: tibdex/github-app-token@v1
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.PRIVATE_KEY }}
- name: Run GitHub CLI
run: |
gh api repos/octocat/Spoon-Knife/issues
env:
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
これで、自ら Personal Access Token を発行し、管理する事なく、認証情報が必要なリソースへのアクセスが出来るようになります。
ちなみに、この場合は curl を使ってもgh
コマンドを使っても問題ないです。
GitHub REST API のドキュメントの方には、 GitHub CLI / cURL / JavaScript のそれぞれを使用した場合のやり方が書いてあります。
注意事項
今回紹介しているやり方は、ローカルのgh
コマンドを実行する Makefile やシェルスクリプトなどに有効です。
Docker や CI ( GutHub Actions を除く)でのやり方は確認していないので、動作を保証出来ません。
また、「 Personal Access Token を利用する事自体が良くない」と言うような論調で書いてしまいましたが、必要に応じて使うことは全く問題ないです。ただし、ローカルでgh
コマンドが使えるのであれば、あえて Personal Access Token を利用する必要はないと思います。
不慮の事故を防ぐためにも、アクセストークンというものは慎重に取り扱いたいものです。詳しくは参考1を読むと良いかもです。
Discussion