Posted at

Jenkins”だけ”で継続インテグレーションの真似事

More than 1 year has passed since last update.


はじめに

Jenkinsの継続的インテグレーション(CI:Continuous Integration)については、以下記事に書いた通り、外部ツールをふんだんに取り入れないとビルド/テスト/デプロイの自動化が難しいです。

それでも、「Jenkinsだけで無理やり継続的インテグレーションってのをやってみたい!」っていうのを、無知ながらもやってみた結果になります。


Jenkins”だけ”でほんとうにできること

https://qiita.com/Higemal/items/bb9a0c12b8fca0dd6657



やりたいこと

自動ビルド

↓ ビルドが問題なく通ったら

自動テスト

↓ テストが問題なく通ったら

自動デプロイ


もう少し細かく

①手動でプログラムのコーディング

②手動でテスト用プログラムのコーディング

③自動でプログラムのビルド

④自動でテスト用プログラムのビルド

⑤自動でテスト(テスト用プログラムの実行)

⑥自動で環境へのデプロイ

⑦継続インテグレーション実行確認


環境

Ubuntu 14.04.3

Java JDK 1.8

Jenkins 2.73.2

言語:Java

エディタ:vi


Ubuntu 14.04にjenkins 2.73.2をインストールする(OS上に直接)

https://qiita.com/Higemal/items/6b564cc10fbe2aeb5b17



いざ実践

・・・の前に、今回使用するディレクトリの説明です。

/develop/UT/java

──┬──────────────
 ├drwxrwxr-x source/    ←ソースコード置き場(プログラム)
 ├drwxrwxr-x testsource/ ←ソースコード置き場(テスト用プログラム)
 │
 ├drwxrwxrwx jenbin/    ←ビルド確認用バイナリ置き場(プログラム)
 ├drwxrwxrwx jentestbin/  ←ビルド確認用バイナリ置き場(テスト用プログラム)
 │
 ├drwxrwxrwx bin/      ←デプロイ先ディレクトリ(プログラム)
 └drwxrwxrwx testbin/    ←デプロイ先ディレクトリ(テスト用プログラム)

#下4つのディレクトリは「jenkins」というJenkinsのユーザが触るため、パーミッションは777にしておきます。


①手動でプログラムのコーディング

プログラムの引数を足し算するだけのソースを作りました。

エラーハンドリング等してないのはスキル不足ご愛嬌。

/develop/UT/java/source/Plus2args.java


Plus2args.java

//  Plus2args

public class Plus2args {
public static void main (String[] args){
add(args);
}

public static void add(final String[] args) {
int number;
number = Integer.parseInt(args[0]) + Integer.parseInt(args[1]);
System.out.println(number);
System.exit(0);
}
}
// EOL



②手動でテスト用プログラムのコーディング

とりあえず正常終了を確認するだけの以下ソースを作りました。

出力値確認すらしてないのは技術力の限界ご愛嬌。

/develop/UT/java/testsource/UT_Plus2args.java


UT_Plus2args.java

// UT_Plus2args.java

import java.util.*;
import java.io.*;

public class UT_Plus2args {
public static void main (String[] args) {
Test_Normal();
System.exit(0);
}

public static void Test_Normal() {
         //ビルド確認用ディレクトリ内のクラスファイルを実行するコマンド文字列
String command = "java /develop/UT/java/jenbin/Plus2args 6 9";
Runtime runtime = Runtime.getRuntime();
try {
//クラスファイルの実行、および実行完了まで待機
Process process = runtime.exec(command);
int exitValue = process.waitFor();
}

catch(IOException e) {
System.out.println("Test_Normal execuing error. IOException.");
System.exit(1);
}
catch(InterruptedException e) {
System.out.println("Test_Normal execuing error. InterruptedException.");
System.exit(1);
}

finally{
}
//正常終了確認用メッセージ
System.out.println("Test_Normal executed.");
}
}

// EOL



③自動でプログラムのビルド

ようやっとJenkinsの登場です。以下を設定しようと思います。

 ・ジョブ名は 20171111_Build_Plus2args

 ・毎日13時05分にビルドを実行する

 ・ソースプログラムをコンパイルしてビルド確認用ディレクトリに置く

まず左上の「新規ジョブの作成」

image.png

「Enter an item name」にジョブ名を設定して、「フリースタイル・プロジェクトのビルド」を選択して「OK」

image.png

設定画面に移ります。説明等をここに書くことができます。

image.png

ビルドトリガで「定期的に実行」を選び、「5 13 * * *」を設定して実行時間を固定します。

image.png

ビルドで「シェルの実行」を選び、以下コマンドを設定して、ビルドしたらビルド確認用バイナリ置き場にクラスファイルを出力するようにします。

javac /develop/UT/java/source/Plus2args.java -d /develop/UT/java/jenbin

image.png

保存ボタンで確定すると、ジョブの詳細画面になります。(スクショはすでにだいぶ触った後なのでビルド履歴がおかしいことになってますが)

image.png

#ちなみに、今作ったジョブをすぐ実行したい場合は、左側の「ビルド実行」で即時実行できます。実行後、ビルド履歴に実行結果が出力されます。してみた結果がこちら。↓

image.png

↓ビルド履歴の「コンソール出力」を選択するとその結果が出ます。

image.png


④自動でテスト用プログラムのビルド

Jenkins設定の説明が入ったのでちょっと本筋からずれましたが、テスト用プログラムについても同様にJenkinsジョブ設定で自動化します。

今回は以下を設定しようと思います。先ほどと同じように新規ジョブを作成します。

 ・ジョブ名は 20171111_Build_UT_Plus2args

 ・ソースプログラムのビルドに成功したら、ビルドを実行する

 ・テスト用ソースプログラムをコンパイルしてビルド確認用ディレクトリに置く

ビルドトリガで「他プロジェクトの後にビルド」を選び、対象プロジェクトに「20171111_Build_Plus2args」を設定して、ジョブ連携を実現します。

image.png

ビルドは「シェルの実行」を選び、以下コマンドを設定して、ビルドしたらビルド確認用バイナリ置き場にクラスファイルを出力するようにします。さっきとほぼ同じ。

javac /develop/UT/java/testsource/UT_Plus2args.java -d /develop/UT/java/jentestbin

image.png

#ちなみに、ソースファイルを少し壊してビルドを実行すると、ビルド実行結果が赤くなり、コンソール画面からエラー内容の確認ができます。

image.png

image.png


⑤自動でテスト(テスト用プログラムの実行)

テスト用のジョブを設定します。

 ・ジョブ名は 20171111_UnitTest_Plus2args

 ・テスト用ソースプログラムのビルドに成功したら、テストを実行する

 ・テスト成功はテスト用クラスファイル実行の正常終了と定義する

新規ジョブを作成。

ビルドトリガは「他プロジェクトの後にビルド」、対象プロジェクトに「20171111_Build_UT_Plus2args」を設定。

ビルドは「シェルの実行」を選び、以下コマンドを設定。テスト用クラスファイルを実行します。

java -cp /develop/UT/java/jentestbin UT_Plus2args

#設定画面は省略します。

#即時実行し、成功したジョブ結果のコンソール出力です。

image.png


⑥自動で環境へのデプロイ

最後のジョブ、デプロイ用のジョブを設定します。

 ・ジョブ名は 20171111_DeployUT_Plus2args

 ・テスト用クラスファイルの実行に成功したら、デプロイを実行する

新規ジョブを作成。

ビルドトリガは「他プロジェクトの後にビルド」、対象プロジェクトに「20171111_UnitTest_Plus2args」を設定。

ビルドは「シェルの実行」を選び、以下コマンドを設定。ソースファイルをコンパイルして、デプロイ先ディレクトリに生成したクラスファイルを置きます。

javac /develop/UT/java/source/Plus2args.java -d /develop/UT/java/bin

javac /develop/UT/java/testsource/UT_Plus2args.java -d /develop/UT/java/testbin

#設定画面は省略します。

#即時実行し、成功したジョブ結果のコンソール出力です。

image.png


#ちょっとここで流れのおさらい(ジョブ連携)


↓定時起動(毎日13:05)

20171111_Build_Plus2args プログラムのビルド

↓ジョブ正常終了

20171111_Build_UT_Plus2args テスト用プログラムのビルド

↓ジョブ正常終了

20171111_UnitTest_Plus2args テスト(テスト用プログラムの実行)

↓ジョブ正常終了

20171111_DeployUT_Plus2args 環境へのデプロイ



⑦継続インテグレーション実行確認

最後にビルド、テスト、デプロイの自動連携実行(≒継続的インテグレーション)を確認します。

最初のトリガとなるプログラムビルドは即時実行で投入します。

プログラムビルドのジョブを即時実行。

image.png

ビルド履歴を確認。うまくいっていってるっぽい。

image.png

ビルドジョブのコンソール画面。正常終了できている。

image.png

テスト用プログラムのビルドジョブのコンソール画面。正常終了できている。

image.png

テストジョブのコンソール画面。正常終了できている。

image.png

デプロイジョブのコンソール画面。正常終了できている。

image.png

ファイル確認。各ジョブの正常終了時間にてファイルが作成されている。

batchuser@ubnt14-gn01:/develop/UT/java$ ll ./jenbin/Plus2args.class

-rw-r--r-- 1 jenkins jenkins 562 11月 16 23:18 ./jenbin/Plus2args.class

batchuser@ubnt14-gn01:/develop/UT/java$ ll ./jentestbin/UT_Plus2args.class
-rw-r--r-- 1 jenkins jenkins 1196 11月 16 23:18 ./jentestbin/UT_Plus2args.class

batchuser@ubnt14-gn01:/develop/UT/java$ ll ./bin/Plus2args.class
-rw-r--r-- 1 jenkins jenkins 562 11月 16 23:19 ./bin/Plus2args.class

batchuser@ubnt14-gn01:/develop/UT/java$ ll ./testbin/UT_Plus2args.class
-rw-r--r-- 1 jenkins jenkins 1196 11月 16 23:19 ./testbin/UT_Plus2args.class

クラスファイル実行確認。ちゃんと動いている。

#エラーハンドリングしていない部分はもちろんエラー停止する。

batchuser@ubnt14-gn01:/develop/UT/java$ java -cp  ./bin Plus2args 10 21

31

batchuser@ubnt14-gn01:/develop/UT/java$ java -cp ./bin Plus2args
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Plus2args.add(Plus2args.java:10)
at Plus2args.main(Plus2args.java:5)


うまくいきました!

ということで、むりくり継続的インテグレーションっぽいことをやってみました。色んな意味でこのレベルが最低限かなと思います(特にコーディングスキルが)

今後は外部ツールを絡ませがら、よりリッチな継続的インテグレーションを試していきます。


参考

Jenkins実践入門

http://gihyo.jp/book/2011/978-4-7741-4891-5

Ubuntu 14.04にjenkins 2.73.2をインストールする(OS上に直接)

https://qiita.com/Higemal/items/6b564cc10fbe2aeb5b17

Jenkins”だけ”でほんとうにできること

https://qiita.com/Higemal/items/bb9a0c12b8fca0dd6657