【2019年度版】GPGでgitのcommitを署名してGitHubでVerifyバッジを出す

たまに見かける、GitHubのcommitにVerifyなるバッジが出ているアレをやりたかったんですが
適当に検索して出てくる日本語情報だと最新環境でストレートに動作しない事が何点か存在したのでまとめておきます

## 環境
macOS Mojave 10.14.3
GNU bash, バージョン 5.0.2(1)-release (x86_64-apple-darwin18.2.0)
homebrew 2.0.2-10-g605c0e8
Homebrew/homebrew-core (git revision 305be; last commit 2019-02-20)
git version 2.20.1
gpg (GnuPG) 2.2.13

## セットアップ方法
homebrewで以下の要領でGPGをインストール
過去のバージョンではgpg-agentが別パッケージとなっていたのですが、新しいバージョンからはgpgに同梱されるようになったようです

[参考](https://stackoverflow.com/questions/52435650/gpg-agent-not-found-for-homebrew)

```shell
brew install gnupg pinentry-mac
```

これを書いた時点ではバージョン2.2.13がインストールされました

## 署名鍵の生成
以下の要領でコマンドを実行

```shell
gpg --full-generate-key
```

適当にググるとよく

```shell
gpg --gen-key
```
しろという記述が出てくるのですが、これだと鍵長の指定とかが出来ないので--fullで実施することをおすすめします

### 鍵の種類
```shell
$ gpg --full-generate-key
gpg (GnuPG) 2.2.13; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

ご希望の鍵の種類を選択してください:
   (1) RSA と RSA (デフォルト)
   (2) DSA と Elgamal
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
あなたの選択は?
```
1のデフォルトで良いと思います

### 鍵長
```shell
RSA 鍵は 1024 から 4096 ビットの長さで可能です。
鍵長は? (2048)
```
GitHubは4096ビットを推奨しているらしいので、4096とタイプして進みます

### 有効期限
```shell
鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0)
```
これも好きな期限を入れて進みます

### ユーザーIDの構成
```shell
GnuPGはあなたの鍵を識別するためにユーザIDを構成する必要があります。

本名: Taro Yamada
電子メール・アドレス: taro.yamada@example.com
コメント: GitHub
次のユーザIDを選択しました:
    "Taro Yamada (GitHub) <taro.yamada@example.com>"
```
これも見たまんまですが、名前とメールアドレスを入力します
このメールアドレスはgitのコミット時に使用されるメールアドレスと同一で、このメールアドレスがGitHubに登録されてるものじゃないと多分Verifyバッジは貰えないです（未検証）

### パスフレーズ入力
こんな画面が出てきますが、これは見ての通りパスフレーズ入力画面みたいです
慌てず騒がずパスフレーズを入力しましょう
<img width="990" alt="スクリーンショット 2019-02-20 6.43.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/95962/01811fa0-92f3-0705-a627-08d77e834bbd.png">

LANG=Cとかしてから実行したら英語で正しく表示してくれるかもしれません（未検証）

アンダースコアで表現されている部分が入力欄で、キーをタイプしたら*マークが表示されるのでそれで入力はできています
キーボードで<OK>を選択して次に進むとこんな画面になりますが、これは見ての通りパスフレーズを再度入力してくれと言っているようです
慌てず騒がず先程入力したものと同じパスフレーズを入力しましょう
<img width="990" alt="スクリーンショット 2019-02-20 6.46.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/95962/708f0422-4071-33d5-7426-b3b4d667f90a.png">

### 鍵の生成を待つ
```shell
たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か
す、ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生
成器に十分なエントロピーを供給する機会を与えることができます。
```
ガチャガチャして待ちましょう

## GPGの設定のセットアップ
### 雛形の入手
設定ファイルを公開してくれている方がいますので、以下の呪文を唱えて雛形を入手しましょう
[参考](https://gist.github.com/bmhatfield/cc21ec0a3a2df963bffa3c1f884b676b)

```
curl https://gist.githubusercontent.com/bmhatfield/cc21ec0a3a2df963bffa3c1f884b676b/raw/893ab10dc8cd4d6c3cc4ce49bd010a20b54ba4e8/gpg.conf > ~/.gnupg/gpg.conf
curl https://gist.githubusercontent.com/bmhatfield/cc21ec0a3a2df963bffa3c1f884b676b/raw/893ab10dc8cd4d6c3cc4ce49bd010a20b54ba4e8/gpg-agent.conf > ~/.gnupg/gpg-agent.conf
```

### gpg-agent.confの修正
use-standard-socketオプションは現在は無効らしいので
2行目をコメントアウトしておきます

```conf
# Enables GPG to find gpg-agent
use-standard-socket ☆これを消す

# Connects gpg-agent to the OSX keychain via the brew-installed
# pinentry program from GPGtools. This is the OSX 'magic sauce',
# allowing the gpg key's passphrase to be stored in the login
# keychain, enabling automatic key signing.
pinentry-program /usr/local/bin/pinentry-mac
```

### .bash_profileのメンテ
以下のソースを参考にしつつgpg-agentの起動引数が変わってるようなので
https://gist.githubusercontent.com/bmhatfield/cc21ec0a3a2df963bffa3c1f884b676b/raw/893ab10dc8cd4d6c3cc4ce49bd010a20b54ba4e8/.profile

```bash
# In order for gpg to find gpg-agent, gpg-agent must be running, and there must be an env
# variable pointing GPG to the gpg-agent socket. This little script, which must be sourced
# in your shell's init script (ie, .bash_profile, .zshrc, whatever), will either start
# gpg-agent or set up the GPG_AGENT_INFO variable if it's already running.

# Add the following to your shell init to set up gpg-agent automatically for every shell
if [ -f ~/.gnupg/.gpg-agent-info ] && [ -n "$(pgrep gpg-agent)" ]; then
    source ~/.gnupg/.gpg-agent-info
    export GPG_AGENT_INFO
else
    eval $(gpg-agent --daemon)
fi
```
上記のようなものをprofileにでも書いて、sourceしておきます
gpg-agentはすでに起動済み　みたいなエラーが出る場合、

```shell
killall gpg-agent
```

してから再度sourceしておけば大丈夫だと思います

## gitに署名を設定する
### GPGの署名IDを取り出す
以下の呪文を唱えると、署名IDがクリップボードにコピーされます

```shell
gpg --list-secret-keys --keyid-format LONG | grep ^sec | cut -f4 -d ' ' | cut -f2 -d '/' | pbcopy
```

### gitに署名を設定
```shell
# 署名鍵の指定
git config --global user.signingkey {ペースト}
# gpgコマンドのパスを設定
git config --global gpg.program $(which gpg)
# コミット時の自動署名の有効化
git config --global commit.gpgsign true
```

## GitHubに公開鍵を登録
公開鍵は以下の要領でクリップボードにコピー出来ます

```shell
gpg --armor --export {GPGの署名ID} | pbcopy
```

あとは、GitHubのSSH and GPG keysページから、GPGの公開鍵として登録すればOKです
https://github.com/settings/keys


ここまで実施すれば、gitで何かコミットを実施した場合にパスフレーズの入力画面が出てくるようになり、正しいパスフレーズを入力すれば、コミットが署名されるようになるかと思います

## 参考ページ
https://qiita.com/miya0001/items/0b50fd2c482d61479f54