今回のエントリーは、sample_app というRails4アプリケーションを使ってJenkinsで継続的インテグレーションをおこなうまでの設定備忘録です。
CI(継続的インテグレーション)とは、コンパイル、ビルド、テスト、デプロイなどを繰り返し行ってコードの品質改善や納期短縮を目指す開発手法です。そして、JenkinsはCIのジョブを定期的に実行し、実行結果をフィードバックしてくれる便利なツールなのです。
Jenkinsは、Git等のバージョン管理の最新コミットを定期的にポーリングして、更新を検知したタイミングでジョブを実行する等が可能です。
JenkinsはJavaアプリケーションなので、Javaをインストールしておく必要があります。
注意点としては、GNU Compiler for Java(GCJ)のjavaがインストールされている場合はjenkinsが正しく起動しません。GNU Compiler for Java(GCJ)のjavaはyumで"java"とだけ指定した場合にインストールされる可能性があります。
yum install -y java-1.6.0-openjdk
javaバージョン情報が以下のように表示されればOKです。
# java -version
java version "1.6.0_30"
OpenJDK Runtime Environment (IcedTea6 1.13.1) (rhel-3.1.13.1.el6_5-x86_64)
OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode)
wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
yum install -y jenkins
jenkinsをインストールして作成されるファイルやディレクトリを説明します。
File | Description |
---|---|
/etc/init.d/jenkins | 起動スクリプト |
/etc/logrotate.d/jenkins | log rotate設定ファイル |
/etc/sysconfig/jenkins | Jenkins設定ファイル |
/etc/yum.repos.d/jenkins.repo | jenkinsパッケージのレポジトリ設定 |
/usr/lib/jenkins/jenkins.war | Jenkins本体。Jenkinsアップデートはこのファイルを置き換えることになる |
/usr/sbin/rcjenkins | SUSEディストリビューション用の起動スクリプト |
/var/cache/jenkins | 『/var/cache/jenkins/war』がドキュメントルートディレクトリ |
/var/lib/jenkins | jenkinsユーザのホームディレクトリ |
/var/log/jenkins | ログディレクトリ |
上記情報は、CentOS6.5-x86_64上の『jenkins-1.560-1.1』での情報です。
Jenkinsはデフォルト設定のままでも動作させることが可能です。
service jenkins start
jenkinsがリッスンするポートの中で、『8080』がHTTPポート、『8009』がApache JServ Protocol version 1.3プロトコルを使用する場合のJenkinsのリッスンポートとなります。
# netstat -antp | grep $(cat /var/run/jenkins.pid )
tcp 0 0 :::8080 :::* LISTEN 16044/java
tcp 0 0 :::35291 :::* LISTEN 16044/java
tcp 0 0 :::41662 :::* LISTEN 16044/java
tcp 0 0 :::8009 :::* LISTEN 16044/java
デフォルト設定のまま起動しているのでポート番号『8080』へアクセスします。
http:// <IPアドレス> :8080/
以下がトップページの画面です。
ブラウザからアクセスしたいURLでApacheにアクセスがあった場合に、8080ポートへプロキシするように設定します。また、不特定多数の人にアクセスさせないために最低限の対応としてBASIC認証をかけます。
ポイントは、プロキシ先を8080ポートにすることで/etc/sysconfig/jenkinsには一切手を加えていません。
<VirtualHost *:80>
ServerName jenkins.example.info
ProxyPass / http://jenkins.example.info:8080/ nocanon
ProxyPassReverse / http://jenkins.example.info:8080/
ProxyRequests Off
AllowEncodedSlashes Off
<Proxy http://jenkins.example.info:8080/>
Order deny,allow
Allow from all
</Proxy>
<Location)
AuthType Basic
AuthName "basic auth"
AuthUserFile /etc/httpd/conf.d/jenkins_htpasswd
Require user jenkins
</Location>
</VirtualHost>
configtestを実行してエラーが出なければApacheを再起動します。
# service httpd configtest
Syntax OK
# service httpd restart
httpd を停止中: [ OK ]
httpd を起動中: [ OK ]
設定したURL http://jenkins.example.info/
へアクセスするとJenkinsのページが表示されるはず!
http://jenkins.example.info/
Jenkins Webページへアクセスできるようになったところで、必要なプラグインをインストールします。
今回、インストールするプラグインです。
Plugin | Description |
---|---|
Git Plugin | JenkinsがGitを扱えるようにする |
Rake plugin | タスクでrakeを実行可能にする |
rbenv plugin | ジョブをrbenv環境で実行可能にする |
Ruby metrics plugin | SimpleCov(RCov)で生成したHTMLをJenkinsがパースすることを可能にする |
[ TOP ] > [ Jenkinsの管理 ] > [ プラグインの管理 ] > [ 利用可能 ]タブ
で必要なプラグイン横のチェックボックスにチェックを入れて、ダウンロードして再起動後にインストール
をクリックします。
すると画面が変わってインストール状況が表示されます。
インストール完了後、ジョブがなければJenkinsを再起動するチェックボックスにチェックを入れると再起動プロセスに移行します。
再起動プロセス中にブラウザで Service Temporarily Unavailable
エラーが表示されることがありますが、apacheを再起動してあげるとします。
ちなみに、プラグインがインストールされたかどうかを確認するには、Jenkinsダッシュボードから確認するか、/var/lib/jenkins/pluginsディレクトリ以下を確認することになります。
Jenkinsダッシュボードから確認するには、 [ TOP ] > [ Jenkinsの管理 ] > [ プラグインの管理 ] > [ インストール済み ]タブ
を開きます。
または、Jenkinsサーバの/var/lib/jenkins/pluginsディレクトリ以下にプラグイン名のディレクトリが作られてますので、確認します。
# ls -ld /var/lib/jenkins/plugins/{git,rake,rbenv,rubyMetrics}
drwxr-xr-x 5 jenkins jenkins 4096 4月 16 01:23 2014 /var/lib/jenkins/plugins/git
drwxr-xr-x 4 jenkins jenkins 4096 4月 16 01:23 2014 /var/lib/jenkins/plugins/rake
drwxr-xr-x 4 jenkins jenkins 4096 4月 16 01:23 2014 /var/lib/jenkins/plugins/rbenv
drwxr-xr-x 7 jenkins jenkins 4096 4月 16 01:23 2014 /var/lib/jenkins/plugins/rubyMetrics
今回はジョブ作成のソースコード管理にてGitを選ぶのでSSH鍵を登録する必要があります。
Jenkinsでは、SSH鍵登録は認証情報の管理というページで設定し、ジョブを作成する際には登録したSSH鍵の名称欄に設定した名前をプルタブから選ぶという手順になります。
Jenkinsをインストールするとjenkinsユーザが作成されます。
まず、sudoで変身ユーザにjenkinsユーザを指定してSSH鍵を生成します。ここではパスワード文字列に空文字を指定します。
sudo -u jenkins -H ssh-keygen -t rsa -N ''
これで/var/lib/jenkins/.sshディレクトリにid_rsaとid_rsa.pubが作成されました。
# ls -l /var/lib/jenkins/.ssh/id_rsa*
-rw------- 1 jenkins jenkins 1675 4月 21 20:25 2014 /var/lib/jenkins/.ssh/id_rsa
-rw-r--r-- 1 jenkins jenkins 413 4月 21 20:25 2014 /var/lib/jenkins/.ssh/id_rsa.pub
生成された/var/lib/jenkins/.ssh/id_rsa.pubの内容をBitbucket等のgitレポジトリホスティングサービスのSSH鍵として登録しましょう。ここは利用するサービスによって手順は異なるので詳細は割愛しますが、GithubとBitbucketの場合は以下のようなURLだと思います。
Bitbucketの場合: https://bitbucket.org/account/user/< ユーザ名 >/ssh-keys/
Githubの場合: https://github.com/settings/ssh
では、Jenkins上に使いたいSSH鍵を登録します。
[トップ] > [Jenkinsの管理] > [認証情報の管理]へ移動します。
Item | Value |
---|---|
認証情報 | SSHユーザ名と秘密鍵 |
スコープ | グローバル |
ユーザ名 | jenkins |
説明 | ssh authentication user |
秘密鍵 | Jenkinsマスター上の~/.sshから |
最後に[ 保存 ]をクリックすれば完了です。
このエントリーでおさえておきたいポイントは3点です。
1点目の注意点としては、本項の設定を行わなかった場合、rakeコマンドパスが/usr/bin/rakeとなってしまうという点です。
後述するジョブ登録でInvoke Rakeという設定項目でrakeタスクを指定しますが、デフォルトではRake Versionが(Default)しか指定できません。(Default)を指定した場合、rakeコマンドパスが/usr/bin/rakeとなってしまいます。
2点目の注意点としては、本項で設定するパス情報についてはrbenv pluginの設定に合わせておく必要があるということです。
このエントリーを書くのにあたり、使用するサンプルアプリケーション『sample_app』はrbenvで管理するruby-2.1.0で動作させることを前提とし、前項でrbenv pluginもインストール済みです。
後述するジョブ登録でrbenv build wrapperというチェックボックスにチェックを入れることで、Jenkinsユーザの実行するrubyをrbenvでインストールすることが可能になります。この時、rakeコマンドパスは/var/lib/jenkins/.rbenv/shims/rakeであり、ruby-2.1.0をインストールした時のRUBY_HOMEは/var/lib/jenkins/.rbenv/versions/2.1.0となります。
[Jenkinsの管理] > [システムの設定] > [Rake]にてJenkinsのビルドで使用するrakeコマンドパスを指定します。
ここで3点目の注意点ですが、Rvm installation pathという設定項目はrakeコマンドパス(ここでは/var/lib/jenkins/.rbenv/shims/rake)を指定する箇所です。
Item | Value |
---|---|
Rvm installation path | /var/lib/jenkins/.rbenv/shims/rake |
Ruby installation - name | ruby-2.1.0 |
Ruby installation - RUBY_HOME | /var/lib/jenkins/.rbenv/versions/2.1.0 |
今の段階ではRUBY_HOMEパスは存在しない(ジョブでrbenvがインストールされる)ので/var/lib/jenkins/.rbenv/versions/2.1.0 is not a directoryという赤字のメッセージが画面に表示されますが、気にせずに[ 保存 ]をクリックします。
これでRake Pluginの設定は終わりです。
本項は既にRSpecテストを書いている場合は不要です。
Gemfileに以下の設定を記述します。
group :test, :development do
gem "rspec"
gem "rspec-rails"
end
gemモジュールをインストールします。
bundle install
rails generate rspec:install
rails generate rspec:model entry
spec/models/entry_spec.rb にフィクスチャファイルのデータを読んでテーブルに保存するテストを書く。
require 'spec_helper'
describe Entry do
fixtures :entries
it { Entry.new.should be_a_new( Entry ) }
end
spec/fixtures/entries.yml
にYAML形式でフィクスチャデータを記述する。
test_01:
title: 'test'
body: 'test'
rails generate rspec:controller entries
spec/controllers/entries_controller_spec.rb
にindexアクションにアクセスして結果を返すテストを記述する。
require 'spec_helper'
describe CuratesController do
describe "GET index" do
before do
get :index
end
it do
response.should be_success
end
end
end
Jenkinsでソースコードのテストを行うジョブを登録します。
[ TOP ] > [ 新規ジョブ作成 ]をクリックします。
ジョブの名前を入力し、ジョブのタイプを選択します。
今回のようにgitなどのレポジトリを監視し、トリガータイミングを設定してビルド・テストを実行する場合はフリースタイル・プロジェクトのビルドチェックボックスにチェックを入れてOKを押します。
詳細ページにて設定します。
Item | Value |
---|---|
プロジェクト名 | sample_app |
古いビルドの破棄 - ビルドの保存日数 | 5 |
古いビルドの破棄 - ビルドの保存最大数 | 5 |
ソースコード管理 | Git |
Repository URL | git@bitbucket.org:<ユーザ名>/sample_app.git |
Credentials | jenkins(ssh authentication user) |
リポジトリ・ブラウザ | bitbucketweb |
URL | https://bitbucket.org/<ユーザ名>/sample_app |
ビルド・トリガ | SCMをポーリング |
スケジュール | H/5 * * * * |
ビルド環境 | rbenv build wrapper |
The Ruby version | 2.1.0 |
Ignore local version | checked |
ビルド - シェルの実行 | export PATH="/var/lib/jenkins/.rbenv/bin:$PATH" eval "$(rbenv init -)" bundle install |
ビルド | Invoke Rake |
Rake Version | ruby-2.1.0 |
Tasks | db:setup |
ビルド | Invoke Rake |
Rake Version | ruby-2.1.0 |
Tasks | spec |
ビルド後の処理 | E-mail通知 |
宛先 | sample@sample.com |
以上を設定し、[ 保存 ]をクリックします。
[ トップ ] > [ sample_app ] > [ ビルド実行 ] をクリックします。
暫くするとプロジェクトページトップの左下にあるビルド履歴という欄に実行履歴が表示されます。今回が初回だったので#1となっています。
上記イメージの例でいうと、#1 2014/04/26 13:23:00という文字にマウスカーソルをあわせると右側に▼印が表示されます。▼をクリックし、コンソール出力を選択するとJenkinsがジョブで実行したコマンド結果を確認することが出来ます。テストが失敗する場合などはコンソール出力を確認することで原因特定に繋げることも可能です。
Perl |
3
|
Linux |
16
|
Jenkins |
1
|
CI |
1
|
Bashシェル |
1
|
シェルスクリプト |
1
|
Munin |
7
|
Ruby on Rails |
7
|
plenv |
1
|
sudo |
2
|
Cobbler |
6
|
ruby |
1
|
rbenv |
1
|
WeeChat |
1
|
tmux |
2
|
Webistrano |
1
|
capistrano |
1
|
puppet |
8
|
growthforecast |
1
|
Supervisor |
1
|
perlbrew |
1
|
git |
2
|
Python |
1
|
pip |
1
|
PHP |
1
|
Nginx |
1
|
MySQL |
2
|
LXC |
2
|
RPM |
3
|
ImageMagick |
1
|
Subversion |
1
|
qmail |
3
|
yum |
1
|
ucspi-tcp |
1
|
daemontools |
1
|
Puppet |
1
|
IPVS |
1
|
Kickstart |
1
|
aaa |
0
|