Quantcast
Channel: Kengo's blog
Viewing all 157 articles
Browse latest View live

SpotBugsプラグイン実装方法2017

$
0
0

過去にFindBugsプラグインの実装方法について記事にしたとおり、FindBugsプラグインの実装には複雑なハックが必要でした。特にfindbugs.xmlやmessages.xmlなどのメタデータ管理が煩雑でした。

これがSpotBugs 3.1.0-RC3ではある程度楽になっているので、シンプルになった方法をここにまとめておきます。

プロジェクトの雛形を作る

archetypeがコミュニティから提供されるようになりました。これを使えばプラグイン開発の知識がなくてもすぐにプロジェクトを作成できます。

github.com

使い方は他のmavenarchetypeと同じで、archetype:generate実行時にarchetypeのgroupId, artifactIdそしてversionを指定するだけです。現状バージョン0.1.0が最新なので、以下のコマンドを実行してください:

$ mvn archetype:generate \-DarchetypeArtifactId=spotbugs-archetype \-DarchetypeGroupId=com.github.spotbugs \-DarchetypeVersion=0.1.0

バグとして検出すべきケースを実装し、単体テストを回す

プロジェクト生成に成功すると、src/test/javaに2つのクラスが見つかるはずです。

これらを実際に解析して結果を確認しているテストケースもあります。

このテストケースは、SpotBugsが出しているtest-harnessモジュールを使っています*1SpotBugsRuleというクラスがキモで、これを使って実際の.classファイルを解析し結果を確認できます。assertion用のMatcherクラスも提供されているので、hamcrestを使ったテストも書きやすいです。

@Rulepublic SpotBugsRule spotbugs = new SpotBugsRule();
     @Testpublicvoid testIssuesAreFound() {
         Path path = Paths.get("target/classes/my/company/AnalyzedClass.class")
         BugCollection bugCollection = spotbugs.performAnalysis(path);

         // There should only be exactly 1 issue of this typefinal BugInstanceMatcher bugTypeMatcher = new BugInstanceMatcherBuilder()
                 .bugType("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE").build();
         assertThat(bugCollection, containsExactly(bugTypeMatcher, 1));

         final BugInstanceMatcher bugInstanceMatcher = new BugInstanceMatcherBuilder()
                 .bugType("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE")
                 .inClass("AnalyzedClass")
                 .atLine(25)
                 .build();
         assertThat(bugCollection, hasItem(bugInstanceMatcher));
     }

以前はプラグインを実際に使ったテストをするためにはfindbugs-maven-pluginを使ってインテグレーションテストを回すしか方法がありませんでしたが、この手法ならより高速にテストを回せます。また test-driven-detectors4findbugsと違って公式なので、今後のSpotBugsの更新にも追随できるはずです*2

メタデータを作成する

まずbugrank.txtは現状必要ないようです。無くてもプラグインはビルドできます。そもそもBugRankという概念はこの論文でやこのページ紹介されている通り、SonarQubeのSeverityのようなもので、priority (confidence)とは全く別の概念です。が、果たしてそれがどの程度浸透しているのか……。SpotBugsが使うpriorityやpriority (confidence)のことは忘れてSonarQubeのSeverityだけ使うのが、運用も回しやすいと思います。

ので、全体的な情報を提供するfindbugs.xmlと、ユーザ向けメッセージを管理するmessages.xmlだけ作成すれば十分です。プロジェクトの雛形にはこれらが既に作成されているので、それを参考にコピペで要素を増やしてください。

番外編:SonarQubeプラグインを作成する

SonarQubeプラグインsonar-packaging-maven-pluginを使ってパッケージできます。sonar-findbugsと拙作findbugs-slf4jが参考になります。

キモはfindbugs-pluginバージョン3.5への依存を宣言することです。このバージョンはSpotBugs 3.1.0-RC2を使っているため、SpotBugsに依存したプラグインを書くには必須です。

なおsonar-findbugsバージョン3.5はpre-releaseバージョンで、まだSonarQubeのUpdate Centerでは配布されていません。使用する際はGitHubのリリースページからjarを落としてきて手動インストールする必要があります。

またSonarQube用のrule.xmlを生成する必要があるのですが、これは雑ですがMavenプラグインを作ったので使ってもらえればと思います。Groovy好きな方はsonar-findbugsのコードを参照しても良いでしょう。

まとめ

以上でSpotBugsプラグインを実装してSonarQubeも含めた運用を回すことができるはずです。 まだ各種親Detectorを学習する手間は必要ですが、5年前に比べてだいぶマシにはなりました。

追記:公式かつ英語のドキュメントもできました。

*1:find-sec-bugsからコードを持ってきて作られたもの

*2:test-driven-detectors4findbugsはFindBugs 1.3.9〜2.0.2にしか対応していなかった


maven archetype v2の作り方

javadoc.ioのクローンをreactorで実装した

$
0
0

また技術キャッチアップ用のプロジェクト作りました。今回使いたかったのは以下の4つ:

  • spring-boot v2.0(リリース前)
  • spring-webflux v5.0(リリース前)
  • selenide v4.5
  • checker framework v2.2

Springは5.0リリース前にマイルストーン版を使って感覚を見たかったため、特にreactorとRxJavaの違いを確認したかったため。 selenideはユースケースを見たことが無かったのでなんの役に立つのか肌感覚を持つため。 checker frameworkは公式ドキュメントに色々不明点がある*1ので、(今までやってきたライブラリやCLIツールではなく)自走するウェブアプリで色々確かめたかったためです。

以下所感をまとめておきます。

reactorによるウェブアプリ実装について

vert.xでも感じたことですが、reactive-streamsを使ってのウェブアプリ実装は十分に可能なものの、どの程度ペイするのかよく分からないというのが実情です。 外部サーバとのI/Oが処理のほとんどとなりやすいウェブアプリにおいて非同期I/Oを短く簡潔に扱えるというのは利点ですが、リアクティブに処理を書く必要性・Backpressureの利点をきちんと享受したいケースがどの程度あるかというと疑問という感じでしょうか。 これについてはそれなりの負荷がかかるサービスで比較検証する必要がありそうです。ab等を使った負荷検証をしてみます。

また静的解析ツールの支援を受けられないのはなかなかつらいなと思いました。 subscribe()時に正常系のconsumerだけ設定したためにエラーに気づけなかったケースとか、Mono.create()Mono.from()の違いを知らずonNext signalを掴み損ねたケースとか、習熟すればすぐに見つけられるがそうじゃないとかなり厳しい「書き方の問題」が多数ありました。年月が解決する問題ではありますが、現時点では業務用途はだいぶきつい印象です。

selenideでできることはコード短縮だけでないという話

Selenideを使ってみて「あれこれって大してコード量減らないのでは……?」と思ったのでつぶやいた結果、公式アカウントに突っ込まれました。

ブラウザのレンダリングを待つようなコードをいちいち埋めないでいいというのは、確かに大きな利点です。特にSeleniumを使ったテストの経験が浅い開発者は、気軽に Thread.sleep(long)してしまいテストを遅くする傾向にあります。コードレビューで指摘し育てるのも手ですが、Selenideのようなソリューションで統一的に解決してしまうのは手でしょう。

ただリダイレクト周りの検証とか、いまいち書き方がわからずWebDriverを直接叩くケースはまだまだありそうな感じでした。これだけ知っていればSeleniumについて気にしないで良い、というモノでは無さそうです。

checker framework

ちょっとまだfalse-positiveや価値の低い解析結果が多い印象です。Java標準APIはデータベースが整ってきているようですが、ライブラリ側(今回で言えばreactor含むSpring Framework)のデータベースが無いため、Nullableを許容するAPIでも「ここはNonnullだから!null渡さないで!」とコンパイルエラーになることが多いです。結局SuppressWarningをつけて回避しています。

彼らが配布するQualifierの認知度が上がり利用されるようにならないと、まだ積極的な導入は難しそうという印象を持ちました。

*1:サンプルプロジェクトがcompileOnlyではなくcompileでchecker frameworkに依存してるのはなぜ?等

FindBugsの後継としてのSpotBugsの紹介

$
0
0

このエントリは「Announcing SpotBugs as FindBugs successor」の意訳です。一部、明らかなURLの誤りを修正し、可読性のため強調を施しています。


皆さんこんにちは、

このメールはこのメーリングリストにおける私の最後の投稿であり、また昨年のこちらの投稿の続きです。
https://mailman.cs.umd.edu/pipermail/findbugs-discuss/2016-November/004321.html

TL;DR:FindBugsプロジェクトはプロジェクトリードが管理者権限を移管しないままプロジェクトを離れ、また1年以上応答がなくなったため停止しました。SpotBugsプロジェクトがその後継であり、バージョン3.1.0 RC5を既にリリースしています。ASM6の安定バージョンがリリースされしだい、SpotBugsの3.1.0 RC6そして3.1.0安定バージョンがリリースされる予定です*1

私が前述のメールを書いてから数名の有志がプロジェクトに参加して、私たちがプロジェクトが生き残るチャンスをものにできるよう助けてくれました。FindBugsという名称は商標であることから他の名称を使う必要が生じたため、新しいプロジェクトはSpotBugsと名付けられました。コードも新しいリポジトリに移され、ホームページ,メーリングリスト,バグトラッカーなどもGitHub上に用意されました。

私たちはASM 6のリリースを待ってSpotBugsの3.1.0 RC6と3.1.0 finalバージョンをリリースします、これは今月中に実現する見込みです。

SpotBugs 3.1.0 RC6がリリースされたら(このバージョンは最後のRC版になるでしょう)、私たちはコマンドライン,Antタスク,Mavenプラグイン,GradleプラグインEclipseプラグインそして新しいマニュアルを提供します。

FindBugs 3.0.1からの変更点はこちらに一覧化されています:
https://github.com/spotbugs/spotbugs/releases

注目すべき変更点は以下のとおりです(私が何かを忘れていたらすみません):

  • リリースされたばかりのJava 9で動作します
  • 実行にはJava 8かそれより新しいJavaが必要です
  • EclipseプラグインMavenプラグインそしてGradleプラグインのIDが変わりました*2
  • BCEL 6.1とASM 6を使用しています
  • GradleプラグインはGradle 4かそれより新しいバージョンで動作します
  • EclipseプラグインEclipse 4.6*3かそれより新しいバージョンで動作します
  • プロジェクトのビルドにはGradleを使っています
  • 新しいマニュアルはreadthedocsでホストされています
  • 新しいプラグイン開発者向けテスト機構を備えています
  • Travis CIを使ったプルリクエストの検証を行います
  • その他コミュニティによる多数のバグ修正と貢献が含まれます

我々はすべてのFindBugsユーザが大きな問題なくSpotBugsを使えるよう望んでいます。マニュアルのマイグレーションガイドを見てください。我々はまた皆さんがテストやバグ報告や貢献を通じてSpotBugsプロジェクトを支援してくれることを期待しています。実際のところ、コミュニティの助けがなければ開発を続けることはできません。

もちろん上述のメーリングリストやイシュートラッカーの購読も忘れないでください。

*4はまたSpotBugsを助けてくれたすべての人々に感謝の言葉を伝えたいです。GitHubの貢献者一覧を見てください。

特にJuan Martín Sotuyo DoderoとKengo TODA*5。彼ら二人がいなければ今日のSpotBugsプロジェクトは存在しなかったでしょう。二人ともありがとう!

これがこのメーリングリストでの最後の言葉です:私はこのようなことが起こるとは想像していなかったし、このようなことを言うことは非常に悲しいのですが……さようならFindBugs!あなたは10年間に渡り、何百万人もの開発者を助けてくれました。Bill、David、こんなに素晴らしいツールをありがとう。こんなアナウンスをしてしまって申し訳ないけど、ショーは続かなければならないんだ。

はじめまして、SpotBugs!

*1:訳注:3.1.0 RC6は既にリリースされています

*2:訳注:原文には記載がないがGradleプラグインもIDが変わっている

*3:訳注:EclipseNeonのこと

*4:訳注:投稿者Andrey Loskutov氏のこと

*5:訳注:訳者のこと

SpotBugs 3.1.0 RC6の利用とフィードバックのお願い

$
0
0

先日SpotBugsの最新版となる3.1.0 RC6が出ました。大きな問題が無ければ、これが最後のRC版となる予定です。

SpotBugs開発において、私は新マニュアルサイト整備CHANGELOG整備、Ant廃止、Gradleスクリプト整備、Travis CI整備、Bot管理、パフォーマンス改善、JUnit用test-harness作成、Gradleプラグインの統合テスト作成、などなど色々やらせてもらいました。昨年FindBugsがforkされてからの10ヶ月間で数多くの変更と修正を入れてきましたが、どうにかJava9リリースのタイミングに合わせる形でSpotBugsの安定版をリリースできそうです。
助けていただいた各位、特にドキュメントの日本語訳にコントリビュートしてくださっているKannoさんと、SpotBugsチームの要請に応えてv6.1を出してくださったApacheBCELメンテナ各位に御礼申し上げます。

このバージョンにはMANIFEST.MFに記載されたClass-Pathが間違っているという既知の問題がありますが、MavenやGradle、AntなどのビルドツールあるいはEclipseによってFindBugs/SpotBugsを使っている場合には問題になりません。ぜひ日頃の趣味開発ないし業務開発で使っていただいて、イシュートラッカーにフィードバックをお願いします。
なおjarコマンドあるいはSpotBugsが提供するスクリプトを利用されている方は、こちらに記載のMANIFEST.MFでjarファイル内のものを置き換えてください。

なお私は今後も個人的にSpotBugs開発に携わっていく予定です。BCEL自体がスレッドアンセーフらしく一筋縄ではいかないようですが、マルチスレッド化を進めていきたいと考えています。今後ともよろしくお願いします。

Mavenプロジェクト用Travis CI設定(2017年末)

$
0
0

今年はビルド周りで自分の常識がいろいろ変わった年だったので、既存の知見もあわせてまとめます。

Mavenのバージョンを固定する

Travis CIは不定期にビルド用仮想マシンを更新しますが、そのタイミングでの最新のMaven仮想マシンに入れるようです。このブログ投稿時だと3.5.2が入っています。

もっと新しいバージョンを使う、あるいはMavenのバージョンを固定するには、Maven Wrapperを使うと良いでしょう。Travis CIはプロジェクトルートディレクトリにmvnwスクリプトがある場合はそれを優先的に使います。

mvnコマンド指定時の注意点

scriptinstalldeployなどのフェーズで mvnコマンドを明示的に実行する場合、 -Bオプションを忘れないようにします。このオプションによってMavenインタラクティブなログを抑制するようになり、ログサイズが激減します。Travis CIはログサイズに上限があるため、うっかり忘れるとビルドが不安定になります。

グローバルにコマンドラインパラメータを指定する方法

グローバルにコマンドラインパラメータを指定する場合、それがローカルでの実行時にも必要となるパラメータならば、Maven 3.3から導入された .mvn/maven.configあるいは .mvn/jvm.configを使うことも可能です。ただし現状これらのファイルはコメントを書けないので、チームで使用する場合はどこかで説明が必要でしょう。

SonarCloudによるコード解析

FOSSならSonarCloudを使えば無料で解析できます。Travis CIには専用Addonがあって、MavenでSonarQube専用プロパティをややこしく設定しなくても、pom.xmlをよしなに解析してプロジェクトホームやIssueトラッカのURLを見つけてくれます。

なおコード解析をPRにも働かせる場合は、PRのもととなるブランチも同じリポジトリに存在する必要があります。これはトークンの復号化に必要なためです。

Travis CIによるSonatype Nexusへのデプロイ

これを取り入れるかどうかは意見が別れるところだと思います。というのもこれをやるには、暗号化済みとは言えGPG署名に必要なファイルやSonatype Nexusのパスワードをリポジトリにコミットする必要があるのです。

私の場合、個人プロダクトでは使わずに Maven Release Pluginを使うようにしています。ただしSpotBugsのような共同リポジトリの場合、リリース難度を下げ属人性をなくすために使用しています。

作業内容は単純に、GPG public keyring, GPG secret keyring そしてGPG passphaseとSonatype Nexusアカウント情報を含んだ settings.xmlを暗号化してリポジトリにコミットし、それをデプロイ時に使うだけです。以下のPRが参考になると思います。

GPGのkeyringは以下のようにコマンドで出力できます。

$ gpg --export$KEY_ID> .travis/pubring.gpg      
$ gpg --export-secret-key$KEY_ID> .travis/secring.gpg      

またリリースの属人性をなくすため、リリース手順書も合わせてコミットしておくと良いでしょう。settings.xmlのテンプレートもあると、引継や暗号化済みファイルの更新に役立ちます。

Contributorに対するリマインド

GitHubPRやIssueにテンプレートを作成することができます。またContributing Guidelineを作成することもできます。従来はこれがユーザに対するほぼ唯一のIssue/PR作成時のリマインダでした。

ただチェックボックスをテンプレートに入れたとしても、すべてのContributorがこれを使ってくれるわけではありません。ので、個人的には以下のブログで紹介されているProbotに期待しています。

Maven3電子書籍の利用され具合(2017年)

$
0
0

ほそぼそと続けているMaven3の入門書「Maven3のはじめかた」ですが、最近はprh入れたりリポジトリの適当すぎた説明を修正したりといった微修正を行っています。

www.gitbook.com

で、意外にも年間2万人のユニークユーザがついたようです。以下が2016年12月〜2017年12月のデータです。

f:id:eller:20171230222121p:plain

どこからそんなユーザが流入したのか気になるところですが、KDDI ChatWork、Teratail、Yahoo!の社内サイトと思しきものがリファラにありました。どうやらMaven用語の説明に活用されたようです。今は正直プラグイン実装手法の説明が厚く用語解説が貧弱なので、用語解説系をもうちょっと強化したほうが良さそう。

検索サイトはGoogle, Yahoo, Bing, 楽天の順。インドやベトナム、ロシアの検索サイトと思われるものもありました。現地で働いている日本人が使っているのでしょうか。今日Google Analyticsを入れたので、次回は検索キーワードあたりも調べられるでしょう。

国別に見ると日本、米国、シンガポール、オランダ、中国の順です。米国とシンガポールには日本人技術者多い印象でしたが、オランダが入ってくるとは意外でした。ただユニークユーザ数は低いのでヘビーユーザがいらっしゃるのかもしれません。

f:id:eller:20180101222920p:plain

この本は今後も継続してメンテしていきます。コードは全てGitHubで公開されていますので、内容へのフィードバックやPRもお待ちしています。

チームビルディングのためにやったこと、できていないこと

$
0
0

これ↓読んで、自分の経験をまとめようと思ったのでメモ。

www.yutorism.jp

チームビルディング、ないし組織・オフィスの改善のためにやってきたことはけっこうある。反面、できていないこともかなりある。

やったこと、継続していること

社内技術勉強会

上海拠点設立時に董事長と話してやったのがこれ。せっかくCS専攻の人を集めたのだし、ポテンシャルある人ばかりなので、彼らが互いに刺激を与え合える機会を作ろうという狙いだった。当時は20名弱だったので、全員にスライドを使って企画意図を説明したのを覚えている。

最初は発表者が2,3名に偏ったり、開催時間が固まらなかったり(最初は朝開催を目指したが、結果的には夕方開催に落ち着いた)、発表が数週間連続でなかったりという問題も多かった。しかし結局は、私が異動でいなかった時期(1年間)も含めて6年間続けられている。継続するのが一番難しいので、これは普通に素晴らしいことだと思っている。

継続のコツは、やはりイベント自体を楽しいものだと思ってもらうこと、他の人を巻き込んで協力を得ることだと思う。魅力を理解してくれた数名が引き継いでくれたからこそ私が不在でもイベントが回ったし、今は自分が聞き込みや勧誘をしなくても社内交流促進の専門家が代わりに調べてくださっている。ので、最近の私はたまに発表するだけという立場。たぶん私が立ち上げ人ということを、新人は認識していないはず。

問題共有イベント

最近は拠点規模が大きくなって、拠点全体で何が起こっているのかを把握するのが難しくなってきた。また異なるチームで似たような問題をバラバラに解いているような状況も散見されるようになってきた。問題解決こそが仕事なのにこの状況は好ましくないだろうということで、従来人事評価時にやってきた成果発表とは別に、プロセスと問題とを拠点内で共有するイベントを立ち上げた。怒らないことを強調しないだけで、前述のイベントとほとんど同じ。

部署の壁を超えて数百人巻き込むので、コストが大きいことを個人的には気にしている。ので毎回アンケートで発表者と聴衆の両方から実際役に立ったのかフィードバックを得ているが、いまのところコストを成果が上回っている認識。今後も成果の評価と改善検討を続けていくつもり。

AMAイベント

これについては自分の上長が事業部で実践していたものをパクって上海に持っていっただけ。主に新人が持っているであろう疑問や、いわゆるhard questionを部長らが匿名(実名付記も可)で集めて一括で答える。文書化されてないルールや、歴史的経緯でそうなっているもの、(中国の)普通の会社でやっているのにやっていないこと(あるいはその逆)とかに関する質問が色々集まる。推測や疑問を検証できる機会を公式に作るだけで、教育やモチベートの切欠を作ることができる。問題回収と整理は非同期でできるので、複数人を一同に集めることもなく開催コストもそんなに高くない。

最初はQuestion Gathering Eventと呼んでいたが、最近AMAという言葉が身近で流行したので、今はAMAあるいはAsk Us Anythingと呼んでいる。

技術交流用WeChatグループ

WeChatでグループを作り、社員と元社員とでFOSSについて話す場としている。はてブと同じノリでURLをポンポン投稿する感じ。任意参加なので尖った技術者が集まりやすい。RustとかTaigaとかConduitとかはここでキャッチしている情報もある。新人には、興味を感じる分野を探す一助になっていればいいなと思っている。

MBO-S

これに関しては普通に目標管理の教科書を参考にやっている。変わったこともたいしてやってないはず。上長としては部の短期・中期目標(どのProblem Spaceにフォーカスするか)を明確に提示し、それぞれに固有名詞を付ける(Project FooBarとか)ことで、メンバー間交流が促進され挑戦・工夫がしやすい状態になるよう心がけている。自分のMBO-Sフォーマットは社内SNSで公開し、壁に貼って誰でも閲覧できるようにしている。

1on1

これも初めて6年になる。運用上工夫しているのは3点:

  1. 直接の部下(課長?)とは週次、間接的な部下とは月次で実施
  2. 時間を自由に使って良いことを前提として、聞きたいことリストをこちらから提示(情熱的に働けているか、やりたいことの妨げになっているのは何か、上長に期待しているのは何か、直近の全社集会について質問はあるか等)
  3. 1on1を受けてこちらがやることを、最後の時間でコミット

本当は2みたいな質問の提示は誘導に繋がるのでやらないほうが良いと思っているが、何も持ってこない人が散見されるので補助線として用意している。

参考にしている本は複数あるが、最近読んだのはフィードバック入門マネジャーの最も大切な仕事HIGH OUTPUT MANAGEMENTあたり。特にフィードバック入門のTeaching + Coaching = Feedbackという図式はわかりやすく応用がきく気がしている。

できていないこと、継続できなかったこと

ライトニングトークイベント

前述の社内勉強会の一環として、30分ずっとLTするようなイベントを考えたことがある。結果、3〜5分という短い時間で話し切ることに慣れさせることができずに終わってしまった。会社を一歩出ればLTの機会がたくさんある東京と違って、勉強会が少ない上海ならではの問題かもしれない。

輪読会、読書会

これが定着しない理由は明確で、私自身に成功体験がないから。どこかでちゃんと運営された読書会に参加して、感覚を身に着けたい。

今は本を一緒に読む代わりに、おすすめの記事や本を社内SNS等で発信している。今のところはCI/CDやMSAについて語る機会が多いので以下だが、随時アップデートしている。

休祝日のチームビルディングイベント

これは日本で開発合宿経験済みではあるのだが、自分が子持ちということやその他の事情から積極的にやる予定がない。上海の部下はともかく、日本の部下とはかなりやりにくいという事情もある。やる気と関心がある部下に、提案から丸投げている状態。

社外の人を巻き込んだ勉強会

これは1回だけやったことがあるが、会場と参加者の定期確保に失敗した。そもそも上海で定期的に勉強会を開催しているのがWiredcraftくらいなものなので、潜在市場はありそう。深センほどではないとしても、上海にはGoogleMicrosofteBayチームラボサイボウズも色々居るはずなので、ちゃんとツテを作って運用したい。

とりあえず現地日本人コミュニティに顔を出しつつ、上海のMeetup.comで定期的に参加できる勉強会を探していくつもり。


JJUG CCC 2018 SpringにてSpotBugsの話をします

JJUG CCC 2018 SpringでSpotBugs3.1系実装について話してきました

$
0
0

先週末に開催されたJJUG CCC 2018 Springに参加してきました。昨年に引き続き、SpotBugsに関する内容です。

20名ちょっとのエンジニアに参加いただき、3.1系実装で苦労しているところ、Java9対応が進まない理由などを話しました。Togetterはこちら

Maven Central Statisticsからもわかっていたことですが、まだFindBugsユーザのほうが多いですね。Java8移行を使っているならSpotBugsの方が安定&高速なので、ぜひ移行を検討いただきたいです。よくできていると好評のマイグレーションガイドもあります。

聴講したものの中では、アンカンファレンスが面白かったです。初めて参加したのですが、様々な立場の方がご自身の経験と考えをもとに意見を交換するのは参加していて楽しく感じます。こういう議論をもっと日頃からできると良いですね。また自分は参加しませんでしたが、海外登壇経験者のパネルディスカッションも面白かったようです。自分は海外在住なのにあまり参加経験がないので、そのうち行ってみたいところ。

SpotBugsプラグインを元にしたSonarQubeプラグインを実装する方法

$
0
0

SpotBugsプラグインの実装方法には公式ドキュメントがありますが、SpotBugsプラグインをSonarQube上で実行するための手法はまだ固まっていません。最近Guava Migration HelperのSonarQubeプラグインのリリースに動いているので、要点をまとめておきます。

SonarQubeプラグイン実装の基本

まずSonarQubeの公式ドキュメントに目を通しておきます。特にMarketplaceでの公開を前提としている場合は、Plugin Keyの命名に制約があったり、SonarCloudの利用が必須だったりしますので、制約についてよく読んでおくと良いでしょう。

Mavenプロジェクトを作る

Gradleサポートは公式ではないので、Mavenを選択します。SpotBugsプラグインと同じプロジェクトで管理すると、メタデータ作成(後述)で手間がかからないのでおすすめです。私のプロダクトではSpotBugsプラグインとSonarQubeプラグインとをサブモジュールとして管理するプロジェクトを使っています。注意点は以下の通りです:

  • SonarQubeプラグイン<packaging>sonar-plugin</packaging>にする。
  • sonar-packaging-maven-pluginの設定に<basePlugin>findbugs</basePlugin><requirePlugins>findbugs:3.5</requirePlugins>を入れる。sonar-findbugs v3.5は初めてSpotBugsを導入したバージョンなのでこれ以降のバージョンを指定するのが良い。
  • SpotBugsプラグインが何らかのライブラリに依存している場合、普通のパッケージとshadedパッケージと両方を用意すると良い。 shadedはAntユーザやCLIユーザなど推移的依存が自動的に解決されない場合(プラグイン手配置が必要な場合)に便利。 shadedだけ用意すると、推移的依存が自動的に解決される場合に同じライブラリを複数回ダウンロードするリスクや、dependencyReducedPomによって依存先のメタデータが隠匿されてしまう(例えばライセンス管理がやりにくくなる)問題も生じる。

rule.xmlを生成する

SonarQubeはfindbugs.xmlやmessages.xmlを読まないので、SonarQubeが読める形式でルールに関するデータを提供する必要があります。私はこれをMavenプラグインで自動生成しています。ルールによってタグを変える必要がある大型プロジェクトじゃない限り、これで十分だと思います。

コードを書く

基本的にはPlugin.javaとRulesDefinision.javaの2つで足ります。以下がサンプル:

注意点は以下の通りです:

  • Context#createRepository()の第一引数は"findbugs"である必要がある。 それ以外の値だと、sonar-findbugsが検知してくれないその結果 findbugs-include.xmlにBugが登録されないので、SpotBugsプラグインが解析に使われても結果一覧に出てこなくなる。

リリースする

あとはいつもどおりMaven Centralに公開した上で、SonarSourceコミュニティのフォーラムで申請すれば通るようです。私のプラグインはまだ申請中です:

英語ブログを新設しました

dockerでSonarQubeのインストールを楽にやる

$
0
0

クラスメソッドさんのブログでSonarQubeの紹介がされています。そちらの記事では記事の半分ほどを割いてインストール方法を説明していますが、dockerを使えばより楽に行えますのでその方法を紹介します。

dev.classmethod.jp

検証用のSonarQubeを立ち上げる

以下のコマンドで、組み込みデータベースを使用したサーバが立ち上がります。ユーザ名admin、パスワードadminでログインできます。 このコマンドは英文公式ページからの引用です。

$ docker run -d--name sonarqube -p9000:9000-p9092:9092 sonarqube

なおalpineを使ったイメージもあるのですが、2018年8月1日現在でClassNotFoundErrorが出るなど不安定なようです。7.1-slpineなどのバージョンではなく、7.1などのバージョンの利用を推奨します。

PostgreSQLを使ったSonarQubeを立ち上げる

組み込みデータベースでの運用は検証用にのみ推奨されていますので、本番運用はRDBMSの利用が必要です。 以下のページにSonarQubeとPostgreSQLを立ち上げるdocker-compose.ymlが紹介されていますので、これを保存したディレクトリでdocker-compose upすればSonarQubeとPostgreSQLが立ち上がります。

docker-sonarqube/recipes.md at master · SonarSource/docker-sonarqube · GitHub

プラグインのインストールを自動化する

$SONARQUBE_HOME/extensions/pluginsディレクトリにプラグインの.jarファイルを保存することで、プラグインをインストールし有効化できます。 例えばSonarQube 6.7.4 LTSに sonar-findbugsとそれが依存しているSonarJavaをインストールするDockerfileは以下のようになります:

FROM sonarqube:7.1

RUN wget -P $SONARQUBE_HOME/extensions/plugins/ --no-verbose https://github.com/spotbugs/sonar-findbugs/releases/download/3.7.0/sonar-findbugs-plugin-3.7.0.jar && \
    wget -P $SONARQUBE_HOME/extensions/plugins/ --no-verbose https://sonarsource.bintray.com/Distribution/sonar-java-plugin/sonar-java-plugin-5.6.0.15032.jar

Read The Docs利用者用にPRレビュー支援Probotを作りました

$
0
0

私がSpotBugsなどで使っているドキュメントホスティングサービス、Read The Docsを使う上で助けになるGitHub Probotを作成しました。

github.com

ドキュメントがいつもどおり全部英語なので、日本語での解説をここに書いておきます。

想定ユーザ

  • Read The Docsを使ったドキュメント作成を複数人で行っている
  • Read The Docsの設定をあまりいじっていない

解決する問題

  • Read The Docsが単体でPRレビュー用ビルドを提供していないので、レビューしてもらう時にステージングサイトやスクリーンショットを主導で用意しなければならない。

解決手法

  • PR作成時に docsディレクトリに変更が入っていれば、Read The Docs上でのビルドとホスティングを有効化し、アクセス用URLをPRに書き込む。

インストール方法

  1. Read The DocsプロジェクトをGitHubリポジトリと接続しておく、あるいはGitHub Webhookと統合しておく
  2. Read The Docsプロジェクトに rtd-botユーザをメンテナーとして招待しておく。
  3. Gitリポジトリ.github/config.ymlrtd.projectを作成し、Read The Docsプロジェクト名とその言語を指定する
  4. GitHub上でrtd-botを有効化する

注意点

  • いまのところ、Read The Docs側の設定項目(例えばドキュメントの場所など)には柔軟に追従できません。
  • 現バージョンのRead The Docsにおける「メンテナーの招待」は、「全権限の委譲」にほかなりません。不安な場合はご自身でProbotをホストいただけます。

技術的な工夫と、今後の開発の予定

このプロジェクトではCommitizenSemantic Releaseを導入しました。思っていたよりも使いやすく、またDependabotがすでにcommitizen風コミットコメントに対応していたため、特に導入に障害はありませんでした。MavenやGradleでも使えたら良いんですが、そこはまだハックが必要そうです。

Read The DocsのAPIはまだ機能不足が目立ちます。最近出たAPI v2でも認証機能すら無く、公開データへの読み取りアクセスしかできません。 今回はこの問題の回避にPuppeteerを使っています。つまり管理画面をNode.jsで操作しています。だいぶダーティハックですが、利用規約上も問題ないはずです。画面の更新には逐次追随する必要がありますが、過去の経験から言ってRead The Docsの画面はさほど大きく変更が入らないと思われます。

直近の予定としては、i18nには対応したいと考えています。他にも対応必要な設定があればROADMAP.mdに追記のPRを送ってください。

2018年のOSS活動状況まとめ

$
0
0

GitHubによると、今年は合計950 Contributions(25日時点)でした。仕事でほぼ使ってないのにこの数字というのは、多いのでしょうか少ないのでしょうか。

SpotBugs周りの開発

2018年もSpotBugsが一番活発な開発でした。新機能開発はほぼ無く純粋なバグ修正がほとんどですが、リリース周りも担っていたので100 commitsを超える貢献をしていました。

f:id:eller:20181225115534p:plain
contributors of spotbugs 2018

同organizationの他プロジェクトでもsonar-findbugs 48 commits, spotbugs-gradle-plugin 43 commits, spotbugs-archetype 17 commitsという感じで、Mavenプラグインを除けば最も活発なcontributorでした。

個人プロジェクト

個人プロジェクトではrtd-bot 72 commits, errorprone-slf4j 46 commits, findbugs-slf4j 44 commits, gradle-helper-for-java-8 40 commits, javadocky 39 commits, what-is-maven 13 commitsという感じでした。

rtd-botで使っているGitHub Probotはいろんな自動化が気軽にできそうで楽しいです。Sentryでサービスの監視をしていますが、Heroku上でChromeが起動しないことがあり、サービス自体はあまり安定させられていません。コストを掛けてサーバのスペックを上げないと解決でき無さそうなので、Read The Doc側のAPIが整備されるのを待つ形です。

今年でErrorproneプラグインもだいたい書けるようになり、これでPMD・Checkstyle・SpotBugs(FindBugs)・ErrorproneとJava周りの静的解析ツールはひととおりプラグインを実装できるようになりました。最近はJenkinsやMavenプラグインに加えGradleのプラグインも学習中なので、ビルド周りの自由度はだいぶ上がった気がします。

個人的に気になっているProject Reactorについては、Javadocky以外に使いみちを見いだせていないのが残念な感じです。流行りのサーバーレスと合わせるならSpring Cloud Functionのような使いみちになるのでしょうが、そもそもサーバーレスではSpring自体ほぼ使わないという……。GraalVMでの起動高速化が一般的になれば別でしょうが、それまではJavaを利用しないという選択肢も有力だと個人的には考えています。

来年の抱負

SpotBugs本体は旧バージョンのメンテナンスを止めて新機能開発に注力できる予定なので、以前からやりたいと話しているマルチスレッド対応を盛り込めればと思っています。1年でできるとは正直思ってませんが、とりあえず依存関係を整理してスレッドアンセーフなクラスを特定することはできるでしょう。おそらくBCELに依存するほぼすべてのDetectorがダメだとは思いますが……。

加えるなら、TypeScript・Kotlin・Rustといった言語の開拓でしょうか。基礎はもうあると思いますし、簡単なツールなら実装済みなのですが、もう少し複雑な事例も経験しておきたいところです。


2019年初頭でのMaven Site作成における注意点

$
0
0

最近新しいMaven Plugin用サイトを作ったので、mvn siteで作成できるサイトについて現時点での注意点をまとめる。

skinについて

maven-fluido-skinが最も使われていてかつ実用的と思われる。以下の記述はこのskinのv1.7を利用することを前提とする。

maven-site-pluginの設定方法

Maven3から<reportPlugins>による設定が可能になっているが、最新の公式サイトでは非推奨になっているので利用を避ける。

This new configuration format is not actually ready for end-users: please don't use it for the moment.

Copyright情報の生成

ページのフッターにCopyright情報が記載されるが、これはpom.xml<organization><inceptionYear>から情報を得て生成される。データが得られないとCopyright Holderが空になり違和感があるので、記入しておくと良い。

Markdownの利用

maven-site-plugindoxia-module-markdownに対する依存を追加すれば良い。.mdファイルはsrc/site/markdown以下に置く。

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-site-plugin</artifactId><version>3.7.1</version><dependencies><dependency><groupId>org.apache.maven.doxia</groupId><artifactId>doxia-module-markdown</artifactId><version>1.8</version></dependency></dependencies></plugin>

Maven Plugin用サイトの生成

Requirement 情報の生成

plugin-info.htmlMavenJDK 1.8、MemoryそしてDisk SpaceのRequirementを明記することができる。これはmaven-plugin-pluginの機能で、<requirements>を利用して設定できる。他にも特殊なRequirementがあるなら<others>を使って明記することもできるようだ。

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-plugin-plugin</artifactId><configuration><requirements><maven>${maven.version}</maven><jdk>1.8</jdk></requirements></configuration></plugin>

HelpMojoの作成

昔から変わらないのでコピペで良い。

Java屋がsemantic-releaseに思うこと

$
0
0

最近Java周りでもsemantic-releaseの利用機会が増えています。Gradle pluginMaven pluginが生まれ、特に後者はyarn*1で実行されるため既存のプラグインとも組み合わせやすく、JavaScriptと比較しても遜色ない状態と言えそうです。

2019年3月時点で、Java特にMavenがどのようにsemantic-releaseを活用できるのか、まとめてみます。

semantic-releaseとは

プロジェクトにおいて以下の制約を導入することで、リリース作業をより一段階自動化する仕組みです。

  1. Semantic Versioningを使ったバージョン番号の付け方
  2. Conventional Commit Messagesを使ったコミットコメントの書き方

すでにJavaコミュニティにおいてもSemantic Versioningは標準となっているため、実際に学ばなければならないのはSemantic Commit Messageだけと言えます。

semantic-releaseは具体的なリリース作業を定義しません。このため使っているプロジェクト管理ツールやCIサービスを問わずに利用可能です。代わりに、リリース手順を構成するステップを定義しており、利用者はステップごとに必要な処理をフックできます。 これは、Mavenがビルドライフサイクルを構成するフェーズを定義しているのと近いです。Maven自身が各フェーズにおける具体的な処理を定義せずプラグインに委ねているように、semantic-releaseも具体的なリリース作業の定義をプラグインに委ねています。

各Stepの説明はsemantic-releaseのREADME.mdに書かれています:

Step名 説明
Verify Conditions リリースに必要な条件がすべて揃っていることを確認する
Get last release Git tagsから最新(前回)のリリースバージョンを取得する
Analyze commits 最新(前回)のリリースから今回のリリースまでに含まれるすべてのコミットを解析する
Verify release リリース可能な状態かどうか検証する
Generate notes 最新(前回)のリリースから今回のリリースまでに含まれるすべてのコミットからリリースノートを生成する
Create Git tag 新しくGitタグを作成する
Prepare リリースの準備をする
Publish リリースを出荷する
Notify 新しく作成したリリース、または発生したエラーについて通知する

GitHub Actionsを使えば、PR後にPrepare Stepまで処理を進め、承認を受けたらPublish & Notifyするという運用もできそうです。出荷承認プロセスを持つコミュニティでも活用できるでしょう。

Mavenとの併用

semantic-releaseをMavenと併用する場合、semantic-releaseがMavenを実行する形になります。Publish Stepでmvn deployする形です。

package.jsonは必須ではないですが、実際にはこのように作成してしまったほうがプロジェクトの見通しは良くなると思われます。これはpom.xmlをコミットするために@semantic-release/gitのカスタマイズが必要となるためです。またdevDependenciesにsemantic-releaseとそのプラグインが列記されるため、それらのバージョン管理がしやすくなる利点もあります。 プロジェクトにpom.xmlpackage.jsonが同居するので、CIツール側で設定ファイルの有無によるビルドツールの推定をしている場合は注意が必要かもしれません。

高速なリリースが行えるのが大きな利点

semantic-release最大の利点は、なんと言っても頻繁にリリースが行えることです。何も考えずPull Requestをマージするだけで、すべてのリリース作業が実施されMaven Cental等にデプロイを行うことができます。LeanやContinuous Deliveryが証明したように、高速かつ頻繁にユーザへ変更を届けることはプロジェクトの成功へダイレクトに効きます。導入可能なプロジェクトでは速やかに入れていくことが望ましいと思います。

他には、semantic-releaseを利用することでリリースマネージャの手作業、例えばタグ打ちやCHANGELOG作成を自動化できる点も嬉しいです。GitHub Releaseの更新のような従来から別の自動化手法があったものも、コミットコメントをSingle Sourceとして利用する手法に切り替えることで、透明性と正確性を確保できます。

考えられるデメリットはそこまで大きくない

一般に、頻繁なリリースはユーザに追随するための負担を強いる可能性がありますが、semantic-releaseはバージョン番号をSemantic Versionに従った形で決めるので、ユーザもバージョン更新の必要性と負担を簡単に見積ることができます。デプロイ回数が増えるのでMaven Repositoryの記憶容量が気になるかもしれませんが、メリットに比較して十分に安いコストではと感じます。OSS開発においてはここは特に気にならない問題でしょう。

Semantic Commit Messageをチームに普及するのが最初の難関か

デメリットが小さいならJavaコミュニティにもすぐに普及するでしょうか?個人的には懐疑的です。大きく分けて2つの問題があります。

まずSemantic Commit Message自体、そこまでクリアに定義されているものではありません。AngularJS Commit Message Conventionsから生まれたもので、多様なプロジェクトに適合できるものにはまだなっていません。

またSemantic Commit Messageに定義されていないコミット種別を利用することも禁止されていません。プロジェクトごとにコミット種別の亜種が生まれ、収集つかなくなる可能性がありそうです。
例えば依存ライブラリのバージョンアップはchore, build, fix, securityのいずれにするべきでしょう?実際にProbotプロジェクトではchore(package), chore(dependencies), build(package), fix(package)のすべてが使われています。1プロジェクト内でも統一されていないわけです。
今のところ周辺ツールもあまり賢くないので、PRレビュー時にレビュアーがコミット種別を確認する必要があります。プロジェクト導入時の最初の難関は、不明瞭な定義をローカルルールに落とし込んできちんと普及させる、このプロセスにあるでしょう。

次に、Semantic Commit Messageの利用を忘れたときに、コミットコメントの修正が面倒という問題があります。Gitはこれをサポートしていますが、コミット履歴の修正は基本的な操作と比べて難度が高いため、ある程度の慣れが必要です。 これについてはPRをSquash Commitしてしまうという、若干粗い解決方法があります。GitHubはSquashしてマージする時のコミットコメントをPRタイトルから取るので、PRタイトルをSemantic Commit Messageに準じたものにすればよいのです。PRタイトルはWeb画面から簡単に修正できるので、慣れていない人でも回しやすいでしょう。なおSemantic Commit Probotはこの運用を想定した実装になっていて、コミットコメントがSemantic Commit Messageとして不正な場合でもPRタイトルが問題なければパスしてくれます。

機能は十分なので運用経験と実績を積むべき時期

以上で、Java屋がsemantic-releaseに思うことを見てきました。

機能的には充分で、すぐにプロジェクトに適用することができます。nexus-staging-maven-pluginmaven-release-pluginなどの既存設定をそのまま使えるので、新規プロジェクトのみならず既存プロジェクトへの導入も簡単でしょう。

まだJavaコミュニティにおいてはさほど知名度がないため、コミュニティでの開発に浸透するのはまだ先だと思いますが、個人プロジェクトではぜひ使ってほしいです。ユーザが増え実績が積まれれば、Javaコミュニティにおいても利用が進むことでしょう。

*1:npmでも良いはずだが、semantic-release-pluginのドキュメントはyarnで統一されているので、長いものには巻かれておく

Gradleプロジェクト用semantic-releaseプラグインを書いた

$
0
0

Gradle用のsemantic-releaseプラグインJavaでsemantic-releaseを再実装したものしか無かったので、TypeScriptで書いたものを作りました。

github.com

./gradlew publishを叩くだけのシンプルなものですが、CI周りの設定はGradle側に寄せてあるはずなのでこれで問題なく運用できます。バージョンをgradle.propertiesで管理する必要がある点にのみ注意してください。

selenium-jupiterを試した

$
0
0

JUnit 5にTemporalyFolderに相当する機能がなかったため、自分のプロジェクトでは長らくJUnit4を使っていました。しかし5.4でTempDirが来たため、徐々にJUnit5に置き換えています。

その過程でSelenideを使った統合テストをJUnit5に置き換えたのですが、selenium-jupiterがなかなか便利でした。作業したリポジトリこちらです。 ただ一筋縄に行かない部分もあるので、備忘録を残します:

SpringBootTestとSelenideとの噛みあわせ

SpringBootTestにはランダムなポートでアプリケーションサーバを起動する機能がありテストの並列実行に役立ちます。 またselenium-jupiterはSelenideをサポートしており、テストメソッドのパラメータに SelenideDriverを指定するとインスタンスを作って注入してくれます。

さてSelenideにはbaseUrlという設定がありConfiguration.baseUrlにURL文字列を指定しておくとSelenideDriverインスタンス作成時に使ってくれます。 これによりテストメソッドではスキーマドメイン名、ポート番号などを省略した相対URLを指定するだけで済むのですが。SelenideDriverインスタンス@BeforeEachメソッドが実行されたタイミングで既に作成されているので以下のようにbaseUrlを指定しても効いてくれません。

@LocalServerPortprivateint port;

@BeforeEachvoid config() {
  Configuration.baseUrl = String.format("http://localhost:%d/", port);
}

@Testvoid test(SelenideDriver driver) {
  System.out.println(driver.config().baseUrl()); // デフォルトの http://localhost:8080/ になってしまう
}

現状きれいに解決する方法が見当たらないので、テストメソッドでは相対URLではなく絶対URLを使うようにしています。

SpringBootTestするならDocker内ブラウザは使わないほうが良い

selenium-jupiterではDocker内のブラウザを使うこともできるのですが、ドキュメント末尾に注意書きがあるようにローカルにアプリケーションサーバを建てているときは一筋縄では行きません。DockerコンテナからDockerホスト(localhost)にHTTP接続をする必要があるのですが、ホスト名を解決する統一的な手法が存在しないのです。特にLinux環境ではホスト名ではなくIPアドレスを取得する必要があり、一度 ip addr show docker0|grep 'inet '|awk '{$1=$1};1'|cut -d '' -f 2|cut -d / -f 1などの操作をしてシステムプロパティ経由でテストに対して渡す必要があり面倒です。baseUrlが使えればホスト名構築処理を抽象クラスで集中管理できたのでまだマシだったのでしょうが……。

他にもブラウザで何らかの問題が起こったときのトラブルシュートが面倒ということもあり、SpringBootTestを使う場合はDocker内ブラウザは使用しないほうが良いのではと感じました。Travis CIなら安定版のChromeをCI環境にインストールする方法があるので、コンテナを使う必要性もあまりありません。

Gradle用のGitHub Actions勘どころ

$
0
0

GitHub Actions のベータ版が個人リポジトリの方に来ているので、色々と試しています。使っているテンプレートプロジェクト実アプリケーションプロジェクトから、いくつか事例を紹介します。

なお各種単語の定義が公式サイトにあるので、いちど目を通すことをおすすめします。

テストレポートをworkflow runに添付する

upload-artifact actionを使うことで、テストレポートをworkflow runに対して添付することができます。

    - name: Build with Gradle
      run: ./gradlew build
    - name: Upload Test Report
      uses: actions/upload-artifact@v1
      if: always()
      with:
        name: test results
        path: build/test-results/test

if: always()がミソで、これがないとテスト失敗時にupload-artifactが実行されません。always()の説明は公式サイトにあります。

複数のjobを並列に実行する場合は、nameを固有かつ直感的な名前にしないと、レポートをダウンロードする際にどれを確認すべきかわからなくなってしまいますので要注意です。

wrapperとDockerコンテナどちらを使うべきか

Gradleを使ったビルドは、大きく分けて2つの方法が採れます。 Jobを実行しているマシンにJDKをインストールする方法と、Docker Hubで公開されているgradleのイメージを使う方法です。 なおGradle用の非公式actionが存在しますが、特にメリットがないため検討していません。

Jobを実行しているマシンにJDKをインストールしてGradle Wrapperを叩くケースが最もシンプルと言えます。 Wrapperを使うため、開発者が手元で使うGradleとバージョンを合わせることも容易です(Wrapperを使わずGradleをインストールしてPATHに通しても良いが特にメリットがない)。

    steps:
    - uses: actions/checkout@v1
    - name: Set up JDK 11
      uses: actions/setup-java@v1
      with:
        java-version: 11
    - name: Build with Gradle
      run: ./gradlew build

Docker Hubのgradleイメージを使う場合は、with.argsを使って実行するコマンドを指定します。 e2eテストのようなコマンドに依存するビルドでは使いにくい面もあると考えられますが、持ち運びの効くコンテナでCIを回せるのは嬉しい点です。YAMLファイルの見通しも比較的良いです。

    steps:
    - uses: actions/checkout@v1
    - name: Build with Gradle
      uses: docker://gradle:5.6-jdk11
      with:
        args: gradle build

なお今のところ、この2つの方法には速度の違いはないようです。Dockerコンテナを使うとsetup-javaがなくなりGradleインストールの時間が短縮される反面、イメージをpullする時間がかかります。Dockerイメージやローカルファイルシステムのキャッシュが導入されたら、このあたりは変わってくるかもしれませんね。

Maven Remote Repositoryは何が良いか

Organizationで使う場合はActionsを実行するリージョンが選べるそうです。

が、少なくとも私の個人リポジトリでは選択できない状態です。のでネットワーク的にどこが近いのか確信はないのですが、いくつか実行して試してみました:

試行回数を重ねないと確かなことは言えませんが、少なくともMavenリポジトリの物理位置がビルド速度に影響出るのは間違いありません。自前でRemote Repositoryを運用している場合は、それを物理的にどこに置くか考える必要がありそうです。あるいはpackage-registryを使っても良いかもしれませんね。

SonarCloudを使う

これは至ってシンプルで、sonar.host.url, sonar.organizationそしてsonar.projectKeyシステムプロパティで指定するだけです。公式フォーラムで紹介されています。これだけで通常の解析もブランチ解析PR解析もいけます。

    - name: Build with Gradle
      run: ./gradlew sonarqube -Dsonar.organization=foo -Dsonar.projectKey=bar -Dsonar.host.url=https://sonarcloud.io
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }}

上記の例では -Dオプションを使って指定していますが、build.gradleに直接書いても大丈夫です。 環境変数として GITHUB_TOKENSONAR_TOKENの設定が必要です。

READMEにステータスバッジを埋める

公式ドキュメントが公開されましたので、それを参照すればOKです。

~/.gradle をキャッシュしたい!

GradleやMavenを使っていると、Mavenリモートリポジトリからダウンロードしたjarファイルをキャッシュしたくなります。残念ながら現時点ではその方法は無いようです。

Actions toolkitに入っているtool-cacheを使って~/.gradle/cachesをキャッシュするActionsを書いてみたのですが、キャッシュの保存はできてもキャッシュされたディレクトリをfindできません。Debugログを有効化しても特に情報は得られませんでした。

Javaに限らず他の言語のコミュニティにも期待されている機能だと思いますので、今後に期待しています。

Viewing all 157 articles
Browse latest View live