3分でPerlのプロジェクトをJenkins Readyにする

こんばんは、着る毛布が届く前に風邪を引いたdannです。

色々な環境やプロジェクトに携わっていて、その度にJenkinsのセットアップやPerlプロジェクト用のモジュールのインストールなどをしていたりしませんか。また、プロジェクトを作るたびに、Job毎にプラグインの設定などを繰り返していたりしませんか?

これらの設定は、完全に自動化することが可能です。Jenkinsのように良く使うツールは、これらのセットアップも自動化していくと捗ります。以下では、その方法を説明します。

以下に、Jenkinsプロジェクトの開始に必要なテンプレートを用意したので、参考にしてみてください。以下では、以下のtemplateを使ったセットアップ方法について説明します。
https://github.com/dann/perl-jenkins-template

Jenkinsのプロジェクトに必要なPluginのセットアップの自動化

Jenkinsでは、GUIだけでなく、jenkins-cliを使うことでCUIでインストールすることができます。
これを使って以下のようなスクリプトで、JenkinsのPluginとJenkinsの統合に必要なPerlのモジュールをインストールします。
これによって、プロジェクトに必要なプラグインPerlのモジュールは自動でインストールできます。

https://github.com/dann/perl-jenkins-template/blob/master/setup_jenkins_modules.sh

#!/bin/bash

#==================================
# Configuration
#==================================
HOSTNAME=localhost
PORT=8080

#==================================
# Main
#==================================
JENKINS_PLUGINS=(
git
checkstyle
htmlpublisher
clover
plot
)

PERL_MODULES=(
Devel::Cover
Devel::Cover::Report::Clover
Perl::Metrics::Lite
https://github.com/dann/tap-to-junit-xml/tarball/master
)

setup() {
    fetch_jenkins_cli
    install_jenkins_plugins
    install_jenkins_related_perl_modules
    restart_jenkins
    clean_jenkins_cli
}

fetch_jenkins_cli() {
    curl -LO http://${HOSTNAME}:${PORT}/jnlpJars/jenkins-cli.jar
}

jenkins_cli() {
    java -jar jenkins-cli.jar -s http://${HOSTNAME}:${PORT} $@
}

install_jenkins_plugins() {
    for plugin in ${JENKINS_PLUGINS[@]}
    do
        jenkins_cli install-plugin ${plugin}
    done
}

install_jenkins_related_perl_modules() {
    for module in ${PERL_MODULES[@]}
    do
        cpanm $module
    done
}

restart_jenkins() {
   jenkins_cli safe-restart
}

clean_jenkins_cli() {
    rm jenkins-cli.jar
}

setup

Jenkinsのproject-templateを用意しておくと捗るぞ

概要

多くののLLのプロジェクトの場合は、シェルのステップを設定しているか、実行するためのbuild.xmlを用意しておいて、ビルドのステップのセットアップをして使っているかなんじゃないかと思います。こういったプロジェクトのステップの設定やどのプラグインを使うか、プラグインの設定など、そういったプロジェクトの設定を手動でするのって面倒ですよね。

要するに既存Job設定をコピーすることで、既存の設定を使い回せる機能があるので、それを使うということですね。

これによって、Clover用のプラグインディレクトリでcover_dbのディレクトリを指定したり、Devel CoverのHTMLの結果をHTML Publisherなどでpublishするディレクトリを指定したり、Publish Checkstyle analysis resultsなどの実行するプラグインをチェックしたりといったのを手動ですること無く、自動で設定された状態にすることが可能になります。

Job Templateのインストールの仕方

以下の定義が実際のjobのテンプレートになります。以下に、上記のビルドステップのスクリプトとプロジェクトで必要となるプラグインの設定が有効になるjobテンプレートを用意しておきました。Job定義はXMLでJenkinsのHomeディレクトリ(ex /var/lib/jenkins)以下のjobsディレクトリに保存されているので、既存Jobでよく使う部分はテンプレートのXMLとして定義して保存しておきます。
https://github.com/dann/perl-jenkins-template/blob/master/config.xml

上記のテンプレートを自動インストールするスクリプトは、以下になります。Configセクションの変数を各自の環境にあわせて使ってみてください。
https://github.com/dann/perl-jenkins-template/blob/master/setup_jenkins_job_template.sh

Job Templateの使い方

上記のインストールが終わった後に、新規プロジェクトを作ります。新規プロジェクトを作る場合には、Jenkinsで、New Job -> Copy existing job を選択し、そこで、perl-jenkins-templateを選択することで、jenkins readyなperlプロジェクト用のJobを作ることができます。

Jobテンプレートの適用になり有効になるもの

上記のJob templateをインストールすると、以下のものがデフォルトで有効になります。

  • JUnitとの統合によるテスト実行結果
  • Cloverの統合によるテストカバレッジの可視化
  • Devel::CoverのHTMLレポート
  • Perl::Metrics::LiteによるCheckStyleとの統合

ビルドの結果としては、以下のような形で表示されます。

このJob Templateによって、プラグインだと次のようにCheckStyle, Clover, JUnitなどのプラグインの設定がされます。

また、ステップについては、以下のような設定が自動設定されます。

set -ex

#===============================================
# Configuration
#===============================================
export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:${PATH}"                                                      
export LOG_DIR=$WORKSPACE/logs
export PERL5LIB="$WORKSPACE/lib:$WORKSPACE/t/lib:$WORKSPACE/t/*/lib:${PERL5LIB}"
export PERL_TEST_HARNET_DUMP_TAP=$LOG_DIR
export TEST_VERBOSE=1

#===============================================
# Main
#===============================================
clean() {
    [ -f Makefile ] && make -k realclean
    rm -rf Makefile Makfile.old MANIFEST blib *.tar.gz
    rm -rf $LOG_DIR
    cover -delete
}

setup() {
    perl Makefile.PL
    mkdir -p $LOG_DIR
}
do_test() {
    HARNESS_PERL_SWITCHES=-MDevel::Cover=+ignore,inc prove -lv t 2>&1 | tee -a $LOG_DIR/tests.tap
}

convert_to_junit_xml() {
    tap-to-junit-xml --input=$LOG_DIR/tests.tap --output=$LOG_DIR/tests.xml
}

make_coverage() {
    cover -report clover
    cover
}

measure_metrics() {
    measureperl-checkstyle --max_sub_lines 60 --max_sub_mccabe_complexity 10 --directory lib > checkstyle-result.xml
}

main() {
    clean
    setup
    do_test
    convert_to_junit_xml
    make_coverage
    measure_metrics
}

main

まとめ

まとめると、

  • JenkinsのPluginやプロジェクトに必要なモジュールのインストールを自動化しておくと捗るぞ
  • JenkinsのJobでプロジェクトに共通な設定は、あらかじめJob定義のXMLをテンプレートを用意しておき、Copy existing Jobでコピーすると設定を使い回せて捗るぞ

ということになります。

使うプラグインや設定など、プロジェクトによって異なる点もあると思いますが、このようなベースを用意しておくことで、いわゆる定型作業を減らすことができ、プロジェクト間でのばらつきを抑えることが可能になります。是非、このようなテンプレートをベースにして、各自のプロジェクトに合わせたJenkinsのJobテンプレートを作ってもらえたらなと思います。

これらは、Perlのプロジェクトだけで使える話ではなく、他の言語でも使える話ですので、是非自動化して、プロジェクトレベルでの標準化と自動化を進めてみてください。

Enjoy automating!