Android
Mac
Jenkins
CI
AndroidStudio

MacでローカルにJenkins環境構築(Android向け)

はじめに

Androidアプリ用にCI/CD環境を作ろうと、
ローカルPCにJenkins環境を構築した際のメモ。
再度構築する時の備忘録です。

やりたいこと

Androidアプリ開発における、以下の自動化、見える化。
(Github上のAndroidプロジェクトに対して実行)

・Lint
・JUnitテスト
・CheckStyle
・FindBugs
・PMD

環境

・Mac OS High Sierra (10.13.3)
・Java 1.8.0.151
・Android Studio 3.0.1
・Jenkins 2.89.2

Jenkinsのインストール

1.以下のサイトよりJenkinsをダウンロードする

https://jenkins.io

スクリーンショット 2018-02-21 9.39.48.png

2.ダウンロードしたjenkinsのpkgをインストールする

※インストーラが起動するので、標準インストール

3.起動確認

ブラウザのURLに"localhost:8080"を入力してJenkinsのアンロック画面が表示されれば成功。
赤字で記載されているパスにパスワードが記載されているので、入力してロック解除する。

※デフォルトのポート番号8080を使用済の場合は以下補足を参考に変更して確認すること

[補足]
以下のコマンドでポート番号等の設定内容を確認可能。

defaults read /Library/Preferences/org.jenkins-ci

変更したい場合は以下コマンドを実行。

sudo defaults write /Library/Preferences/org.jenkins-ci SETTING VALUE

ex) HTTP port
sudo defaults write /Library/Preferences/org.jenkins-ci httpPort 8888

4.初期設定

ロック解除すると、初期設定画面が表示する。
とりあえず"Install suggested plugins"を選択し、適当なユーザを登録。
これでダッシュボードに辿り着けるはず。

5.手動での起動/停止

この方法でインストールすれば、Mac起動時に自動起動されるよう設定されてるはずだが、設定変更等した場合に手動で再起動する必要があったりするので覚えておく。

・起動
sudo launchctl load /Library/LaunchDaemons/org.jenkins-ci.plist

・停止
sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist

Jenkinsのジョブ作成

※Github上のAndroidプロジェクトを対象とするので、事前に用意しておく

Androidプロジェクトのビルド設定

1.jenkinsユーザとグループにAndroid SDKへのアクセス権を設定しておく

$sudo chown -Rf jenkins /Library/Android/sdk
$sudo chgrp -Rf jenkins /Library/Android/sdk
(デフォルトだとこのパスのはず)

2.Jenkinsの管理 > システムの設定 > グローバル プロパティ > 環境変数に以下の2つを追加
(Androidのビルドに必要)

キー:ANDROID_HOME
値:/Library/Android/sdk

キー:PATH
値:${PATH}:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools

3.Jenkinsの管理 > プラグインの管理でフィルターに"git"と入力して、GitClientを追加
(gitリポジトリからソースコードを取得するのに必要)

4.ダッシュボードから「新規ジョブ作成」を選択し、「フリースタイルプロジェクトのビルド」を選択

5.Generalタブ > ソースコード管理の項目で「Git」を選択し、GithubのリポジトリURLを入力(.gitまで含む)
※デフォルトはmasterブランチだが、指定があればブランチ名を変更しておく

6.Generalタブ > ソースコード管理の項目で追加処理に「Clean before checkout」を加える

7.Generalタブ > ビルド環境の項目で「ビルド開始前にワークスペースを削除する」にチェックを入れる

8.Generalタブ > ビルドの項目でビルド手順の追加から「シェルの実行」を追加

9.シェルスクリプトに「./gradlew build」を入力

10.Generalタブ > ビルド後の処理の項目で「成果物」を保存を追加

11.保存するファイルに「*/.apk」を記載

12.作成したジョブで「ビルドを実行」を選択し、ビルドが成功してapkが作成されていれば確認OK

Lintによる静的解析結果の表示

1.Jenkinsの管理 > プラグインの管理 で「Android Lint」を追加

2.ジョブ > 設定 > eneralタブ > ビルド後の処理の追加 > 「Publish Android Lint results」を追加

3.ビルドを実行し、以下のような項目が表示されていれば成功

スクリーンショット 2018-02-21 16.38.44.png

JUnitでの自動テスト

1.ジョブ > 設定 > ビルド後の処理の追加 > 「JUnitテスト結果の集計」を追加
2.テスト結果XMLに以下を入力

app/build/test-results/**/*.xml

3.ビルドを実行し、以下のような項目が表示されていれば成功

スクリーンショット 2018-02-21 17.05.32.png

checkstyleでのコーディング規約解析結果を表示

1.Jenkinsの管理 > プラグインの管理 で「Checkstyle」を追加

2.ジョブ > 設定 > Generalタブ > ビルド後の処理の追加 > 「Checkstyle警告の集計」を追加

集計するファイルには、出力されるcheckstyle結果が記載されたXMLファイルを指定。

例)
app/build/reports/checkstyle/*.xml

3.Androidプロジェクトにcheckstyleの設定を追加

・以下のcheckstyleを「[PROJECT_ROOT]/config」に作成。
※厳しすぎる場合は適宜修正

https://github.com/checkstyle/checkstyle/blob/master/src/main/resources/google_checks.xml

・Moduleのbuild.gradleに以下を追加。
(例ではapp/build.gradleに追記)

apply plugin: 'checkstyle'

task("checkstyle", type: Checkstyle,
        dependsOn: "assemble") {
    group 'Reporting'
    description "Generate Checkstyle reports."

    ignoreFailures = true
    reports {
        xml.enabled = true
        html.enabled = true
    }

    showViolations true
    configFile = rootProject.file('config/checkstyle.xml')
    source = files(android.sourceSets.main.java.srcDirs)
    classpath = files(configurations.compile.files)
}

check.dependsOn "checkstyle"

4.ビルドを実行し、結果に以下のような項目が表示されていれば成功

スクリーンショット 2018-02-22 23.22.52.png

Findbugsの静的解析結果を表示

1.Jenkinsの管理 > プラグインの管理 で「FindBugs」を追加

2.ジョブ > 設定 > Generalタブ > ビルド後の処理の追加 > 「FindBugs警告の集計」を追加

集計するファイルには、出力されるFindBugs結果が記載されたXMLファイルを指定。

例)
app/build/reports/findbugs/*.xml

3.AndroidプロジェクトにFindBugsの設定を追加

・FindBugsの除外対象フィルターを記載したファイルを追加。
※Testをファイル名に含むファイルを除外

<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
    <Match>
        <Class name="~.*Test" />
    </Match>
</FindBugsFilter>

・Moduleのbuild.gradleに以下を追加。
(例ではapp/build.gradleに追記)

apply plugin: 'findbugs'

def autoGenerated = ['**/R.class',
                     '**/R$*.class',
                     '**/Manifest*.*',
                     'android/**/*.*',
                     '**/BuildConfig.*',
                     '**/*$ViewBinder*.*',
                     '**/*$ViewInjector*.*',
                     '**/Dagger*.*',
                     '**/*_Provide*Factory.class.*',
                     '**/*_Deleter.class',
                     '**/*_Relation.class',
                     '**/*_Selector.class',
                     '**/*_Updater.class',
                     '**/*_Schema.class',
                     '**/*_Schema$*.class',
                     '**/OrmaDatabase.class',
                     '**/OrmaDatabase$Builder.class',
        ]

task("findbugs", type: FindBugs,
        dependsOn: "assemble") {
    group 'Reporting'
    description "Generate Findbugs reports."

    ignoreFailures = true
    reports {
        xml.enabled = true
        html.enabled = false // どちらかしか一度に出力できないのでJenkinsプラグイン用にXMLのみ
    }

    effort = 'max'
    reportLevel = 'low'
    source = files(android.sourceSets.main.java.srcDirs)
    classes = fileTree(dir: 'build/intermediates/classes/debug/',
            excludes: autoGenerated)
    classpath = files(configurations.compile.files)
    excludeFilter = rootProject.file('config/findbugs.xml')
}

check.dependsOn "findbugs"

4.ビルドを実行し、結果に以下のような項目が表示されていれば成功

スクリーンショット 2018-02-25 11.18.17.png

PMDの静的解析結果を表示

1.Jenkinsの管理 > プラグインの管理 で「PMD」を追加

2.ジョブ > 設定 > Generalタブ > ビルド後の処理の追加 > 「PMD警告の集計」を追加

集計するファイルには、出力されるPMD結果が記載されたXMLファイルを指定。

※これだけなぜかビルドエラーになるので調査中

まとめ

あとはJacocoも入れてカバレッジ表示したり、
githubと連携してプルリクにメッセージ表示したりしてチェックを簡単にできるようにしたい。

参考記事

http://yuki312.blogspot.jp/2016/02/android-gradle.html
https://qiita.com/usamao/items/93535df778916ee70ad8