経緯
dangerをCircleCI上で使ってAndroidのコードを精査する (FindBugs/Android Lint) - Qiita では、CircleCI 1.0を使っていました。
CircleCI 2.0でAndroidのアプリをビルドしつつ、コードレビューBOTも動かす - Qiita では、CircleCI 2.0でしたが、Saddlerを使っていました。
DangerでCheckstyleの結果を指摘する - Qiita では、CircleCI 2.0でDangerを利用しましたが、Checkstyleの結果だけを指摘しました。
その後Gemを更新したりして、 FindBugs / PMD / Android Lint の結果も通知出来るようになりました。
今回は、そのあたりのコードをまとめて貼っていきます。
できるようになること
CircleCI 2.0を動作させ、Dangerを経由して、下記のチェック結果をPull Requestにコメントする。
イメージとしては、下記のような形です。( 実際のPR )
必要なこと
build.gradleにて、各チェックが実行されるようにする
app/build.gradle
の任意の箇所に、下記のように追加します。
apply from: "https://raw.githubusercontent.com/monstar-lab/gradle-android-ci-check/1.3.1/ci.gradle"
詳細は monstar-lab/gradle-android-ci-check を見ていただき、不要な部分などあれば、独自に記述してください。
これにより、 ./gradlew :app:check -x test
とやることで、各種のチェックが実行され、xmlが出力されるようになります。
Gemfileを記述し、Gemfile.lockを生成する
Dangerやその他必要なものをinstall出来るように、Gemfile
を記述していきます。
# frozen_string_literal: true
source "https://rubygems.org"
gem 'danger'
gem 'danger-checkstyle_format'
gem 'android_lint_translate_checkstyle_format'
gem 'findbugs_translate_checkstyle_format'
gem 'pmd_translate_checkstyle_format'
その後、ローカルで bundle install
しておき、生成されるGemfile.lock
もrepositoryに追加しておきます。
(個人的には、プロジェクトごとにGemを管理したいので、 bundle install --path vendor/bundle
を実行してます。)
Dangerfileを記述する
Dangerfile
を作成し、下記のようにします。
# github comment settings
github.dismiss_out_of_range_messages
checkstyle_format.base_path = Dir.pwd
# checkstyle
checkstyle_format.report 'app/build/reports/checkstyle/checkstyle.xml'
# Findbugs
require 'findbugs_translate_checkstyle_format'
findbugs_xml = ::FindbugsTranslateCheckstyleFormat::Script.translate(File.read('app/build/reports/findbugs/findbugs.xml'))
checkstyle_format.report_by_text findbugs_xml
# PMD
require 'pmd_translate_checkstyle_format'
pmd_xml = ::PmdTranslateCheckstyleFormat::Script.translate(File.read('app/build/reports/pmd/pmd.xml'))
checkstyle_format.report_by_text pmd_xml
# PMD-CPD
require 'pmd_translate_checkstyle_format'
pmd_cpd_xml = ::PmdTranslateCheckstyleFormat::Script.translate_cpd(File.read('app/build/reports/pmd/cpd.xml'))
checkstyle_format.report_by_text pmd_cpd_xml
# # Android Lint
require 'android_lint_translate_checkstyle_format'
android_lint_xml = ::AndroidLintTranslateCheckstyleFormat::Script.translate(File.read('app/build/reports/lint-results.xml'))
checkstyle_format.report_by_text android_lint_xml
CircleCI 2.0の設定を記述する
.circleci/config.yml
を下記のように記述します。
version: 2
defaults: &defaults
working_directory: ~/code
docker:
- image: circleci/android:api-26-alpha
environment:
JVM_OPTS: -Xmx3200m
jobs:
build:
<<: *defaults
steps:
- checkout
- restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- run:
name: Download Dependencies
command: ./gradlew androidDependencies
- save_cache:
paths:
- ~/.gradle
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- run:
name: Check lint
command: ./gradlew :app:check -x test
- run:
name: Build apk
command: ./gradlew :app:assembleDebug
- store_artifacts:
path: app/build/outputs/apk/app-debug.apk
destination: app-debug.apk
- store_test_results:
path: app/build/test-results
- persist_to_workspace:
root: ~/code
paths:
- .
check:
working_directory: ~/code
docker:
- image: circleci/ruby:2.4.1
steps:
- attach_workspace:
at: ~/code
- restore_cache:
key: gems-{{ checksum "Gemfile.lock" }}
- run: bundle install --path vendor/bundle
- run:
name: Run danger
command: bundle exec danger
- run:
name: Move artifacts
command: |
ARTIFACTS="/tmp/circle_artifacts"
mkdir -p "$ARTIFACTS"
cp -v "app/build/reports/checkstyle/checkstyle.xml" "$ARTIFACTS/"
cp -v "app/build/reports/findbugs/findbugs.xml" "$ARTIFACTS/"
cp -v "app/build/reports/pmd/pmd.xml" "$ARTIFACTS/"
cp -v "app/build/reports/pmd/cpd.xml" "$ARTIFACTS/"
cp -v "app/build/reports/lint-results.xml" "$ARTIFACTS/"
- save_cache:
paths:
- vendor/bundle
key: gems-{{ checksum "Gemfile.lock" }}
- store_artifacts:
path: "/tmp/circle_artifacts"
deploy:
<<: *defaults
steps:
- attach_workspace:
at: ~/code
- run:
name: Build apk
command: ./gradlew :app:assembleRelease
- store_artifacts:
path: app/build/outputs/apk/app-release.apk
destination: app-release.apk
- store_artifacts:
path: app/build/outputs/mapping/release/dump.txt
destination: dump.txt
workflows:
version: 2
build_and_deploy:
jobs:
- build
- check:
requires:
- build
- deploy:
requires:
- build
- check
filters:
branches:
only: master
check
jobだけDockerのイメージが切り替わっていたり面倒なことになっていますが、その理由などは、 CircleCI 2.0でAndroidのアプリをビルドしつつ、コードレビューBOTも動かす に書きました。
CircleCI側の設定
Dangerでは、DANGER_GITHUB_API_TOKEN
という環境変数を利用します。
GitHub側でPersonal access tokenを作成し、CircleCIの設定画面の"Environment Variables"に設定しておきます。
BOTアカウントを作っておき、そのtokenを使用すると、BOTに指摘されたように見えていい感じです。
また、必須ではないですが、CircleCI側で、「PRが作成されたときだけCIを実行する」としておいた方が良いかと思います。
プロジェクトの設定画面から、"Advanced Settings"にある、"Only build pull requests"をONにしておきます。
あとはGitHubにPUSHしPRを作成すると、CircleCIがビルドを行い、変更箇所にwarningなどがあれば、PRのコメントとして指摘が付きます。
(最終的な設定イメージ: https://github.com/noboru-i/SlideViewer/tree/bc86f226b943aeedb58b74b50784f7de8835346e )