Jenkins+GradleでJavaのCIのための基本build.gradle設定 (JUnit,PMD,FindBugs,CPD,JaCoCo)

私的Java開発をJenkinsでCIするためのbuild.gradleとJenkinsの設定です。要不要に応じて書き換えたり足したりが必要です。特にチェックルール。

# 環境
+ Java 1.7
+ Groovy 1.8.6
+ Ant 1.9.2
+ Ivy 2.2.0
+ Gradle 1.11
+ Mac OS X 10.9.2

# 全体の流れ

1. Jenkinsに必要なプラグインをインストール
2. GradleでFindBugs, PMD, CPDを実行するようbuild.gradleを作成
3. Eclipseでは

# Jenkinsにいれるプラグイン

+ Gradle plugin - jenkins+gradle連携
+ FindBugs Plug-in - バグ検知
+ PMD Plugin - コーディングチェック
+ Violations plugin - 静的レポートの集計表示
+ JaCoCo plugin - コードカバレッジの算出
+ Task Scanner Plug-in - コメントTODOなどの収集

Violations pluginがあればPMDとFindBugsのプラグインを個別にいれなくても表示可能ではあります。
私はFindBugs Plugin, PMD Pluginの方が見やすいと感じるので個別にもいれています。

Task Scanner Plug-inはJavaコード中のコメントのFIXMEやTODO, TBDなどを収集して一覧にしてくれる素敵なプラグインです。
これがあれば書いているのに永遠に放置されるTODOとはおさらばでできます。（解決する気があればですが）

カバレッジ算出をJaCoCoにしたのはGradleのプラグインとして用意されているから以外の理由はありません。
http://www.gradle.org/docs/current/userguide/jacoco_plugin.html#applyJacoco

# Gradleの設定 build.gradle

下記構成のbuild.gradleです。

+ Javaバージョン1.7
+ ローカル開発時はローカルMaven2キャッシュリポジトリにuploadArchives
+ FindBugsの実行 - バグ検知<br>
レポート出力先: build/reports/findbugs/main.xml<br>
http://gradle.monochromeroad.com/docs/dsl/org.gradle.api.plugins.quality.FindBugs.html
+ PMDの実行 - コーディングチェック<br>
レポート出力先: build/reports/pmd/main.xml<br>
http://gradle.monochromeroad.com/docs/dsl/org.gradle.api.plugins.quality.PmdExtension.html
+ CPDの実行 - 重複コードチェック<br>
レポート出力先 : build/reports/pmd/cpd.xml
+ JaCoCo - コードカバレッジの集計<br>
jacocoレポートではローカルでも利用したいのでhtml出力もおこなう。<br>
http://www.gradle.org/docs/current/userguide/jacoco_plugin.html#applyJacoco<br>
レポートHTML出力先 : build/reports/jacoco/jacocoReport/html

```groovy:build.gradle
apply plugin: "java"
apply plugin: "eclipse"
apply plugin: "maven"
apply plugin: "findbugs"
apply plugin: "pmd"

def defaultEncoding = 'UTF-8'
[compileJava, compileTestJava]*.options*.encoding = defaultEncoding

sourceCompatibility = 1.7
targetCompatibility = 1.7
group = 'com.mychaelstyle'
archivesBaseName = 'MyLibs'
version = '0.1.0'

repositories {
  mavenCentral()
  maven {
    url 'file:'+System.getenv('HOME')+'/.m2/repository'
  }  
}

dependencies {
  testCompile "junit:junit:4.11"
  compile 'log4j:log4j:1.2.17'
  runtime fileTree(dir: 'libs', include: '*.jar')
}

uploadArchives {
  repositories {
    mavenDeployer {
      file(System.getenv('HOME')+'/.m2/repository').mkdirs()
      repository(url: 'file:'+System.getenv('HOME')+'/.m2/repository')
    }
  }
}

jar {
  manifest {
    attributes 'Implementation-Title': 'MyLibs', 'Implementation-Version': 0.1
    attributes "Main-Class" : "com.mychaelstyle.Main"
  }
  from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}

task writePom << {
  pom {
    project {
      inceptionYear '2014'
      licenses {
        license {
          name 'The Apache Software License, Version 2.0'
          url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
          distribution 'repo'
        }
      }
    }
  }.writeTo("$projectDir/pom.xml")
}

findbugs {
  ignoreFailures = true
  toolVersion = "2.0.1"
  sourceSets = [sourceSets.main]
  reportsDir = file("$project.buildDir/reports/findbugs")
  effort = "max"
}

pmd {
  ignoreFailures = true
  sourceSets = [sourceSets.main]
  reportsDir = file("$project.buildDir/reports/pmd")
  ruleSets = [
    "basic",
    "braces"
  ]
}

// JaCoCo coverage reports
jacoco {
  applyTo(tasks.withType(JavaExec))
}
test {
  jacoco {
    enabled = true
    destPath = 'build/reports/jacoco/jacoco.exec'
  }
}
task jacocoReport(type: JacocoReport) {
  executionData test
  sourceSets project.sourceSets.main
}

// checkにCPDを追加
check << {
  File outDir = new File('build/reports/pmd/')
  outDir.mkdirs()
  ant.taskdef(name: 'cpd', classname: 'net.sourceforge.pmd.cpd.CPDTask',
    classpath: configurations.pmd.asPath)
  ant.cpd(minimumTokenCount: '100', format: 'xml',
    outputFile: new File(outDir , 'cpd.xml')) {
    fileset(dir: "src/main/java") {
      include(name: '**/*.java')
    }
  }
}
// コラボに必須なgradle wrapper
task wrapper(type: Wrapper) {
  gradleVersion = '1.9'
}
```
# Jenkinsの設定
1. 最初にgradle wrapperコマンドでラッパーを作成してコミットしておきます。
2. プラグインを導入済みなら「ビルド手順の追加」の中に「Invoke Gradle script」があるので追加します。Use Gradle WrapperでCIおこないます。<br>設定項目はみればだいたいわかると思います。
3. ビルド後の処理を追加します。<br>
FindBugs警告の集計 ... build/reports/findbugs/main.xml<br>
PMD警告の集計 ... build/reports/pmd/main.xml<br>
未解決タスクの集計 ... 対象: src/main/java/**/*.java , タスクタグ: FIXME, TBD, TODO<br>
重複コード分析の集計 ... build/reports/pmd/cpd.xml<br>
静的解析結果を集約<br>
JUnitテスト結果の集計 ... build/test-results/*.xml<br>
Javadocの保存 ... build/docs/javadoc<br>
Jacocoカバレッジレポートを記録<br>

# eclipse連携

Limyが便利なのでEclipse使う人はこれ。レポートが見やすいと思います。
http://www.limy.org/program/eclipse_plugin/