MakeとGitHub CLIで初回Pushまでを最速に。ISUCONハック前編

みなさん、GitHub CLIは使っていますか?私は普段の業務で長く使っています。

そろそろ本番を迎えるISUCONという競技においても

これは非常に使えるんじゃないか?🤔

と感じたので、その使い方をISUCON13個人スポンサーのyamachuが紹介していこうと思います!

GitHub CLIを使ったISUCONの初動スピードアップ方法

ISUCONに出場している多くのチームが、ISUCONのコード管理にGitHubを使用していると思います。 GitHubにはIssue機能があり、またPullRequest機能があり、わかりやすいWebUIがあります。

GitHubの運用方法も様々あります。 私が参加した時は、IssueやPullRequestで以下の内容を管理していました。

  • Issue: 次なる一手を打つ判断に使うログデータ
  • PullRequest: 考えた施策

そう、例えばこんな感じです。

https://github.com/yamachu/isucon12-qualify/issues

スピードアップに関係ない作業を削りたい

私は1人で参加しているため、スコア改善に寄与しない作業を競技時間から極限まで取り除く必要 があります。一人だと小さい時間の積み重ねの影響が大きく、これを改善しないことには時間が足りないという悩みがありました。

  1. 競技開始時に実施するGit / GitHub連携用のワークフローを作るのが面倒...
  2. 競技中の長いログのIssue転記が手間...

例えば

- 必要なコードをGit管理し、GitHubにPushするまでのフローに手間取ってしまったり…
- Pushに必要な秘密鍵を作ってGitHubに登録したり、scpでサーバに持っていったり..
- 作業ログを残すために長いログをコピペしてIssueに転記したり...
- そのために画面行ったり来たり...
- 長いからターミナルの文字を小さくしてみたり...

そういう作業はわずか8時間しかない競技時間から削りたいですよね。 その悩みをMakefileとGitHub CLIが解決してくれました。

今回は前編、後編に分けて紹介します。

  1. 初回Pushを楽にするためにMakefileで自動化
  2. ログをGitHub CLIを利用して、CLIのパイプからIssue コメントに流し込む方法

GitHub CLIを使った運用改善

では、GitHub CLIを利用してみましょう。手順は以下で進めます。

  • GitHub CLIのインストール
  • gh auth loginによるログインとSSH鍵の生成
  • 権限管理にFine-grained personal access tokenを使う

GitHub CLI とは

GitHub CLIはGitHub上で行える操作をCLI上から行えるアプリケーションです。

https://docs.github.com/ja/github-cli/github-cli/about-github-cli

PullRequestやIssueの作成や編集、またGitHub APIのクライアント機能を有しています。 この記事では、仕事でもISUCONでも使えそうな機能に絞って紹介していきます。

まずはGitHub CLIのインストール

ISUCONの競技を行うマシンはだいたいUbuntuになると思うので、それに適したインストール方法を使用します。

https://github.com/cli/cli/blob/trunk/docs/install_linux.md#official-sources

GitHub CLIのソースコードをホストしているリポジトリにインストール方法が書かれているので、競技が始まったらそれに適したものを見つけてコピペしてインストールを行います。 私はこれを秘伝のMakefileに書いておいて、いつでもインストールできるようにしています。

Makefileのサンプルはこちら https://gist.github.com/yamachu/d65ca3ddb277633d0e2e92f511a3f589#file-makefile

GitHub CLIでログイン & token権限を丁寧に

さてインストールが済んだので、早速使ってみましょう。 GitHub CLIを使用するには、まずはGitHubの認証情報を使用してGitHub CLIの設定をする必要があります。

例えば以下のようなコマンドでログインを行うことが出来ます。

$ gh auth login

このコマンドを実行すると、認証のためのURLが表示され、そこで認証のコードを入力するとGitHub CLIの設定が完了します。 加えて、この設定フロー中に、SSH鍵の生成やアカウントへの追加なども行うことが出来ます。

以前はopensslコマンドを使ってSSH鍵を生成し、GitHubに登録していました。

現在は、通常業務や個人開発の中では gh auth login 時に生成されるSSH鍵をGitHubに登録しています。

その際、いつでもrevokeしやすいように、鍵の名前などはどのマシンに存在するかわかるような名前にしています。

権限管理にFine-grained personal access tokenを使う

さて、ここで

通常業務や個人開発の中では

と書きました。

普段の業務であれば上記の方法で認証し、SSHの鍵の生成や追加までを行います。

しかし、忘れていけないのはISUCONはチーム競技です。

同じインスタンスにチームメンバーがログインすることになり、誰かのフルアクセスな認証状態で作業を行うことになります。

IT企業に務めているエンジニアとして、権限周りには常に気を遣っておきたいです。 信頼の出来るメンバーでチームを構成しているでしょうから、何も起きないと信じたいですが...

GitHub CLIは自分の認証状態で色んなことが出来てしまいます。 例えば

  • 自分の所属しているOrganizationを調べる
  • リポジトリを列挙する

そんなことが出来る状態にGitHub CLIをしておきたくないので、ISUCONの競技を行う上では、 Fine-grained personal access token を使用した認証を行うことをおすすめします。

https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#fine-grained-personal-access-token-1

Fine-grained personal access token は有効期限の定められた、また権限を自分で細かく調整したトークンです。

例えば、特定のリポジトリのファイルの書き込み権限やIssueの作成権限だけを与え、他のリポジトリにはアクセス出来ない、みたいなことが出来ます。 これで安心してGitHub CLIを使えますね。

単一リポジトリなら Deploy Keysで良いのでは?

ここで単一リポジトリへの書き込み権限の付与だけを目的としていた場合、GitHub CLIを使わずに、Gitクライアント + Deploy Keysで事足りるのではと疑問を持つかと思います。 確かにリポジトリへの書き込み権限のみに着目すれば、Deploy Keysは最も容易で、かつシンプルな解決策と言えるでしょう。

今回はリポジトリへの書き込みに留まらない、コマンドライン上からのIssue管理も行いたいため、GitHub CLI + Fine-grained personal access tokenによる認証を採用しています。

first pushに向けたGitHubとGitHub CLIの設定

それでは、これからの作業の流れを簡単に触れていきます。

  1. 事前にコードを管理するリポジトリをGitHub上に作成し、チームメンバーを追加する
  2. Fine-grained personal access tokenを必要な権限でリポジトリに紐付ける
  3. 当日は、用意したTokenを使用してGitHub CLIの設定を行う
  4. GitHub CLIを認証ヘルパとして使用するように設定する
  5. Gitのユーザ名とメールアドレスを設定する

この流れで作業を進めていきましょう。

チームメンバーの追加

まずはコードを管理するリポジトリをGitHub上に作成し、チームメンバーを追加していきましょう。 前日までに終わらせて、当日はここで管理しようとチームで連携が取れているといいですね。

Fine-grained personal access tokenをリポジトリに紐付ける

次は、用意したリポジトリに対してアクセスするためのFine-grained personal access token生成です。

https://github.com/settings/tokens?type=beta

このURLから新たなTokenを生成します。

今回は特定のリポジトリに対して

  • リポジトリのコードへの書き込み権限
  • Issueの作成権限
  • Pull Requestの作成権限

の権限を与えたいため、以下のような設定を行いました。

権限付与対象のリポジトリを選択
付与した権限の一覧

先程作成したリポジトリを Repository access > Only select repositories で指定しておきましょう。

GitHub CLIの設定

ではこのTokenを使用して、GitHub CLIの設定を行います。

$ gh auth login --with-token -p https
# ここで入力待ちになるので、ここでTokenをペーストし、ReturnKeyを押してから、Ctrl+Dで入力を終了する

以上のフローを踏んだ後に

$ gh auth status

とすると

github.com
  ✓ Logged in to github.com as yamachu (/home/ubuntu/.config/gh/hosts.yml)
  ✓ Git operations for github.com configured to use https protocol.
  ✓ Token: github_pat_11AAO5LII0tb6Io0YDrboT_***********************************************************

こんな感じで、 誰のTokenで認証を行ったか、どのようなプロトコルでGit操作を行うか、またTokenの一部の値が表示されます。

これが表示されたらGitHub CLIの設定は完了です。

GitHub CLIを認証ヘルパとして使用するように設定する

さて、Pushを行うにはまだやることがあります。

ssh鍵を作らずにGitHub CLIを利用するだけでPushする方法もあります。 ここでは、その設定を済ませてしまいましょう。

普段であればみなさんはここでSSH鍵の生成や設定を行っているでしょうが、今回は違います。

$ gh auth setup-git

このコマンドを使用し、GitHub CLIを認証ヘルパとして使用するように設定します。 そうすることで、httpsプロトコルでの git push などは、GitHub CLIが使用している認証情報を使用して行われるようになります。

そして最後に、Git管理されたリポジトリでcommit出来るようにユーザ名やメールアドレスを設定します。

$ git config --global user.email ここにメールアドレス
$ git config --global user.name ここに名前

さて、これで GitHub CLIとGitクライアントの設定が完了しました!

インスタンス上のアプリケーションコードを追加したり、ミドルウェアの設定ファイルを追加してPushしてみましょう。

ここで注意が必要なのは、remoteに設定するのは「https」プロトコルでのURLになります。

$ git remote add origin https://github.com/yamachu/gh-cli-de-isucon11q-practice.git

こんな感じのものになります。 さて、ここまでで初動 Pushのための準備が終わりました。

一度まとめておきましょう。

  1. 事前にコードを管理するリポジトリをGitHub上に作成し、チームメンバーを追加する
  2. Fine-grained personal access tokenを必要な権限で、1. で作成したリポジトリに対して作成する
  3. 当日はそのTokenを使用してGitHub CLIの設定を行う
  4. GitHub CLIを認証ヘルパとして使用するように設定する
  5. Gitのユーザ名とメールアドレスを設定する

これらが終わったら、あとは普段通りにコードを管理していくことが出来ます。

では、前編はここまで! 後編では「ログをGitHub CLIを利用して、ShellのパイプからIssue コメントに流し込む方法」について話します。

以上