🐙

GitHub CLI + jqで特定タイトルのイシュー番号だけ取得する

2024/08/09に公開1

はじめに

こんにちは、がんがんです。

普段 GitHub CLI + GitHub Actions で良しなに自動化しているのですが、たまに GitHub CLI だけだと痒いところに手が届かないことがあります。
そんな時は GitHub CLI に備わっている-qオプションで jq を利用することができます。

CLI のオプションとして jq コマンドが利用できる点は AWS CLI と似ていますね。AWS CLI と jq については以前下記記事で実験しています。

https://tech-blog.optim.co.jp/entry/2022/08/31/100000

本記事では GitHub CLI と jq の力を存分に使って問題解決していきたいと思います。

ゴール:解決したい課題

今回の要件は以下のとおりです。

  • 達成したい課題:毎日作成している日報イシューを自動でクローズしたい。クローズ対象は前日のイシュー
  • 環境:GitHub Actions で動作させる
  • 利用するツール:GitHub CLI、jq で完結させる

本課題を解決するため順番に実験していきます。

イシュー一覧を取得する

まずはイシュー一覧を取得してみます。GitHub CLI にはlistコマンドが存在しており、こちらで簡単に取得できます。

https://cli.github.com/manual/gh_issue_list

terminal
$ gh issue list

特定タイトルのイシューをイシュー番号だけ取得したい

例えば、タイトルが 2024/08/09 のイシュー番号を取得したいとします。GitHub CLI には-S, --searchオプションが備わっており、こちらを用いることで解決できます。

terminal
$ gh issue list -S '2024/08/09' --json number -q '.[].number'
679

ただ、この場合は類似タイトルだった場合に複数個が取得されます。例えば、2024/08/102024/08/10 TODO がイシューにあった場合は以下のように 2 つ取得されます。困りました。

terminal
$ gh issue list -S '2024/08/10' --json number -q '.[].number'
680
681

特定タイトルのイシューを(タイトル完全一致で取得し)イシュー番号だけ取得したい

-Sオプションだと取得が不十分な結果になりました。そのため、jqコマンド側で絞ります。いい感じです。

terminal
$ gh issue list --json number -q '.[] | select(.title == "2024/08/09") | .number'
679

変数を利用する場合は?

ワークフロー作成おじさんは気づいたはずです。「毎回変わるタイトルはどうやって可変させれば良いのか」

shell / jq 大好き芸人は気づいたはずです。「jq の--arg オプションは利用できるのか」


実際に試してみましたが予想通りダメでした。--argオプションが GitHub CLI に存在していないのでエラーが発生します。

terminal
$ gh issue list --json number,title -q --arg target '2024/08/09' '.[] | select(.title == $target) | .number'
unknown arguments ["target" "2024/08/09" ".[] | select(.title == $target) | .number"]; please quote all values that have spaces

Usage:  gh issue list [flags]

Flags:
      --app string         Filter by GitHub App author
  -a, --assignee string    Filter by assignee--search
  -A, --author string      Filter by author
  -q, --jq expression      Filter JSON output using a jq expression
      --json fields        Output JSON with the specified fields
  -l, --label strings      Filter by label
  -L, --limit int          Maximum number of issues to fetch (default 30)
      --mention string     Filter by mention
  -m, --milestone string   Filter by milestone number or title
  -S, --search query       Search issues with query
  -s, --state string       Filter by state: {open|closed|all} (default "open")
  -t, --template string    Format JSON output using a Go template; see "gh help formatting"
  -w, --web                List issues in the web browser

-qオプションだけだと jq の力を最大限利用することはできなそうですね。大人しくjqを使っていきます。jq 利用する場合は以下のコマンドでいけます。

terminal
$ gh issue list -R 'shinGangan/dairy-report' --json number,title | jq --arg target "2024/08/09" '.[] | select(.title == $target) | .number'
680

特定タイトルのイシューのイシュー番号を取得し、そのイシューをクローズする

では、一番やりたかった「特定イシュー番号を特定しクローズする」というワンライナーを書きます(別にワンライナーである必要はないです。Shell 芸をワンライナーで書けると気持ちいいだけです)。

terminal
number=$(gh issue list --json number,title | jq --arg target "2024/08/05" '.[] | select(.title == $target) | .number') \
&& gh issue close $number -c "期限が切れたのでクローズします"

本項ではクローズしていますが、例えば

  • 特定イシューを紐付けたい
  • 特定イシューに対してコメントを残したい

などの GitHub CLI で行えることは可能となります。また、jq の柔軟性を活かして柔軟な条件分岐が書けるのも良い点です。

参考

https://jqlang.github.io/jq/manual/

https://tech.innovator.jp.net/entry/2024/04/11/145352

おわりに

今回は GitHub CLI と jq を用いて特定イシューの操作を行いました。
jq は非常に柔軟性に優れており、ユーザーがやりたい Shell 芸を補助してくれます。

また本記事では登場していませんが yq という yaml 版 jq も存在しています。
こちらも便利ですので是非触ってみてください。

Discussion

rakiraki

参考程度に別解的な。

gh search issues "2024/08/05" --match title --state open --sort created --order desc -L 1 -R your/repo --json number -q '.[][]'
  • 以前に同じことを考えていた
  • タイトルを完全一致にさせるには記事のようにコマンドの外でマッチさせる必要がある(--match title でタイトルを条件にできるけど記事のように同じ日付タイトルの他のやつもマッチしてしまう)
  • 他の条件(ここでは state や order。個人的にはラベルを追加している)が使えるので、 gh issue list よりも gh search issues のほうが条件を正確に設定できる