GitLab の push をトリガーに Jenkins を回す

前回まで作ってた GitLab と Jenkins の連携方法のメモ。GitLab に push すると、そのプロジェクトをビルドしてメールでテスト結果を報告するようなサンプルを作る。

GitLab のリポジトリ作成

まずは CI まわしたいプロジェクトのリポジトリを作成する。このへんは普通の github とやりかたは変わらないので割愛する。今回は Node.js で mocha のテストプロジェクトをやってみたいので、「mocha-test」というプロジェクト名にした。

Jenkins の設定

Jenkins からそのプロジェクトを参照できるようにする。Jenkins は jenkins ユーザーで稼働しているため、そのままの設定だとリポジトリが見れない。GitLab 構築の際に apache ユーザーを admin にしたように、jenkins ユーザーも admin に設定する。まずは jenkins ユーザーの ssh key を生成する。

# sudo -H -u jenkins ssh-keygen -q -N '' -t rsa -f /var/lib/jenkins/.ssh/id_rsa

生成したキーを gitolite に読み込ませる。

# cd /home/git
# cp /var/lib/jenkins/.ssh/id_rsa.pub jenkins.pub
# chown git:git jenkins.pub
# chmod 444 jenkins.pub
# sudo -u git -H sh -c "PATH=/home/git/bin:$PATH; gitolite setup -pk /home/git/jenkins.pub"

ここまでがうまく行っていれば、/home/git/.ssh/authorized_keys に jenkins の行が追加されているはず。
そしてまだ admin 権限は設定されていないので、まだプロジェクトはクローン出来ない。
次は gitolite-admin の設定をする。

# cd /tmp
# sudo -u apache git clone git@localhost:gitolite-admin.git  # 前回までの記事で apache に admin権限を渡しているので、apache で clone する。他のユーザーに管理者権限を渡している場合はそのユーザーで実行すること。
# cd gitolite-admin/

この中の設定ファイルを編集
# vim conf/gitolite.conf

repo    gitolite-admin
  RW+                            = apache
repo    testing
  RW+                            = @all
repo    @all
  RW+                            = apache

こんな感じになっているものに、jenkins を追加。(多分repo @allに追加するだけでいいと思うけど、一応gitolite-adminにも追加)

repo    gitolite-admin
  RW+                            = apache jenkins
repo    testing
  RW+                            = @all
repo    @all
  RW+                            = apache jenkins

んで、変更をコミットする。

# git add conf/gitolite.conf
# git commit -m "add jenkins to admin user"
# sudo -u apache git push -u origin master
用がすんだら、clone したものを消しておく
# cd ../
# rm -rf gitolite-admin

これで jenkins ユーザーに管理者権限がついているはずなので、チェックする。

# cd /tmp
# sudo -u jenkins git clone git@localhost:gitolite-admin.git
もし localhost じゃなくて、ドメイン名をつけていたらそれでアクセスできるかをチェックすること。(known_hosts に追加する必要があるため)

成功したらディレクトリを消しておく
# rm -rf gitolite-admin

Jenkins の設定

Jenkins で CI したいジョブを作成する。

ホーム画面で新規ジョブ作成をクリック。

次にジョブ名を入力して、フリースタイル・プロジェクトのビルドを選択。今回ジョブ名は「mocha-test」とした。

ソースコード管理システムに Git を選択し、リポジトリの情報を入力する。

ビルドのトリガには「SCMのポーリング」を選択する。スケジュールにはなにも記入する必要はない。

ビルドするときに実行するシェルスクリプトを設定する。入力するシェルスクリプトは下記。

export PATH=/usr/local/bin:$PATH
npm install -d
$WORKSPACE/node_modules/mocha/bin/mocha --reporter tap > mocha-test-results.txt


ビルド処理後にメール通知したいので、E-mail通知の設定もしておく。
すべて記入が終わったら、一番下の「保存」または「適用」をクリックして保存する。

Git の Hook の設定

ここまで設定が完了したら、プロジェクトが空の状態でビルドが開始されるか確認する。具体的には、下記のリクエストを実行するとビルドが開始されるはず。

http://[Jenkins のホスト名]/jenkins/git/notifyCommit?url=git@localhost:mocha-test.git

パラメタの url は、上記で設定したGitのリポジトリと同じ値を入力すること。
ブラウザでも curl でも良いのでリクエストを実行した後に、Jenkins のページをリロードするとビルドが開始または実行が終了しているはず。そして設定したメールアドレスにもメールが届いているはずなので、ビルドが正常に実行されたことを確認しておく。(この時点ではビルドは実行はされるが失敗になるはず)



上記のコマンドが正常に動いているようであれば、このコマンドをGitLabのHookに登録する。

# cd /home/git/repositories/mocha-test.git/hooks
# rm post-receive  # デフォルトのものはシンボリックリンクなので削除
# cp /home/git/.gitolite/hooks/common/post-receive . # 元の実ファイルをコピーして編集
# vim post-receive

下記のように一行加える。

#!/usr/bin/env bash

# This file was placed here by GitLab. It makes sure that your pushed commits
# will be processed properly.

----------------ここの一行を加える----------------------
curl http://[Jenkinsのホスト名]/jenkins/git/notifyCommit?url=git@localhost:mocha-test.git
------------------------------------------------------

while read oldrev newrev ref
do
  # For every branch or tag that was pushed, create a Resque job in redis.
  pwd=`pwd`
  reponame=`basename "$pwd" | sed s/\.git$//`
  env redis-cli rpush "resque:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$reponame\",\"$oldrev\",\"$newrev\",\"$ref\",\"$GL_USER\"]}" > /dev/null 2>&1
done

んで、パーミッションを整える

# chmod 770 post-receive
# chown git:git post-receive

あとは git clone してチェックする。

挙動の確認

まずはローカルにプロジェクトをクローンする。

# git clone git@[Jenkins のホスト名]:mocha-test.git

前回の Node のテストを持ってくる。こんな感じのヤツ。

mochatest
 |- lib
 |    |- calc.js
 |
 |- test
 |    |- calc.test.js
 |
 |- package.json
# cd mocha-test
# mkdir lib
# mkdir test

それぞれのファイルを作成する。
# vim lib/calc.js

function add(x, y) {
  return x+y;
}

// このへんはおまじない
if (typeof exports !== 'undefined') {
  exports.add = add;
}

# vim test/calc.test.js

var calc = require('../lib/calc');
var assert = require("assert")

describe('calc', function() {
  describe('.add', function() {
    it('should return sum of 2 arguments', function() {
      var result = calc.add(1, 2);
      assert.equal(result, 3);
    });

    it('error', function() {
      var result = calc.add(1, 3);
      assert.equal(result, 3);
    });
  });
});

# vim package.json

{
  "name": "mocha-test",
  "version": "0.0.1",
  "devDependencies": {
    "mocha": "0.7.0"
  }
}

これで git push してJenkinsのビルドが動くかを確認する。

# git add .
# git commit -m "Initial commit"
# git push -u origin master

これで Jenkins のページをリロードして、ビルドが開始/完了していたら成功。新しくメールも着ているか確認する。
これだけだとちょっと気持ち悪いので、テストを変更してビルド成功するようにする。テストを書き換える。
# vim test/calc.test.js

13 行目
- assert.equal(result, 3);
+ assert.equal(result, 4);

んでコミット/プッシュ。

# git add test/*
# git commit -m "fix test to pass"
# git push -u origin master

これでまた push トリガーでビルドが走る。そして、テストがOKになってステータスが変わるはず。



とりあえずこんな感じ。