GitHub CLI を導入して Web 画面をポチポチせずに GitHub を使いこなす方法

## 概要
GitHub の操作をコマンドで効率的にしたいため、GitHub CLI を導入することにしたので、その時の備忘録（具体的に使いこなす方法は、後でまとめられたら追記するかも。取り急ぎ導入方法をメインに記載）

- [公式 Web ページ](https://cli.github.com/)
- [公式 ドキュメント内での補足](https://docs.github.com/ja/github-cli/github-cli/about-github-cli)（日本語）
- [GitHub リポジトリ](https://github.com/cli/cli)
- [GitHub CLI マニュアル](https://cli.github.com/manual/)（現状、英語版のみ）

## GitHub CLI とは
- コマンドライン（CLI）上で GitHub の操作を行える公式ツール
- インストールすると、**gh コマンド** が使えるようになる
- GitHub の Web サイトを開いて〜、プロジェクト作って〜、プルリクエスト作って〜…というのをすべてコマンドで出来る
- つまり、GitHub の操作をコード化（＝自動化）することも出来る！
- 既に公式に用意された便利なコマンドもある
  - 例えば、**「SSH キーの生成から、公開鍵の登録まで」** を **コマンドだけでサクッと出来る**（とっても楽！）
  - ただし、マシンに鍵がない場合のみ生成できるようなので、既に別の鍵がある場合は、新たに自分で別途生成し、それを選択するというフローになる

![GitHub CLI_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787582/13d24c21-37e3-01d9-2c1e-9f483ad161e0.png)

### 以下に楽かがわかるサンプル
初期設定が完了し、ログインも完了し、権限も問題がない場合、**「リポジトリの新規作成」** は以下のコマンド一発で完了する
```bash
gh repo create demo-repo --private --add-readme -c
```
👆これは **「Webサイトにログイン → 新規リポジトリ作成をクリック → リポジトリ名（demo-repo 部分）を入力 → プライベートにチェックをいれる ＋ README.md 付きにチェックをいれる → 作成が終わったらローカルマシンにクローンをする」** という一連の作業を、**コマンド１行** で終わらせることができる。
尚、これは個人リポジトリに限らず、**組織アカウントへのリポジトリ作成も実行可能** なのが素晴らしい（リポジトリ名の前に、所有者＝ `組織名/` を付与するだけ）。

## 導入手順
### インストール
各 OS のインストール方法と、ついでにアップグレードする方法を一部抜粋（詳細は GitHub リポジトリに記載されている）

macOS は Homebrew で、Windows は WinGet を利用する方法を紹介

|OS|インストール|アップグレード|
|---|---|---|
|macOS|`brew install gh`|`brew upgrade gh`|
|Windows|`winget install --id GitHub.cli`|`winget upgrade --id GitHub.cli`|

※ インストールに数分かかります

インストールすると、`gh` コマンドが利用可能となる
尚、GitHub CLI の公式リリースページからバイナリを直接ダウンロードすることもできる

#### インストール確認
バージョン確認コマンドを使って、入っているかを確認する
```bash
# バージョン確認コマンド
$ gh --version

# 実行結果
gh version 2.61.0 (2024-11-06)
https://github.com/cli/cli/releases/tag/v2.61.0
```

バージョンが表示されればインストール成功

### 認証する
インストールが完了したら、GitHub アカウントの認証をする
```bash
gh auth login
```

認証コマンド初回実行後の動きは以下の通り
```bash
# Q. GitHub をどこで使ってるか？
? Where do you use GitHub?  [Use arrows to move, type to filter]
> GitHub.com
  Other
  # 👉 公式サイトなら、そのままエンターキーで OK

# このマシンで Git 操作をする場合の優先する接続方式は、HTTPS なの？SSH なの？
? What is your preferred protocol for Git operations on this host?  [Use arrows to move, type to filter]
  HTTPS
> SSH
  # 👉 SSH キー（公開鍵）を利用する/してる なら、SSH を選択

# マシンに SSH キーが未作成の場合のみ、ここで新規作成をするか聞かれる

# 既に SSH の公開鍵がある場合、どれを GitHub にアップロードするの？
? Upload your SSH public key to your GitHub account?  [Use arrows to move, type to filter]
> /Users/ユーザ名/.ssh/id_rsa_sample_1.pub
  /Users/ユーザ名/.ssh/id_rsa_sample_2.pub
  /Users/ユーザ名/.ssh/id_rsa_sample_3.pub
  Skip
  # 👉 公開鍵だけ用意したけど、まだ GitHub に設定していない場合のみ選択
  # 👉 未作成 ot もう GitHub への設定は終わってる場合は "Skip"

# どうやってこの CLI を認証するの？
? How would you like to authenticate GitHub CLI?  [Use arrows to move, type to filter]
> Login with a web browser
  Paste an authentication token
  # 👉 "Login with a web browser" ＝ Web 画面を起動して認証を済ませる

# 上記を選択すると、ワンタイムパスワードが発行されるので、URL にアクセスして使用する（エンターキーを押すと、自動でブラウザが立ち上がる）
! First copy your one-time code: {ワンタイムパスワード}
Press Enter to open https://github.com/login/device in your browser... 
  # 👉 ブラウザで対象ユーザを選択し、ワンタイムパスワードを入力して進める
  # 👉 "Congratulations, you're all set!" と表示されたら完了。ブラウザを閉じても良い

# 完了すると、以下の表示が出て認証処理が終了
✓ Authentication complete.
- gh config set -h github.com git_protocol ssh
✓ Configured git protocol
✓ Logged in as {GitHub ユーザ名}
```

これで、認証した GitHub アカウントで gh コマンドが利用できるようになった

## アカウント操作
複数の GitHub アカウントを持っている場合、それらを確認・切り替えることができる

`gh` で認証したアカウント一覧と、現在のアクティブを確認
```bash
アカウント確認
$ gh auth status

# 実行結果
github.com
  ✓ Logged in to github.com account {ユーザ名} (keyring)
  - Active account: true  # 👉 true なら現在アクティブ
  - Git operations protocol: ssh
  - Token: gho_************************************
  - Token scopes: 'gist', 'read:org', 'repo'
```

アクティブなアカウントを切り替えたい場合
```bash
# アカウント切り替え（コマンド実行後、対象を選択）
$ gh auth switch

# または、ユーザ指定して切り替え
$ gh auth switch --user ユーザ名
```

`gh` で認証したアカウント一覧から外す（ログアウトする）
```bash
# ログアウト（コマンド実行後、対象を選択）
$ gh auth logout

# または、ユーザ指定して即ログアウト
$ gh auth logout --user ユーザ名
```

アカウントを新たに追加したい場合、また `gh auth login` を実行すれば良い

## リポジトリ操作

リポジトリ一覧を見る
```bash
# 一覧表示
$ gh repo list

# 実行結果（例）
NAME            DESCRIPTION   INFO     UPDATED            
to3izo/repo-1                 private  about 10 months ago
to3izo/repo-2                 private  about 1 year ago
to3izo/repo-3                 public   about 3 years ago
```
**NAME** に表示されたリポジトリ名は、各種リポジトリ操作の指定に利用できる

```bash
# リポジトリのクローン
$ gh repo clone リポジトリ名

# リポジトリのフォーク
$ gh repo fork リポジトリ名

# リポジトリ内容の閲覧
$ gh repo view リポジトリ名
```
※ ただ、クローンだけは普通の `git clone` で済ませても良いかもしれない

リポジトリの新規作成もコマンドでできる
```bash
gh repo create
```

## プルリクエスト（PR）操作
プルリク（PR）を操作するコマンドが用意されている

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

**※ 対象のリポジトリがある場所で、コマンドを実行する**

プルリクエスト一覧を取得
```bash
# 一覧表示
gh pr list

# 実行結果
Showing 1 of 1 open pull request in to3izo/repo-1

ID  TITLE     BRANCH     CREATED AT
#1  Title A   branch_a   about 3 hours ago
#2  Title B   branch_b   about 18 hours ago
#3  Title C   branch_c   about 2 days ago
```
**ID** に表示された ID は、各種プルリク操作の指定に利用できる（数値だけで良い。シャープは不要）

```bash
# プルリクエスト内容の確認
$ gh pr view プルリクID

# 実際のコマンド例（#3 のプルリクエストを表示）
$ gh pr view 3
```

## その他、便利そうなコマンド

|内容|コマンド|
|---|---|
|[Issue 一覧取得](https://cli.github.com/manual/gh_issue_view)|`gh issue view`|
|[ワークフローの実行](https://cli.github.com/manual/gh_workflow_run)|`gh workflow run`|
|[最新のリリース確認](https://cli.github.com/manual/gh_release_view)|`gh release view`|

## よくある手順
例）既にいくつかあるアカウントでログインしている状態で、特定の組織アカウントにリポジトリを作成するフロー

```bash
# ログイン確認
gh auth status

# ログインアカウントの切り替え
gh auth switch --user ユーザ名

# ログインしてなければログイン
gh auth login

# 所属する組織アカウントを確認
gh org list

# 組織アカウントのリポジトリを作成
# "demo-repo" をプライベートで組織 "OrgName" に作成、README.md 追加、同時にクローンもする
gh repo create OrgName/demo-repo --private --add-readme -c
```
最後のコマンドは `-d` オプションで概要も追加できる。組織を指定しなければ個人リポジトリが対象となる。

## まとめ
- Web 画面でポチポチやっていた GitHub 操作をコマンドで完結することができる
- コード化できるため、自動化も可能（公式でも既に便利な機能が提供されている）
- 非常に便利だが、扱うかどうかや、使い方等は慎重に決めたほうが良さそう
- Web 画面の手動操作であえて状況を把握しながらやっているような場合は、コマンドで一括実行が怖いシーンもあると思う
- 認証周りを簡潔に設定可能だが、内部的に何が行われているかを確認し、作業現場の運用上やセキュリティ上のルールに抵触しないかを把握する必要がある
- 個人の環境であればまだ問題ないかもしれないが、ビジネス上の顧客から提供された環境などでの利用は、ちゃんと先方との認識を合わせて、確認・合意が必要となる