at backyard

Color my life with the chaos of trouble.

GitHub上で表示されるコミットを署名付きにするために行ったこと

tauri-plugin-sqlにPRを送った際に、署名付きのコミットにしてほしいと言われたので、始めてコミットに署名をつけるという設定を行った。

github.com

単に以下のようにマークが付くというだけでなく、そのコミットが本人のものであることが証明できるようになっているらしい。

Verifiedというマークが付く

今回、上記リポジトリへのコントリビューションに必要ということで急遽設定したので、細かな背景・仕組みなどはまだ理解していないが、設定のために行ったことを備忘録として残しておくことにした。

自身の環境

mac環境はarm64の 11.6.7 (M1のMacBook Air)

Gitは以下の通り。

git --version
# git version 2.30.1 (Apple Git-130)

gpgとpinentry-macをインストール

まずは署名をつけるために必要になるGPGキーを生成するためのツールをインストールする。

brew install gpg pinentry-mac

pinentry-mac というツールはGUI上でパスフレーズを入力するためのツールという理解。
たぶんなくても良さそう。

インストールしたgpgバージョンはこちら。

gpg --version
# gpg (GnuPG) 2.3.7
# libgcrypt 1.10.1

インストールしたpinentry-macのバージョンはこちら。

pinentry-mac --version
# pinentry-mac (pinentry) 1.1.1

Pinentryのパスを設定する

Pinentryを利用するための設定が下記。

GnuPGで利用するPinentryのパスを指定するなどしている。

# ディレクトリ作成(他の人の記事を見ていると勝手に作られるような気配もあったが自分の場合はなかったので作成)
mkdir ~/.gnupg

# Pinentryのパスの設定
echo "pinentry-program /opt/homebrew/bin/pinentry-mac" > ~/.gnupg/gpg-agent.conf

# 参照していた記事の一つに書いてあったので勢いで打ってしまったが、特に打たなくても良かったかもしれない。あとで気が向いたら調べる。
gpgconf --kill gpg-agent

GPGキーの作成

下記のコマンドを打つことでGPGキーを作成するためのフローが開始する。

gpg --full-generate-key

いくつかの質問に答える。
(必要そうなところだけ抜粋する)

なお、私のGPG環境は日本語が勝手に有効化されていたので、普通に日本語で質問されています。

鍵の種類の選択

ご希望の鍵の種類を選択してください:
   (1) RSA と RSA
   (2) DSA と Elgamal
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
   (9) ECC (署名と暗号化) *デフォルト
  (10) ECC (署名のみ)
  (14) カードに存在する鍵

特にこだわりがなければEnterのみでOK

楕円曲線の選択

ご希望の楕円曲線を選択してください:
   (1) Curve 25519 *デフォルト
   (4) NIST P-384
   (6) Brainpool P-256
あなたの選択は?

こちらも、特にこだわりがなければEnterのみでOK

鍵の有効期限の設定

鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は?

鍵の有効期限。デフォルトでは無制限となる。 期限を設定した場合、期限切れとなると更新が必要。

GitHubのドキュメントにも更新の際の事が書いてあった

https://docs.github.com/ja/authentication/troubleshooting-commit-signature-verification/updating-an-expired-gpg-key

本名とメールアドレスとコメントの入力

次に本名とメールアドレスとコメントを入力する。

  • 本名 - 言葉通り本名を入力する。ニックネームでも良いとの記述も見たが、検証はしていない
  • メールアドレス - GitHubに登録されているメールアドレスを入力する。メールアドレスを入力したくない場合は <username>@users.noreply.github.com でも良いとの記述を見かけた気がしたが、ちゃんと調べてはいない(※)
  • コメント - 特に入力するものがなければ空でもOK

※この件についてはGitHubの下記のドキュメントあたりに載っている...かもしれない

https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-email-preferences/setting-your-commit-email-address#setting-your-commit-email-address-on-github

次にパスフレーズの設定を実施。
これは私の場合はGUIにプロンプトが立ち上がってそちらで入力した。
(せっかくなのでキャプチャ撮っておけばよかった...)

これで鍵の生成は完了。

公開鍵の設定

次に公開鍵の設定を実施する。

まずは下記のコマンドを叩く。

gpg --list-secret-keys --keyid-format=long

下記のようなものが表示される。
※番号は適当にマスクしています。

--------------------------------
sec   xxxxxxx/foofoofoofoofoofoo 2022-XX-XX [SC]
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid                 [xxxxxxxxx] username <mail@example.com>
ssb   xxxxxxxx/XXXXXXXXXXXXXXXX 2022-XX-XX [E]

ここで表示された番号のうち、 foofoofoofoofoofoo の部分を使って以降のコマンドを実行していく

gpg --armor --export foofoofoofoofoofoo

これで公開鍵が生成される。

生成されたものは -----BEGIN PGP PUBLIC KEY BLOCK----- から -----END PGP PUBLIC KEY BLOCK----- までを含めてクリップボードにコピーし、下記のGitHubで登録する。

https://github.com/settings/gpg/new

タイトル欄は自分でわかるようなタイトルをつけた。

GPGキーをGitクライアントに設定

次にローカルPCのGitクライアントにGPGキーを設定する

git config --global user.signingkey foofoofoofoofoofoo

これで設定は完了。

署名付きでコミットする方法

署名付きでコミットする際には以下の3通りの方法が選択できるらしい。

  • コミット単位で署名付きにする方法
  • 特定のリポジトリ内のすべてのコミットを署名付きにする方法
  • すべてのリポジトリのすべてのコミットを署名付きにする方法

特定のリポジトリ内のすべてのコミットを署名付きにする方法

今回はひとまずコントリビュートしようとしたリポジトリのみで有効にできればよかったので、2番めの 特定のリポジトリ内のすべてのコミットを署名付きにする方法 を採用した。

特定のリポジトリのみで有効にする方法は、リポジトリディレクトリに移動して下記のコマンドを実施するのみ。

git config commit.gpgsign true

これで以降のコミットは署名付きのものとなる。

コミット単位で署名付きにする方法

コミット単位で署名を付けたい場合、 -S オプションを付けてコミットする。

git commit -S -m "Signed commit"

すべてのリポジトリのすべてのコミットを署名付きにする方法

globalに対して設定することで全てのコミットが署名付きとなる。

git config --global commit.gpgsign true

一度コミットした内容を署名付きで再度コミットする方法

ここからは今回のケースで私が行った方法についてなので、かなり個人的な内容となってくる。

まず、すでに署名なしの状態でコミットしていたため、これらを署名付きのコミットにする必要があった。
レビュアーの方からforce pushしてほしいと言ってもらえたので、

  • すでにコミットした内容を一度取り消しして、
  • 再度コミットしなおす(リポジトリ単位で有効化しているためこの時点で署名付きのコミットになっている)
  • 最後にリモートリポジトリに対してforce pushする

という段取りで作業をさせてもらった。

コミットの取り消しについて

コミットの取り消しについては以下の方法で実施。

# 最新のコミットを取り消し
git reset --soft HEAD^

# addも取り消し
git reset HEAD <取り消したいファイル>

これで自身のコミットを一度全て取り消した。

その後、再度同じ内容でそれぞれコミットし、最後にリモートリポジトリにforce pushした。

初めて署名付きコミットをする場合

ちなみに署名付きのコミットを初めて実行する際はGUIのプロンプトがでてきてパスフレーズを求められる。

keychainに保存するにチェックを入れてパスフレーズを入力すると、次回からの入力は省略できる。

署名入りの空コミットを行う方法

もう一つ個人的なメモ。

最初署名入りの空のコミットを行おうとしていた。
(が、全てのコミットが署名入りでないとPRをマージできないようになっている、ということだったのでこの方法は意味をなさなかった)

が、一応やり方を調べてみたのでメモがてら書き残しておく。

gitコマンドは--allow-empty オプションを付けることで変更がない状態でも空コミットが可能となっている。
上にも書いたようにすでに署名入りコミットは有効化されているため、下記のように空コミットをして対応した。

git commit --allow-empty -m "Signed commit"

もし署名を有効化していない場所で一発だけ署名入りコミットをしたい場合は下記のようになるかと(未検証)

git commit --allow-empty -S -m "Signed commit"

備忘録は以上となる。

今回PR送らせてもらった tauri-plugin-sqltauri を使ってかんたんなノートアプリを作ってみている。

開発時の体験もサクサク進められる感じで楽しいです。