Android
bitbucket
Jenkins

プルリクをトリガーにjenkinsで自動テスト&静的解析

More than 1 year has passed since last update.

自分のプロダクトでは若手も多いということで、最低限のレビューをjenkinsにやらせるようにしました。
(Androidメインの記事ですが、似たようなことはiosでもできます)

findBugs/PMD/CheckStyleの導入

設定ファイルの追加

任意の場所に各ツールの設定ファイルを配置してください。
ここではプロジェクトのルートにconfigフォルダを用意して配置しました。
(ファイル名はcheckstyle-config.xml、android-exclude-filter.xml、pmd-ruleset.xmlとしました)
※具体的な設定ファイルは省略します

graldeの修正

今回のツール用のgradleをconfigフォルダ内に新規作成します

quality.gradle
apply plugin: 'checkstyle'
apply plugin: 'findbugs'
apply plugin: 'pmd'

dependencies {
    checkstyle 'com.puppycrawl.tools:checkstyle:8.1'
}

def qualityConfigDir = "$project.rootDir/config"
def reportsDir = "$project.rootDir/build/reports" // 解析結果の出力パス

check.dependsOn 'checkstyle', 'findbugs', 'pmd'

task checkstyle(type: Checkstyle) {
    group = "quality"
    ignoreFailures = true
    configFile file("$qualityConfigDir/checkstyle-config.xml")
    source 'src'
    include '**/*.java'

    reports {
        xml.enabled = true
        html.enabled = true
        xml {
            destination "$reportsDir/checkstyle.xml"
        }
        html {
            destination "$reportsDir/checkstyle.html"
        }
    }

    classpath = files()
}

task findbugs(type: FindBugs) {
    group = "quality"
    ignoreFailures = true
    effort = "max"
    reportLevel = "high" // どのレベルの報告まで対応するかで変更
    excludeFilter = new File("$qualityConfigDir/android-exclude-filter.xml")
    classes = files("build/intermediates/classes/")
    source 'src/main'
    include '**/*.java'
    exclude '**/gen/**'
    reports {
        xml.enabled = true
        html.enabled = false
        xml {
            destination "$reportsDir/findbugs_report.xml"
        }
        html {
            destination "$reportsDir/findbugs_report.html"
        }
    }
    classpath = files()
}

task pmd(type: Pmd) {
    group = "quality"
    ruleSetFiles = files("$qualityConfigDir/pmd-ruleset.xml")
    ignoreFailures = true
    ruleSets = []

    source 'src'
    include '**/*.java'
    exclude '**/gen/**'

    reports {
        xml.enabled = true
        html.enabled = true
        xml {
            destination "$reportsDir/pmd.xml"
        }
        html {
            destination "$reportsDir/pmd.html"
        }
    }
}

プロジェクトのgradleに下記を追加します

build.gradle
buildscript {
    dependencies {
        classpath 'io.fabric.tools:gradle:1.+'
    }
}
apply plugin: 'com.android.application'
apply from: '../config/quality.gradle' // ここを追加
...

bitbucketの設定

プロジェクトの設定>フック
ポストレシーブ(Bitbucket Server Webhook to Jenkins)の設定
jenkins URLにjenkinsサーバーのURLを設定(jenkins本体のURLで、jobのパスは不要)

jenkinsの設定

ソースコード管理(git)

git設定.png
「高度な設定」を選択すると、上記のような画面になります。
名称は空欄でOK、Refspecとブランチ指定子は公式にあるように下記の文字列を入力してください。

Refspec
+refs/pull-requests/*:refs/remotes/origin/pr/*
ブランチ指定子
origin/pr/${pullRequestId}/merge

ビルドトリガ

ビルドトリガー.png
「SCMをポーリング」にチェックを入れ、スケジュールは空欄にしてください。
「post-commitフックを無視」は環境に異なるとかいう噂ですので、動かなかったらON/OFFを切り替えて試してみてください…

Stash Pull Requests Builder

PRビルダー.png
Cronには「* * * * *」、stash hostにはstashのURLを指定してください。
Project,RepositoryNameは監視するプロジェクト/リポジトリ名を設定してください。

ビルド後の処理

CheckStyle/FindBugsの集計

プラグインで下記のようにしておくと見やすいです。
集計.png

Notify Stash Instance

Commit SHA-1には以下のように入力してください
(「高度な設定」内にあります)

CommitSHA-1
${sourceCommitHash}

スクリーンショット 2017-10-26 13.28.01.png

結果

こんな感じで見えます
result.png

カスタムコメント

プルリクに記載されるコメントはカスタマイズ可能です。
私は上記キャプチャのように、各ツールの警告数をコメントで出力するようにしています。
スクリーンショット 2017-10-26 13.52.59.png

計測結果数の環境変数化

ここで、PMD_RESULEやFB_RESULTS は環境変数なのですが、計測結果数を環境変数として保存して実現しています。やり方はこちらに書きましたので、ご参照ください。
https://qiita.com/mkosuke/items/ef55ae48b2064873ba2b

計測結果数の集計

解析結果ファイルをスクリプトで地道に解析しています。
ちなみにスクリプトは苦手なのでもっと賢いやり方はあるのだと思います…

CheckStyle
CS_TERM=\<td\>[0-9]*\<\/td\>\<td\>[0-9]*\<\/td\>
CS_RESULT=$(grep $CS_TERM ./build/reports/checkstyle.html | sed -r "s/[^0-9]+([0-9]+)[^0-9]+([0-9]+)[^0-9]+/\2/")
echo -e "CS_RESULTS=$CS_RESULT" >> analytics_result.txt
FindBugs
FB_TERM=\<BugInstance
FB_RESULT=$(grep -c $FB_TERM ./build/reports/findbugs_report.xml)
echo -e "FB_RESULTS=$FB_RESULT" >> analytics_result.txt
PMD
PMD_TERM=var/lib/jenkins/jobs/BUS_BUILD_CHECKER/workspace/
PMD_RESULT=$(grep -c $PMD_TERM ./build/reports/pmd.html)
echo -e "PMD_RESULTS=$PMD_RESULT" >> analytics_result.txt

例では解析結果をanalytics_result.txtというテキストファイルに出力していますので、環境変数のインジェクトでanalytics_result.txtを読み込んであげればカスタムコメントにも使えるようになります。