こんにちは!ラクスル事業本部でエンジニアをやっています、灰原です!
皆さんは普段の開発でGitHubのPersonal Access Token (PAT) を使うことはありますか?
ラクスルではいくつかの社内パッケージをGitHub Packagesで管理しており、それらのインストールのためにPATが使われています。
例えばRubyのgemであればbundle config
コマンドでPATを指定したり、npmパッケージであれば.npmrc
ファイルにPATを書いたりします。この対応自体はGitHub Packagesのドキュメントにも書かれているものですが、言わずもがなPATの扱いには注意が必要です。不必要な権限 (scope) を付与しない、有効期限を設定するなど基本的な対策を取るべきでしょう。
しかしPATの有効期限が切れるたびに、GitHubの画面から適切なscopeと有効期限を指定したPATを再生成して、bundlerやnpmなどそれぞれの設定をやり直すという、この一連の作業はそれなりに面倒なものです。
この記事では、そんな面倒な作業をGitHub CLIとちょっとしたスクリプトで効率化する方法について紹介します。
GitHub CLIでPATを取得
まずはPATの作成作業の効率化です。これには GitHub CLI を使います。コマンドラインからプルリクエストを作ったりラベルを付けたりできて便利なGitHub CLIですが、実はGitHubのPATを取得することもできます。
まずは gh auth login
コマンドで認証情報を獲得します。これを実行するとワンタイムパスワードが表示され、それをブラウザで開いたGitHubの画面に入力すると、認証が完了します。その後、gh auth token
コマンドを実行すると、先の認証時に取得したPATが表示されます。
$ gh auth login # ログイン $ gh auth token # PAT取得
gh auth token
で取得したPATを使って、curlでGitHub APIにアクセスしてみます。
$ curl --request GET \ --url "https://api.github.com/octocat" \ --header "Authorization: Bearer $(gh auth token)"
無事にOctocatが表示されました。
(上記の例では検証のためにcurlを使っていますが、GitHub CLIにはGitHub APIにアクセスする機能があります。)
追加のscopeを設定する
ところでGitHubのPATはscopeが設定されています。
gh auth status
コマンドを使えば、GitHub CLIが提供するPATのscopeを確認することができます。
単にgh auth login
した後の状態のscopeは、admin:public_key
/ gist
/ read:org
/ repo
となっていました。
しかしGitHub Packagesからパッケージをインストールする際には、read:packages
scopeが必要です。
このような追加のscopeを設定するには、gh auth login
コマンドの -s
( --scopes
) オプションを使います。
例えば下記のように、read:packages
scopeを追加で要求することができます。
$ gh auth login -s 'read:packages'
gh auth status
コマンドで確認してみると、確かに read:packages
scopeが追加されていることがわかります。
これでGitHub Packagesも扱えるようになりました。
envsubstで設定ファイルにPATを埋め込む
envsubst
というコマンドを使うと、テンプレートエンジンのように環境変数をテキストに埋め込むことができます。
In normal operation mode, standard input is copied to standard output, with references to environment variables of the form $VARIABLE or ${VARIABLE} being replaced with the corresponding values.
envsubst Invocation (GNU gettext utilities)
これを使うと、gh auth token
で生成したPATを簡単に設定ファイルに埋め込むことができます。
例えば、.npmrc.template
として以下のようなファイルを用意しておきます。
@NAMESPACE:registry=https://npm.pkg.github.com //npm.pkg.github.com/:_authToken=${GH_TOKEN}
そのうえで、次のワンライナーを実行すると、PATを含んだ .npmrc
ファイルが生成されます。
$ cat .npmrc.template | GH_TOKEN=$(gh auth token) envsubst > .npmrc
このようなテンプレートファイルと、envsubst
を実行するMakefileなどをレポジトリごとに用意するのも1つのアプローチでしょう。
シェル起動時にまとめて設定する
もう1つのアプローチとして、bundlerの設定したり、ホームディレクトリ直下に.npmrc
を置いたりするシェルスクリプトを作り、それをシェル起動時に読み込ませる方法もあります。
例えば以下のようのシェルスクリプトです。
#!/bin/bash set -eu function login() { if gh auth status; [ $? -ne 0 ] ; then gh auth login -s 'read:packages' fi } function substitute() { token=$1 template=$2 file=$(echo ${template} | sed -e "s/\.template$//") cat ${template} | GH_TOKEN=${token} envsubst > ${file} echo substitute: ${file} } function main() { login token=$(gh auth token) # bundle bundle config --global https://rubygems.pkg.github.com/raksul w-haibara:$(gh auth token) # npm substitute ${token} ~/.npmrc.template } main
おわりに
GitHub CLIを使ってPATを生成し、それを各種設定ファイルに埋め込む方法を紹介しました。 小さなところから日常の手間を減らしていきたいものですね。