何気なく使っているactions/checkoutで気をつけること
こんにちは、島田です。
今回はいつも何気なく使っているGitHub Actionsのactions/checkoutでハマったポイントについて書いていきます。
何を作っていたか
弊社では
// [UNTIL] 2024-03-01
とコード内に書くことで、日付が近くなるとSlackに通知してくれるGitHub Actionsを運用しています。
これはシンプルですが意外と便利です。
例えば、Linyの機能にカレンダー予約というものがあります。
この機能は、カレンダーの空いている日付から日時指定の予約ができる機能です。店舗への来店や常設の相談窓口、サロンやクリニック、少人数の講座や面談の予約など、幅広く活用できる機能です。店舗の受付窓口になるので、当然祝日はお休みするなどの設定をできる必要があります。
日本における国民の祝日は、内閣府が前年の2月に公開します。2024年の2月に2025年の祝日が公開されるといった運用です。
そのため、Linyのカレンダー予約では毎年2月1日に次の年の国民の祝日を更新する必要があります。そこで、設定しているファイルに下記のコメントアウトを残すことで、毎年必要になる設定更新を忘れることなく実施できるのです。
// [UNTIL] 2025-02-01
祝日対応以外にも、
- 後でリファクタしたい時
- 調査用のログを仕込んでデータを貯めたい時
- フィーチャーフラグを仕込む時
などなど、活用の幅は広いものになっています。
ちょっとした困りごと
コメントの期限が近づいてきて、Slackへ通知が飛んだ時、「誰が残したコメントかわからない」という困りごとがありました。もちろんローカルでgit blameして誰がコメントしたかを調査すればいいのですが、忘れることもありますし、GitHub上またはSlack上で完結できると嬉しいです。
解決しようとした
解決するには、「git blameでコメントをつけたuser名を取得」すればいいだけです。簡単ですね。そう思っていました…。
「コメントつけたの私じゃないです」
あれ?ローカルで動かした時はきちんとコメントをつけた人が取れていたんだけどな。
確認したところ、本当に違いました。ローカルとGitHub Actionsのランナー上でのgit blameの結果が異なっていたのです。
$ git blame <ファイル名> -L <行数>,<行数>
00000000 (<Aさん> 2024-02-01 10:00:00 + 0900 <行数>) // [UNTIL] 2024-02-01 祝日を更新する
$ git blame <ファイル名> -L <行数>,<行数>
^0000000 (<Bさん> 2024-02-01 10:00:00 + 0900 <行数>) // [UNTIL] 2024-02-01 祝日を更新する
コミットID等はぼかしています
なぜ…? 🤔
色々調べてみると、どうやら「コメントをつけた人」ではなく、その「リポジトリへ最後にコミットした人」が出力されていました。
「なんだこれ。なんかコミットIDに変な^もついてるし…。」
(勘のいい人はここでもう気づいているかと思います。)
仕方ないのでsshしてデバッグする
CircleCI等にも存在しますが、CIには実行中のランナーにsshしてデバッグできる機能がよくありますね。GitHub Actionsも例に漏れずありました。
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
mxschmitt/action-tmate
をuseするだけでGitHub Actionsのstepの詳細にsshコマンドが表示されます。
これを自分のターミナルから実行することで、実行中のランナーにsshできます。
runner@fv-az417-768:~/work/playground/playground$
実行中のランナーでgit blameしてみた
runner@fv-az417-768:~/work/playground/playground$ git blame <ファイル名> -L <行数>,<行数>
^0000000 (<Bさん> 2024-02-01 10:00:00 + 0900 <行数>) // [UNTIL] 2024-02-01 祝日を更新する
確かに同じになる。
試しにgit logしてみる。
runner@fv-az438-605:~/work/playground/playground$ git log
commit 0000000000000000000000000000000000000000 (grafted, HEAD -> tmate-test, origin/tmate-test)
Author: <Bさん> <email@test.com>
Date: Fri Mar 1 15:59:29 2024 +0900
tmate-test
ん???
コミットが1つしかない!?
actions/checkoutが元凶だった
# Number of commits to fetch. 0 indicates all history for all branches and tags.
# Default: 1
fetch-depth: ''
fetch-depthを設定することで、正しくgit blameができました。
これで誰が担当か一発で分かるようになりましたね。
次は、これをSlackのメンションに変換したいなと思っています。GitHubのUser名→Slackのメンションの機構はすでに作ってありますが、GitHub上でコミットした時とローカルでコミットした時とで表示されるUser名が異なるため、この変換をどうしようか悩んでいます。
実行時間の変化を調べた(2024-03-09 追記)
fetch-depthが1になっているのは、checkoutを高速化するためだろうということは容易に予想がつきます。そのため、fetch-depthを0にしたとき、実行時間がどの程度変化するのかを調べました。
約8倍になっています。😨
※弊社で最もコード量の多いリポジトリで実行しています。
と言ってもこれは大した問題にはなりません。
CIの実行時間が伸びた場合考えられるデメリットとしては、以下の2点でしょう。
- CIの実行を待つ分開発者体験が悪くなる
- 課金額が増える
1点目はそもそもPullRequest等で走るCIの話です。今回のGitHub Actionsはスケジュール実行されるものなので、関係ありません。
2点目は GitHub Actionsの課金ルール のおかげで大した問題にはなりません。GitHub Actionsはランナー(≒Job)の実行時間ごとに1分単位で課金されます。今回のJobは変更後も1分以内に実行が完了しており、課金額は変わりません。
余談
リモートでgit blameした時についていたコミットIDの先頭についていた^
は、そのコミットが一番最初のコミットであることを表しています。これを知っていれば最初の方で気付けましたね。
Discussion