クラウドインフラ本部ネットワークサービス部のid:a8544です。
連載13回目の今回は、これまで「CI戦術編」で紹介してきたいろいろなツールについて 振り返り、それらツールをいつ・どのように実行するべきなのか、わたしたちの実例をもとにご紹介します。
🤔 ふりかえり — ご紹介してきたツールたち
これまで本連載では、わたしたちがCIで活用しているツールの一部をご紹介してきました。 それらツールを次の表にまとめます(各記事へのリンクは、本記事末尾のバックナンバーをご確認ください)。
回 | ツール(等)名 | ひとこと説明 |
---|---|---|
2 | alembic | データベースマイグレーション |
3 | cSpell | スペルチェッカー |
4 | isort | Pythonのimportのソート |
5 | black | Pythonのコードのフォーマッタ |
6 | mypy | Pythonのコードの型検査 |
7 | Pylint | Pythonのコードの静的検査(リンター) |
8 | pyupgrade | Pythonのコードの静的検査(リンター) |
9 | OAS生成 | FastAPIでOASを生成する方法 |
10 | openapi-typescript | OASからTypeScriptのライブラリを生成する方法 |
11 | Renovate | 依存ライブラリのアップグレードヘルパー |
12 | Trivy | 依存ライブラリの脆弱性検知 |
これらツールはいずれも、わたしたちのCIで実行されるという共通点を持ちます。
ツールはたくさんありますが、各ツールの目的で見ると、次のように3つに分類できます。
- コード品質向上 : わたしたちが実際に書くコードの品質を維持する
- フォーマッタやリンターなど
- コード生成 : 開発に必要なコードを、すでに存在するコードから自動で生成する
- 外部管理 : 依存ライブラリの管理をする
- RenovateやTrivy
🏃 ツールの実行機会
わたしたちの開発において、これらツールがCIで実行されることに違いはありません。
ただし、これらツールをCIで しか 実行していないというわけでは ありません。 CI以外、つまり開発者の開発する端末で実行することで、より恩恵が受けられるツールもあるからです。
さらに、CIも一様ではありません。CIが 起動する機会(GitLabでは、CIのパイプラインが起動する機会)によって、その処理も分けています。
このことを説明するために、まずツールを実行する機会には何があるのか整理します。 より頻繁に発生するものから順に、次のようなものがあります。
- 即時 : 書かれたコードに対して即時(タイプするたびに)実行する。エディタ中で動作する。
- コーディング中随時 : 開発者がコードを書いている中で、必要だと判断したときに都度実行する。開発者の端末で動作する。
- プッシュ時 : コードがプッシュされる、マージリクエスト(プルリクエスト)が作成・更新される都度実行する。CIで動作する。
- ナイトリー : 一日一回、最新のリポジトリのコードについて実行される。CIで動作する。
これらの機会についてまとめたのが、下表です。
機会 | 実行場所 | 方法 | 頻度 |
---|---|---|---|
即時 | 開発者のローカル端末 | エディタ (IDE) | 数秒に1回 |
コーディング中随時 | 開発者のローカル端末 | タスクランナー | 1時間に数回 |
プッシュ時 | CIランナー | CI | 1日に数回 |
ナイトリー | CIランナー | CI | 1日に1回 |
ここで「タスクランナー」は、端末で yarn run
を実行することで起動されるような(参考)、
小さなスクリプトを指します。フロントエンドでは Yarn を、
Pythonのバックエンドではmakeを使っています
(Poe the Poet の導入も部分的に行われています)。
例えば、 make lint
を実行することで、一連のリンターが実行されるようにしています。
🧭 ツールの実行戦略
目的が異なれど、各種ツールはコードをよりよいものにすることを助けてくれるものですから、 実行して損することはありません。ただ、すべてのツールをコードを書くたび、即時実行すればいいのかというと、 当然ながらそうではありません。 どの機会にどのツールを実行すべきなのか、その判断の材料となるのは、「ツールの目的」と「実行に要する時間」です。
ツールを実行する目的
まず「コード品質向上」には、コードを書いている最中にも役立つツールが多くあります。 例えばmypyは、型検査によってtypoや根本的なロジックの誤り(のうち、単純なもの)を検出できます。 検出が早ければ早いほどすぐ誤りに気付いて修正できるので、作業時間が短縮できます。よって、 このようなツールは、支障のない範囲で頻繁に、コーディングの最中にも実行することがあります。
一方で「コード生成」は、完成した既存のコードから、 機械的に別のコードを生成するプロセスです。したがって、開発者がタイプするたびに実行する必要はなく、 ある程度意味のある単位で「完成」してからその都度実行するのが適切です。
また、「外部管理」は、依存ライブラリの更新や新たな脆弱性の発見があって 初めて意味をなすものです。これらは開発者のコーディングの過程には関係ない、 予測が困難なタイミングで発生します。したがって、開発の過程にひもづく機会で実行する意味はなく、 一日一回などといった固定のタイミングで実行することが妥当でしょう。
ツールを実行するのに要する時間
ツールを実行するには時間がかかります。かかる時間はツールによってかなり差があります(1秒未満〜数分)。 キーをタイプするたびに待たされるようでは、開発が進められません。 よって、頻繁に生じる機会で実行するツールは、自然と高速なツールに限られます。
まとめ
以上の観点をもとに、これまでご紹介してきたツールの実行機会を整理したのが、次の表です。
ツール名 | 目的 | 即時 *1 | コーディング中随時 | プッシュ時 | ナイトリー |
---|---|---|---|---|---|
alembic | コード生成 | ✅ | ✅ | ✅ | |
cSpell | コード品質向上 | ✅ | ✅ | ✅ | ✅ |
isort | コード品質向上 | ✅*2 | ✅ | ✅ | |
black | コード品質向上 | ✅*2 | ✅ | ✅ | |
mypy | コード品質向上 | ✅*3 | ✅ | ✅ | ✅ |
Pylint | コード品質向上 | ✅*4 | ✅ | ✅ | ✅ |
pyupgrade | コード品質向上 | ✅ | ✅ | ✅ | |
OAS生成 | コード生成 | ✅ | ✅ | ✅ | |
openapi-typescript | コード生成 | ✅ | ✅ | ✅ | |
Renovate | 外部管理 | ✅ | |||
Trivy | 外部管理 | ✅ |
表への注:
- *1 わたしたちの開発では、各開発者が自由にエディタ (IDE) を選択して使っています。 エディタ (IDE) の設定は各開発者が自身の責任で行うので、この構成が強制されているわけではありませんが、 実態として全員がほぼ同様の構成を採っています。
- *2 エディタ (IDE) で保存時に実行されるように構成している開発者がほとんどです。
- *3 エディタ (IDE) 中ではmypyではなく Pyright (Pylance) を使っていたり、併用している開発者もいます。
- *4 Pylintの実行は遅いので、 エディタ (IDE) 中では実行していない開発者もいます。
この表から分かるように、「即時」の機会で実行するツールは限られており、より頻度の低い機会になるほど、実行されるツールが増えます。
また、Renotave・Trivyを除くツールは全て、開発者が手元で「コーディング中随時」実行できるようになっています。 実際、CI(プッシュ時)でも、手元で随時実行するときも、全く同一のタスクを実行しています。 これは、CIでのテストと手元での確認をなるべく統一し、「手元では通るのにCIでは通らない」という事態が起こるのを防ぐためです。
さいごに
CI戦術編でご紹介してきたツールをまとめ、それらツールがどの機会で実行されるように構成しているのかをご紹介しました。 これまでの各回ではCIでの実行を中心にご紹介してきましたが、ツールによってはより頻繁に・さまざまな機会で実行していることをご説明しました。 また、「CIでの実行」と一言に言っても、目的によって実行の機会を変えていることもご説明しました。
この回まででCI戦術編の内容は以上となります。次回からは、「CI・CD戦略編」と題して、CI・CDの実装戦略をご紹介していきます。CI・CD戦略編の初回となる次回は、「テスト戦略」についてご紹介する予定です。 お楽しみに。
連載バックナンバー
CI戦術編
- 【CI戦術編 その1】alembic check コマンドを活用したマイグレーションスクリプト生成忘れ防止
- 【CI戦術編 その2】コードレビューを充実したものにする方法、あるいは一生残る恥ずかしい履歴を作らないように
- 【CI戦術編 その3】Pythonのimportのことならまかせろ isort
- 【CI戦術編 その4】Blackを利用したコーディングスタイルの統一
- 【CI戦術編 その5】Pythonで明示的に型を書く理由
- 【CI戦術編 その6】Python開発の強い味方 Pylint
- 【CI戦術編 その7】 pyupgradeを使って最新の記法に対応してみた
- 【CI戦術編 その8】OAS(OpenAPI Specification)で仕様書を自動生成しよう
- 【CI戦術編 その9】自動生成しか勝たん openapi-typescript
- 【CI戦術編 その10】 Renovateで依存ライブラリのアップデートに負けない方法
- 【CI戦術編 その11】Trivy: あなたの使ってるライブラリ、大丈夫ですか?
- 【CI戦術編 その12】CI戦術編総まとめ — いつ何を使うべきか