2017年2月27日月曜日

[CI][Wercker] Workflows を利用してテストのパラメタライズと並列化をしてみた

安定運用していたので、あまり見ていなかった Wercker から、もう non-Docker なやつはやめるから移行してやーってメール来たので、見てみたら Workflows という新機能が実装されていたので、ついでにその機能を使った CI に変えました。

Workflow についてはこちらを参照してください。
Manage complex CI/CD automation scenarios with Workflows

必要こととしては、wercker.yml にパイプライン処理を追加するのと、
Wercker のページ上で Pipelines と Workflows を構築する2点です。

パイプライン処理の作成(YAML)
wercker.yml の方はドキュメントとかを参考にこのように変更しました。(ちょっと長いです)

定義したパイプラインは2つで、wandbox と nothing です。
wandbox は iuwandbox を使用してテストコードを Wandbox に投げつけテストします。
CI サービス + Wandbox は以前にこのブログで紹介したので、そちらを参照してください。
ブログズミ: Shippable + Wandbox で C++ の CI 環境構築

wandbox パイプラインのポイントとして compiler と --std オプションを環境変数にしているところです。(IUWANDBOX_COMPILER と IUWANDBOX_CPPVER)
後述しますが、Wercker ではパイプラインごとに環境変数を設定できます
パイプラインは、YAML に書いたパイプライン処理と環境変数等のセットで、1つになります。
つまり、パラメータを環境変数にしておくことで、YAML の定義1つで、複数のパイプラインを作ることができるのです。

また、ワークフローのジョイント用に何もしない nothing パイプラインも用意しました。

wercker.yml の設定は以上です。
パイプライン・ワークフローの作成
続いて、Web 上でワークフローを作っていきます。
プロジェクトの設定ページを開いたら、「Workflows」があるのでそこを開きます。
Editor の下にフローっぽいのがありますが、まずはさらに下にある「Pipelines」でパイプラインを作っていきます。


「Add new pipeline」を押すと、以下のようなページが開くので、任意のパイプライン名と YAML に定義したパイプライン処理の名前を記入します。
「Hook Type」には、「Default(パイプライン連結)」と「Git Push」がありますので、用途に合わせて選択してください。今回はパイプラインを連結していくので、「Default」を選択しました。


「Create」ボタンを押すと設定ページが開きます。
ここで環境変数などが設定できます。(今回は IUWANDBOX_COMPILER と IUWANDBOX_CPPVER を設定)


これで1つ目のパイプラインができました。
あとは、同じことを環境変数を変えつつ必要なパターン分だけ用意します。
(これ結構めんどくさいんですけどね…)



パイプラインができたら、最後に Workflows です。
Workflows のページに戻ってきたら、Editor のところにあった + アイコンをクリックします。
下の画像のように、ブランチフィルターとパイプラインを選択するポップアップがでてくるので、選んで「Add」を押します。


あとは、同様に + をクリックして好きなように連結していきましょう。


以下は現時点(2017/2)での挙動における注意点

※ 1つのパイプラインを複数使用することはできません
※ 分岐したパイプラインを Join することはできません
※ パイプラインは40個以上作れるのですが、パイプライン追加のリストに入らいないため実質40個が上限になっています。

実行結果


最後に
パラメタライズドな感じでパイプラインを定義して自由にフローを組み立てられるのは非常に便利だなと思いました。(Jenkins もこんな感じにできないのかなぁ)

あとは Join ができるとすごく嬉しいですが、なくてもすごく便利に使えると思うのでオススメです!
今回は以上です。
では。

2017年2月21日火曜日

[雑記][Jenkins] Cppcheck Plugin のパイプライン対応がもうすぐ来そうな予感

こんにちは。
先日某所であった勉強会(?)で Jenkins おじさんたちと Jenkins なお話を久しぶりにしたので、滞ってた自宅 Jenkins のパイプライン化対応を再開しようかなと思ってます。

で、Cppcheck のパイプライン対応しようと思ったら、まだ対応してなくて保留していたのも思い出しました。

プラグインの対応状況
Plugin Compatibility with Pipeline : https://github.com/jenkinsci/pipeline-plugin/blob/master/COMPATIBILITY.md
こちらに主要な?プラグインの対応状況が載っています。
画像は2016年9月のときのものですが、現在もまだチェックがありませんでした。


しかし、issue を見てみると、もうすぐ更新ありそうな気配がしてました。
[JENKINS-35096] Add support for Jenkins Pipeline to the cppcheck-plugin - Jenkins JIRA

早く使えるようになってほしいですね!

※ 実は対応してないプラグインを頑張って使う方法を調べようとしてたんですが、https://github.com/jenkinsci/pipeline-plugin/blob/master/COMPATIBILITY.md を今見たらほぼほぼ対応してるっぽいので、待ちスタンスに切り替えました。

2017年2月17日金曜日

[Jenkins][Cppcheck] ソースファイルの文字化けを解消する

Windows 上で Jenkins を実行していると、エンコードが MS932 になっていることがほとんどだと思います。


この状態で Cppcheck Result から UTF-8 のソースコードを表示すると、日本語が文字化けしてしまいます。


この問題について質問を受け、対策を考えてみたのでまとめておきます。

Jenkins の文字コードを変更する方法
まず真っ先に出て来る方法は、エンコードを UTF-8 にする方法です。


対応はとても簡単です。
-Dfile.encoding=UTF-8 を Jenkins 起動引数に追加するだけで OK です。
java -Dfile.encoding=UTF-8 -jar jenkins.war --sessionTimeout=1440
サービスにインストールしている場合は、Jenkins.xml の <arguments> に追加してください。

Jenkins を再起動して見てみるとこのように日本語が正しく表示されるようになります。


問題点
ただし、この方法には問題点もあります。
Windows バッチ処理は通常 cp932 (sjis)なので、システムを UTF-8 にしてしまうと、バッチ出力が今度は文字化けしてしまいます。
そこで、バッチ処理の最初に「chcp 65001」する必要が出てきます。
chcp 65001 ナシとアリ、それぞれの結果が以下になります。




ただ、毎度毎度 chcp するのも面倒ですよね。
なので、別の方法も考えてみます。

Warnings Plugin を使って集計する
Cppcheck Plugin ではなく Warnings Plugin を使う方法です。
Warnings Plugin では設定にエンコーディング指定がありますので、こちらを設定すればシステムのエンコーディングと異なっていても大丈です。


Cppcheck の結果を Warnings Plugin で集計は3つのステップで対応します。

Cppcheck の出力カスタマイズ
Warnings Plugin で Cppcheck の結果を集計するために、まず Cppcheck の出力をカスタマイズします。
(デフォルトだと出力されない情報もあるので)
今回は以下のようにしてみました。
--template="{file}:{line}: {severity}: {id}: {message}"
(.+?):(\d+): (information|portability|performance|style|warning|.*error): (.+?): (.*)$


Warnings Plugin にパーサーを追加
続いて、Cppcheck の出力をパースするルールを追加します。
「Jenkins の管理」「システムの設定」の「コンパイラの警告」を開きます。


名前などはご自由に。
「マッピングスクリプト」に以下のようなスクリプトを設定してください。
import hudson.plugins.warnings.parser.Warning
import hudson.plugins.analysis.util.model.Priority

String fileName = matcher.group(1);
int lineNumber = Integer.parseInt(matcher.group(2));
String category = matcher.group(3);
String id = matcher.group(4);
String message = matcher.group(5);
Priority priority;

if (category.contains("error")) {
    priority = Priority.HIGH;
} else if (category.contains("information")) {
    priority = Priority.LOW;
}
else {
    priority = Priority.NORMAL;
}

return new Warning(fileName, lineNumber, id, category, message, priority);

ジョブの設定
最後にジョブの設定をします。
ビルド後の処理から「コンパイラの警告の集計」を追加。
パーサーには上で追加したパーサーを選択してください。


そして、「高度な設定」を開いて「デフォルトのエンコーディング」を設定してください。


設定は以上です。

結果

文字化けしてませんね^^

根本的解決を目指す
Cppcheck Plugin が Warnings Plugin のようにエンコード指定に対応できればいいわけです。
というわけで、やってみようと思っていたのですが…全然手が回らず…今回はここまでです。


今後の展開にご期待ください!!