こんにちは、生産性向上チームの平木場 (@Shitimi_613) です。みなさん依存関係更新は定期的にやっていますか?今回は生産性向上チームが開発した assam という OSS の依存関係更新フローを改善したお話をします。
目次
はじめに
生産性向上チームは assam という OSS を開発およびメンテナンスしています1。必要な機能の開発はすでに終えており、現在は問題が発生した場合に bug fix や脆弱性改修をリリースしています。
そのため、リリースは頻繁に行っているわけではなく、assam のコードに触れるときは何か問題が起きたときだけです。その結果、リリースの間隔が開くことによって、いざリリースしようとしたときに依存関係の更新で様々な問題に遭遇するというつらい問題が発生していました。
今回は細かく依存関係更新をしていくために実施した取り組みを紹介します。
こまめに依存関係を更新していくために
こまめに依存関係を更新していくためには、「なにか問題が起きたら修正してリリースする」という非常にざっくりとしたメンテナンスのルールを刷新する必要がありました。まず要求をチームメンバーで出し合い、要求を満たすためにやることを考えました。
依存関係更新がこまめにできていない原因として以下の事柄が挙げられました。
- 依存関係をいつ更新するかが定まっていない
- 依存関係更新のプルリクエストを作成するサービス(Renovate)がプルリクエストを作っても放置して忘れてしまう
- 更新時に何を確認するべきかが定まっていない、属人化されている(ユニットテストが通ればいい?実機でのテストも必要?)
要求
原因を解決するために必要なことを話し合い、こまめに依存関係を更新していくための要求を出しました。
要求 | 理由 |
---|---|
依存関係を定期的に更新する | 不定期で発生するリリース作業を楽にするため |
依存関係の更新のみを理由にリリースしない | 意味のない更新はユーザーに価値を提供しないため |
更新作業になるべく工数を割かない | 他の作業ができる時間が減ってしまうため |
動作確認を忘れない | 更新に伴って品質を落としたくないため |
更新作業の存在を忘れない | 今回のような問題を再発させないため |
決めた取り組み
そして、要求を満たすために以下を取り組むことにしました。
取り組み | 満たす要求 |
---|---|
週一で更新作業を行う | 「依存関係を定期的に更新する」 |
動作確認手順書を作成する | 「更新作業になるべく工数を割かない」「動作確認を忘れない」「依存関係の更新のみを理由にリリースしない」 |
依存関係更新のプルリクエストが自動生成されるようにする | 「更新作業になるべく工数を割かない」 |
チームで使っているタスク管理ツールに定期的に更新タスクが自動生成されるようにする | 「更新作業の存在を忘れない」 |
更新作業の間隔についてどれくらいの間隔が適切かの判断が難しかったため、とりあえず週一で行ってみて必要なら間隔を変えることにしました。
実際にやったこと
実際にやったことが以下になります。
- 動作確認手順書の作成
- Renovate 設定ファイルの修正
- 更新タスクの自動生成
動作確認手順書の作成
assam の動作確認を円滑に行うために動作確認手順書を作成しました。(本当は動作確認そのものを自動化したいところですが、動作確認を自動化するために専用の環境を用意するのが厳しく、また確認したい項目が多くなかったため、手動で動作確認をすることにしました。)
動作確認手順書には「手順」と「確認したいこと」をそれぞれ含めました。また実際に実行するコマンドを記述することで、高速かつ人によってムラが出ない動作確認を行えるようにしました。
動作確認手順書を一部抜粋したものを以下に示します。
- 確認したいこと
- ビルドできること
- 設定ができること
- 認証ができること
- 認証後に AWS CLI が叩けること
- 手順
- プルリクエストの Files Changed を見て不自然な差分がないことを確認する
- チェックアウトする
- ビルドする(
go build
)(確認:ビルドできること) ~/.aws
を rename する (mv ~/.aws ~/.aws.backup
)- assam の設定をする(
./assam -c
)(確認:設定ができること) - ...
Renovate 設定ファイルの修正
assam は依存関係更新をスムーズに行うために Renovate を以前から利用しており、依存関係先が新たに更新されるとその都度プルリクエストが作成されます。
私たちは 1 週間に一度のみ更新することにしたため、プルリクエストが生成されるタイミングを週一にするような設定をしました。
また、このままでは依存関係ごとにプルリクエストが生成されるため、検証・更新を複数回行う必要があり煩雑です。assam の場合、依存関係の数が少ないため、1 つの Pull Request にまとめても問題発生時の切り分けは難しくありません。そのため、複数の依存関係の更新を 1 つのプルリクエストにまとめる設定も行いました。
実際のrenovate.json5
を以下に示します2。
{ "extends": [ ":label(renovate)", // プルリクエストに renovate ラベルを付与する ":prConcurrentLimit10", // Renovate が作れる open なプルリクエストを最大 10 個にする ":timezone(Asia/Tokyo)", // タイムゾーンを Asia/Tokyo にする ":enableVulnerabilityAlertsWithLabel(security)", // 脆弱性に関するプルリクエストに security ラベルを付与する ":semanticCommitTypeAll(chore)", // コミットメッセージの先頭に chore を付与する "schedule:weekly" // 毎週月曜日の午前 0:00 から午前 3:00 までの間でプルリクエストを作成する ], "postUpdateOptions": [ "gomodTidy" // go mod tidy を行うようにする ], "groupName": "all" // 全てのプルリクエストを all という名前でまとめる }
この設定により、依存関係更新のコミットをまとめたプルリクエストが毎週月曜日に生成されます。生成されるプルリクエスト例を以下に示します。
更新タスクの自動生成
生産性向上チームは Linear というタスク管理クラウドサービスを利用しています。Linear には API が用意されており、Issue(タスクのこと)の生成やメンバーのアサイン、State の変更などを自動化できます。
今回私たちは GitHub Actions ワークフローを定期実行し、Linear API を叩き、タスクを自動生成するようにしました。Scheduled events を設定することでワークフローを自動実行できます3。
例えば、毎週月曜日の朝 9 時(日本時間)に実行したい場合は以下のようにします。(GitHub Actions では UTC 時間で cron 構文を書く必要があるので 9 時間ずらして設定しています。)
on: schedule: - cron: '0 0 * * 1'
Linear API をワークフローのシェルから直接叩く方法が手っ取り早かったのですが、Issue の description を Markdown で記述する必要があるため、今後、定期作成タスクの新規作成や編集の際に開発体験がよくないと考えました。そのため、Linear JavaScript SDK を使って Markdown で書いたタスクを作成するプログラムを作成し、定期作成タスクの編集や新規作成をしやすくしました。
例えば、次のような Markdown を作成します。
--- # YAML front matter に Linear API の IssueCreateInput のパラメータを記述することで、Issue 登録時にその情報が反映されるようになっています。(title は必須です) ## 参考:https://github.com/linear/linear/blob/19a8db2837cc7e324891e83241b68ce95405fba3/packages/sdk/src/schema.graphql#L2004 title: assam の renovate 対応 estimate: 1 --- https://github.com/cybozu/assam/pulls ## タスク作成時のチェック - このタスクのユーザと提供価値、それに対する品質の確認方法が決まっている - ユーザ: 生産性向上チーム - 提供価値: assam のリリースするときに依存関係更新で困らない - それに対する品質の確認方法: 動作確認できている ## 受け入れ条件 - [ ] assam の renovate が作成した PR がすべてマージされている - [ ] [動作確認マニュアル](動作確認マニュアルへのリンク)の手順で動作確認ができている ## やらないこと - リリースはやらない *created by [cron-linear-issue](リポジトリのリンク)*
そして、GitHub Actions のワークフローを用意することで、以下のようなタスクが定期的に生成されるようになりました。
やってみた結果
新しい依存関係更新フローの運用を始めてから 1 ヶ月強ほど経ち、定期的に assam の依存関係更新をするようになりました。
定期的にプルリクエストが作成され、自動で作成されるタスクのおかげで更新作業を忘れない上に、動作確認手順書のおかげでメンバーに関係なく同じ品質の動作確認が行えるようになりました。その後実際にリリースする場面がありましたが、依存関係に関するトラブルは発生せず、スムーズに assam をリリースできました。
始めて数回の頃はまだプロセスに慣れていませんでしたが、だんだんメンバーも慣れてきて更新にかかる時間も減ってきました。また、週一で更新作業をやっていたところ「assam のリリース頻度から考えるに月一で依存関係を更新しても良さそう」という話になり、途中から月一で更新するように変更しました4。
やってみた結果、事前に決めた要求を継続的に満たすことができ、スムーズに assam をリリースできるようになりました。
まとめ
頻繁に更新しないような OSS を長期的に運用していくためにこまめな依存関係更新はかかせません。
この記事では継続的に細かく依存関係を更新するために、生産性向上チームが行った取り組みを紹介しました。この取り組みによって、チームが抱えていた「依存関係の更新を細かく行えていない」という問題を解決し、assam のリリースがスムーズに行えるようになりました 🎉
OSS である assam に対して今回の仕組みを適用しましたが、社内で生産性向上チームが開発・運用しているサービスやツールにも同じような仕組みを流用できそうだなと考えました。リリース後もしっかりと面倒を見ていきたいですね。
We're hiring!
生産性向上チームは社内エンジニアの生産性を爆上げするための活動をしているチームです 💪💪
生産性を上げることが好きな方をお待ちしております!
-
詳しくは GitHub リポジトリと「AWS + Azure ADによるSingle Sign-Onと複数AWSアカウント切り替えのしくみ作り」をご覧ください。↩
-
設定について詳しく知りたい方は Renovate 設定ファイルのドキュメント(https://docs.renovatebot.com/)を参照してください。↩
-
余談ですが、パブリックリポジトリの場合、60 日間リポジトリにアクティビティがないとスケジュールされたワークフローが無効化されるので注意が必要です。Warning: To prevent unnecessary workflow runs, scheduled workflows may be disabled automatically. When a public repository is forked, scheduled workflows are disabled by default. In a public repository, scheduled workflows are automatically disabled when no repository activity has occurred in 60 days. https://docs.github.com/en/actions/managing-workflow-runs/disabling-and-enabling-a-workflow↩
-
スパンが長くなり更新および動作確認作業を忘れる懸念がありますが、詳細な手順書があることやタスクから手順書への導線があることから、たとえ忘れても更新はできると考えます。↩