Help us understand the problem. What is going on with this article?

dangerをCircleCI上で使ってAndroidのコードを精査する (FindBugs/Android Lint)

More than 3 years have passed since last update.

前回は、PR自体の属性(milestoneとかassignee)に対してのチェックを行いました。

今回は、FindBugsとAndroid Lintの結果を通知してみます。

最終的な差分は こちら のようになりました。

手順

Dangerfileの修正

http://techlife.cookpad.com/entry/2017/06/28/190000 を参考に、下記のような処理を追加しました。

# Findbugs
findbugs.gradle_task = "app:findbugs"
findbugs.report_file = "app/build/reports/findbugs/findbugs.xml"
findbugs.report(true)

# Android Lint
android_lint.gradle_task = "app:lint"
android_lint.report_file = "app/build/reports/lint-results.xml"
android_lint.filtering = true
android_lint.lint(inline_mode: true)

今回、対象となるモジュールは "app"という名前だったので、上記のような形になります。

この状態でPUSHし、PRを作成、CircleCI上で実行してみた結果としては、下記のようになりました。

https://circleci.com/gh/noboru-i/SlideViewer/153

Danger::DSLError: 
[!] Invalid `Dangerfile` file: undefined local variable or method `findbugs' for #<Danger::Dangerfile:0x007f0e42481dc0>.

ということで、gemを追加します。

Gemfileの更新

下記のように、danger-findbugsなどを追加します。

gem 'danger'
gem 'danger-findbugs'
gem 'danger-android_lint'

そして、 bundle install すると、インストールされ、Gemfile.lockにも追記されます。

インストールできたので、 bundle exec danger pr https://github.com/noboru-i/SlideViewer/pull/63 をしてみました。(これで合ってるか不安ですが。。)

すると、2つのエラーが出ました。

* What went wrong:
Task 'findbugs' not found in project ':app'.
* What went wrong:
Execution failed for task ':app:lint'.
> Lint found errors in the project; aborting build.

  Fix the issues identified by lint, or add the following to your build script to proceed with errors:
  ...
  android {
      lintOptions {
          abortOnError false
      }
  }
  ...

ということで、解消します。

app/build.gradleの編集

まずは、findbugsというタスクがないということですが、 https://github.com/monstar-lab/gradle-android-ci-check を使います。
(詳しくは、 ci.gradle の中身を見ていただければと思います。)

apply from: "https://raw.githubusercontent.com/monstar-lab/gradle-android-ci-check/1.3.1/ci.gradle"

次に、lintのエラーのときにabortしてしまっているのをやめさせます。

android {
    // ...
    lintOptions {
        abortOnError false
    }
}

この状態で、再度 bundle exec danger pr https://github.com/noboru-i/SlideViewer/pull/63 を実行します。

今度は上手く実行されたようです。
ただ、Dangerfileに github.dismiss_out_of_range_messages を書いていることもあり、差分以外のチェック結果についてはGitHub上で表示されません。
全体のチェック結果を確認できるようにしておきます。

Artifactsへの保存

結果のxmlなどを、CircleCI上のArtifactsに保存しておきます。
circle.ymlを下記のように書き換えます。

test:
  override:
    - bundle exec danger
    - cp app/build/reports/findbugs/findbugs.xml $CIRCLE_ARTIFACTS || true
    - cp app/build/reports/lint-results.xml $CIRCLE_ARTIFACTS || true

※07/09追記: || trueが無いと、PRが存在しないmasterブランチのCIなどでエラーになったので追記。

これにより、CircleCIの画面上より、対象のxmlを見ることができます。

https://circleci.com/gh/noboru-i/SlideViewer/154#artifacts/containers/0
image.png

試してみる

まずは、それぞれのエラーを仕込んでみます。

Integer i = null;
i.toString();

SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
editor.commit();

明らかにNull Pointer Exceptionが起こるということで、FindBugsのチェックに引っかかります。
http://findbugs.sourceforge.net/bugDescriptions.html#NP_ALWAYS_NULL

また、SharedPreferencesはcommitではなくapplyを使いましょうという、Android Lintの ApplySharedPref というルールに引っかかります。
http://tools.android.com/tips/lint-checks

この状態でコミットし、CircleCIにてdangerを実行しました。

image.png

ちゃんと出てますね。

では、これらを修正してみます。

Integer i = 1;
i.toString();

SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
editor.apply();

image.png

見事に消えました。

まとめ

dangerプラグインが用意されているお陰で、FindBugsとAndroid Lintの結果をGitHubのPRコメントに追記するのは簡単にできました。

また、修正されたものについては、PRコメントからも消えるのが良いですね。

ただ、個人的には、 NP_ALWAYS_NULLだったり、ApplySharedPrefのような、それぞれのチェックに対応するキーが表示されたほうがありがたいなーと思いました。
実際に作業していくにあたっては、Artifactsとして保存したxmlを見る必要も出てきそうな気がします。

あとは、Checkstyleの結果も出力したいですね。誰か、dangerプラグイン作ってるかな?

noboru_i
Androidを中心に、iOSやサーバサイドも少しだけやっています。 CircleCIやDangerといった、CI/CD周りにも興味があります。
http://noboru-i.github.io/
monstar-lab
自社サービス「モンスター・チャンネル」や「セカイラボ」をはじめ、日本を代表する企業のWeb・アプリの受託企画/開発を行っています。
https://monstar-lab.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away