小さいプロジェクトでCIしてますか?

ポエムです。

ぼくはプログラマな仕事をしていて、受け持ってるプロジェクトはメンバ一人という小さいプロジェクトです。

この話は、ある日CIをしようと思った話です。

CIと言っても何がしたい?

何がしたい?ではなく。何がほしいか?な気がします。

CIと言っても何がほしい?

安心感です。

プログラマにこれが不足してくると、つらみをどんどん感じるようになります。

安心感を得るために必要な材料は人によって異なると思います。ぼくの欲しい安心感は

  • メモリーリークしてない
  • ビルドが通り、warningもない
  • Doxygenがエラーはいてない
  • メイン機能のテストが通っている

言語や案件によって様々な安心感があると思いますので、ここはきっと人それぞれです。

ふと周りを見るとCIしている現場はあまり多くありません。なぜでしょうか?

何でCIしてないの?

CI => テスト書かないと!という感じがあるのが原因な感じがしています(個人的な意見)

TDDもはじめから導入されているプロジェクトでない限り、始めづらいし、あとからつけるのもツライし...という感じになりテストがない=>CIもしないみたいな感じがあるような気がします(個人的な意見)

CIするには、テストを書かないとーってなってあとまわしな感じがあります(ぼくもそう思い時がある)

しかし、自分はただただ安心感を求めていることに気づいたので、まずテストコードを書いてということは、負担になってしまうのでやめました。

毎回GitでCommitやPushの度に、ビルドが通るか、主要な機能のテストが通るか、メモリーリークがないかをチェックするだけで、安心感が得られるのでそれだけなら頑張れる感じがしました。

さぁ、CI!

さぁ、CIということで有名なJenkinsさんを試してみようと思うのは、割りと一般的な人のやり口だと思います。

そして、Jenkinsを導入しようとちょっといじってみたのですが、ウッ...!っとなってしまいました。

Jenkinsを使うとなると、ユーザ作ってセキュリティの設定をして、Gitプロジェクトの登録方法を調べ、GitLab連携のこと調べ、鍵交換して、なんかエラーはいていて、任意のコマンドを実行させるには...Slackとかへの通知は......アッ...アッ...

とツライ...しか考えられなくなりました。

そして、Jenkinsはぼくの中でオワコンとなってしまいました。

ジャバアレルギー持ちなのでそれも影響したのではないかと思っています。

一歩引いてJenkinsを見てみるとぼくがしたかったのは

  • ビルドコマンドやメモリリークチェックツールの実装(スクリプトを叩く)
  • 通知と履歴閲覧
  • Git連携(CommitやPostでJenkinsにテストを走らせる)

もともと小規模なプロジェクトで、やらせたいことは大したことはない気がしました。

「コマンドを実行して、DBに保存し、通知する」

だけなので、なんか作れそうな気がしますし、作ってたほうが楽しいです。

Git-Hook-DrivenなCIツールを作った

というわけで、要件(コマンドを実行、DBに保存、通知)を満たしているツールを作ってみました。

yymm/Hartmann

CLIのクライアント・サーバアプリです。GolangとPythonで書きました。Jenkinsでググると軍人が何人か出てくるので軍人の名前にしました。

手間をかけずに作ることも重要だったので、超軽量な感じです。

Git-Hook-Driven

Jenkinsを設定していて、GitLabなどのホスティングサービスとの連携(web hook)の設定がめんどうでした。

さらに、今回の場合わざわざテストサーバにテストをしてもらう必要はありません。望んている内容は同じ環境内でテストしても問題ないし、テストサーバたてるのもかなり面倒です。

そして、Commitしたらテスト、Pushしたらテストというサイクルをプロジェクトのライフサイクルに組み込めればいいと考えました。

ということで、Git Hookにビルドスクリプトを仕込みます。

ビルドが時間のかかる処理の場合は、”exec <command> &”にしてバックグラウンドで処理するようにしました。

具体的には、.git/hook/post-commitに以下の内容を追加しました。

ex. post-commit

#!/bin/sh
echo "CI!!"
exec client.py "cd ~/path/to/project && ./buildscript" &

実行すると、

% git cm "test commit"
CI!!
[master 8456393] test commit
 1 file changed, 1 deletion(-)

となって、バックグラウンドでビルドなどが走ります。

クライアント・サーバ

クライアント(Python)がコマンドの実行結果をJsonでPostして、サーバ(Golang)がRedisにそのJsonを保存するだけの簡単アプリです。

MacOSXとUbuntuのNotifier(teminal-notifier, notify-send)で通知をしてくれるようにもなってます。

クライアントはGit Hookに仕込んで、お好みのタイミングで使えるように設計しました。

Note

問題点はいろいろありますが...

  • 履歴をまともに見れない
  • なんか色々まだ雑
  • 自分しか使っていないのでドキュメントもないもない

とりあえずこれで、ぼくのプロジェクトは、変なコードを仕込んだらコミットの度に怒られるようになり、良い緊張感で仕事できるようになりました。

仕事の息抜きにこのアプリを改良したりと楽しいこと(Golang書いたりPython書いたり)できるので、モチベーションも保たれ作業効率がUPすることは間違いないでしょう。

まとめ

安心感と心の平和のために、本当に必要な物は何か、一般的な情報(Jenkinsとか)から離れて考えてみることはいいことな気がしました。

本当に必要としているものは、そんな大それたことではなくて、シェルスクリプトとか既存の技術をちょっと組み合わせるだけで済んでしまうようなことかもしれません。

ポエムとは何かよくわかってませんが、ポエムでした。