GitHub の CLI コマンドである gh コマンドのソースコードリーディングをして、 bug の issue を立てた

2022/12/04に公開

概要

  • GitHub を操作する CLI コマンドである gh コマンドのリポジトリに issue を立てた
  • めちゃめちゃ細かいところなので、動作に問題はほとんどない
  • 修正方針が2通りあり、どちらにするかを決められないので PR 作成まではできていない
  • 発生の仕方が面白かったのでみんなに共有したい

背景知識

gh コマンド

gh という CLI コマンドがある。 GitHub の web GUI 上でできる操作を CLI で完結できてかなり便利だ。

codespace

GitHub には codespace という機能がある。 だいたい仮想環境上で動いて、webから操作できる、 repository を開いた状態の VSCode だと思ってもらえればいい。 Web や gh コマンドから作成・削除ができる。

organization

GitHub は個人だけではなく、団体(organization)として名前空間を作成することができる。

gh コマンドの不思議な挙動

ある日のこと。gh コマンドを用いて、 myOrganzation の中の codespace を全て削除しようとしていた。
gh codespace delete --org myOrganization --all

すると以下のような内容が表示された。

Deleting codespaces ⣽
error deleting codespace "xxxxxxxxxxxxxxx": HTTP 404: Not Found (h ttps://api.github.com/user/codespaces/hogeSpace)
error deleting codespace "yyyyyyyyyyyyy": HTTP 404: Not Found (ht tps://api.github.com/user/codespaces/fugaSpace)
error deleting codespace "yyyyyyyyyyyyy": HTTP 404: Not Found (ht tps://api.github.com/user/codespaces/piyoSpace)
.....

大量の 404 エラー。 organization がないわけではなくて、 codespace がないっぽい???どういうことだろう。

ソースコードを読んでみる

gh codespace delete コマンド

gh codespace delete コマンドの実装を読んでみると、このコマンドは次の2フェーズの処理をしていることに気づいた。

  1. 削除すべき codespace の一覧を取得してくる
  2. 上の codespace を一つ一つ削除する

そこで取得フェーズと削除フェーズの実装を追うことにした。

一覧取得フェーズ

ユーザーネームを指定していない場合、ネット越しに API の /orgs/MyOrganization/codespaces を叩きにいく。

この API endpoint の docs によると、この API は organization に紐づく codespace を全て返すらしい。

削除フェーズ

ユーザーネームを指定していない場合、 API の /user/codespaces/hogeCodespaceDELETE メソッドで叩く。

この API の endpoint の docs によると、現在認証されている(ログインしている)ユーザー の codespace を 削除する API らしい。

結論

つまり、 gh codespace delete コマンドは、 organizations 内の全ての codespaces を取得しているのに、それを今ログインしているユーザーの codespace を消す窓口から消しにいくのだ。したがって、ログインユーザー以外の持ち物の codespace を削除しようとしたタイミングで 404 が帰ってくる。

うわ~~~~こういう微妙なAPIの仕様のズレから生まれる微妙な不具合...

対応

issue を立てた。
治し方は、本来の挙動をどちらとみるかによって以下の2通りがあると思う。

  1. gh codespace delete --org myOrganization --all サブコマンドは、myOrganization内のログインユーザーの持っている codespace を削除するコマンドである。
  • 現状は、余計なことをしようとして、余計な処理だけが必ず失敗して、終了コードと表示だけがおかしくなる軽微なバグだ。
  • 治すためにはcodespace 一覧取得フェーズをログインユーザーの持っている codespace に限って取得するように修正する。
  1. gh coddespace delete --org myOrganization --all サブコマンドは、myOrganization内の文字通り全ての codespace を削除するコマンドである。
  • 現状は、必要なことをしようとして、しかし完遂しきれない比較的軽微でないバグだ。
  • 直すためには、 codespace 削除フェーズをログインユーザーによらずcodespaceを削除する API を用いるように修正する。

どちらの挙動を正とするかは私には決められなかったので、2通りの方針があるよという提案だけして後はメンテナたちに任せることにした。

まとめ・感想

微妙な不具合を見つけた。ソースコードリーディングをしたら発生メカニズムまで判明したので、面白いと思って共有した。
脱線だが gh コマンドはかなり便利なので使ってない人は試してみるとよいと思う。便利なコマンドを提供してくれている gh コマンドのメンテナたちに感謝!

GitHubで編集を提案

Discussion