うさぎ組

ソフトウェア開発、チームによる製品開発、アジャイル、ソフトウェアテスト

Git + Jenkins + Groovyの連携2 #kyon_mmAdvent

kyon_mm Advent Calendar

つぎのリンクにあるAdventCalendarの三日目です。
http://connpass.com/event/1457/

Gitの共有サーバを構築して、開発PCと連携する

よくあるというかやりやすそうな構成を下に図示しました。


GitとJenkinsを別サーバーにするほうがスケールしやすいのですが、このブログ対象読者は一応入門なので、とりあえず置いておきます。
Gitのサーバーを別にするならgitoliteで管理するのがいいかと思います。


Gitの共有リポジトリをいじる方法は大別すると3つになります。

  1. ディレクトリをまるごと共有する
  2. git内蔵のdaemonコマンドでサーバーをたてる
  3. 他のツールを使ってサーバーをたてる (ex. gitolite,gitosis etc

ファイルサーバーがあってそこに置く程度で運用するなら、1がいいでしょうし、専用のサーバーで行うなら2か3になります。
2の場合は認証を行いません。
3はツールによって異なりますが、ssh認証を行うものが多いです。



スモールスタートとしてやってみるのであれば、1,2がいいかなって思いますが、これから短い期間でスケールしていくことが判明しているのであれば、3がいいと思います。


ここから先はかなり投げやりで、ここを読んでください方式です。
というか1,2,3全部Pro Gitに書いてあるんですね。はい。
ProGit4章のGitサーバーはとりあえず、4.1から4.5まではどの方式でもだいたい必要な知識なので目を通しましょう。そのあとに、とりあえず自分でやってみる方針の公開方法の部分を読んでみましょう。時間があれば他のも読んでみるといいと思います。
Git - Git サーバー


gitoliteであればこちらの記事も参考になります。
http://blog.hifumi.info/dev/gitolite-manage-multirepos/

Gitのコマンドから自動的にJenkinsのビルドを実行する

GitやMercurialなど、VCSには「フック」というものが存在します。ツールによって提供している範囲は様々ですが、基本的に「あるコマンドが実行される直前」「あるコマンドが実行される直後」に「自動的に実行させたい処理」を指定することが可能です。
Gitの場合はこれはhookと呼ばれ、各リポジトリのhookディレクトリに格納されることになります。
これを使いJenkinsのビルドを実行させるようにします。
必要な作業は次になります。

  1. GitやJenkinsの配置構成を決める。
  2. ビルドするプロジェクトに必要なJenkinsのプラグインツールをJenkinsサーバーにインストールする。
  3. Jenkinsで実行したいJOBを作成し、クローンしてくるリポジトリを指定する。
  4. ビルドを実行したいタイミングを「どのリポジトリ」で「どのようなコマンドが発生した」ときかを決定して、hookスクリプトを指定する。

全体を上の画像のような構成で考えると、「サーバー側リポジトリ」に「pushされたタイミング」でビルドするとよさそうな気がします。


注意はGitでshareするリポジトリは--bareオプションでリポジトリを作る必要があります。
多くは次の2パターンになります。

  1. 既にあるリポジトリから「git clone --bare {既にあるリポジトリ}」として、クローンしてきたものを共有リポジトリとする。
  2. 新規作成のプロジェクトなので「git init --bare {リポジトリ名}」として、共有リポジトリを新規につくってプロジェクトを開始する。

共有リポジトリを作成したら、あとは各開発PCがクローンします。サーバーと開発PCでどのように通信させるかはこのエントリの前半の参考Webサイトを参照してください。


サーバーのリポジトリ(bareリポジトリ)のhookスクリプトを変更します。
仮にこのプロジェクトが「/Users/kyon/repos/git/gradle_central」にあるとすると、次のようなディレクトリ構成になっているはずです。


このhooksディレクトリにhookスクリプトの初期サンプルがはいっています。ファイル名から.sampleを除くと該当のスクリプトが有効になります。
※シェルやコマンドプロンプトは対象の実行ファイルを実行した時の終了値というものがあります。コマンドプロンプトならERRORLEVELといわれる変数がそれにあたります。それが0に設定されれば正常終了、0以外ならなんらかのエラーが発生している。0以外がどんな意味をもつかは、その実行ファイルが定義する。というルールがあります。


いくつか紹介すると次のようなものがあります。
pre-applypatch.sample -> git amコマンドを使ってパッチとしてコミットを適用しようとしたときに実行される。終了値が0以外でamコマンド失敗になる。
pre-commit.sample -> git commitコマンドを使ってコミットをつくろうとしたときに実行される。終了値が0以外でcommitコマンド失敗になる。
commit-msg.sample -> git commitコマンドを使ってコミットをつくろうとしたときに実行される。ユーザーが入力したコミットコメントを保存している一時ファイルが入力になる。終了値が0以外でcommitコマンド失敗になる。


今回は「post-receive」を使いましょう。これは「他のリポジトリからpushされたコミットの反映が完了したときに実行される」ものです。
post-receiveというファイル名にし、次の内容でhooksディレクトリ直下に置きます。

#!/bin/sh

# curl http://{JenkinsのURL}/job/{JOB名}/build?delay=0sec
curl http://localhost:8080/job/Gradle_Build/build?delay=0sec


これで、サーバー側の準備はできました。
あとは、次の流れになります。なお、使用するブランチはとりあえずmasterのみとします。
重要な原則が2つあります。
1.gitの操作をするときは、常に対象のリポジトリのgitkを開いておく。gitに対する操作はコマンドラインとする。
2.gitの変更をpushする前に必ず、pullやfetchを行い、全ての変更をmergeもしくはrebaseしてからpushすること。

これをふまえて次のフローですすめます。

  1. 開発PC側でgradle_centralリポジトリをクローンする。git clone gradle_central
  2. 開発PC側のリポジトリ上で次のコマンドでgitkを起動する。gitk --all &
  3. 開発PC側でクローンしてきたリポジトリに対して変更を加える。
  4. 開発PC側で変更をコミットする。git add . ; git commit
  5. gitkでF5を押し、更新されていることを確認する。
  6. 開発PC側でまずはサーバー側の変更を受け取る。 git pull ; (代わりにgit fetch; git mergeもしくはgit rebaseでもよい。というか、こちらのほうがよい。)
  7. gitkでF5を押し、思ったように変更が取り込まれている事を確認する。
  8. 開発PC側で変更をサーバー側に共有する。 git push origin master
  9. ここからは自動的に動作する話
  10. gradle_centralリポジトリがpushを受け取る。
  11. gradle_centralリポジトリcurlコマンドを使ってJenkinsのビルドを起動する
  12. JenkinsのGradle_Build JOBがgradle_centralリポジトリの最新の状態をcloneしてビルドを開始する。

ビルドの失敗を通知したい場合は、JOBの設定画面の「ビルド後の手順の追加」でメール通知をするようにしてもいいでしょうし、Twitterで通知するプラグインもあるので、インストールしてみて使ってみるのもいいと思います。



Jenkins

Jenkins

プログラミングGROOVY

プログラミングGROOVY

入門Git

入門Git