コードレビュー改善のために
Jenkinsと IntelliJ IDEAの プラグインを自作
してみた話
2023/6/4 JJUG CCC 2023 Spring
Tasuku Nakagawa (@getupmax)
Leisure Product Department
Rakuten Group, Inc
2
コードレビュー
でどこ(何)を見ていますか?
• 仕様通りか
• コードの質
• テストの質
• カバレッジ
3
Bitbucket Server
には、プルリクエストにカバレッジを表示する機能(API)がある
→ これを使わない手はない
https://ja.confluence.atlassian.com/bitbucketserver/code-insights-966660485.html
4
カバレッジ表示機能
をCIパイプラインに組み込みたい
リポジトリのクローン
コンパイル
テスト
カバレッジ計測
カバレッジ表示
https://www.jenkins.io/
5
カバレッジ表示API
をJenkinsから利用するためには
• 既存のプラグインを利用する
→ 調べた限りなさそう😭
• Jenkinsfileにベタ書きする
→ Jenkinsfileの肥大化 + テストできない🤮
6
Jenkinsの特徴
• Javaで書かれている
• プラグインで拡張可能
→ プラグインもJavaで書ける
カバレッジ表示APIを呼ぶプラグインを自作すれば解決👍
7
Jenkinsプラグインの作り方
1. 雛形を生成する
2. インターフェースを定義する
3. ロジックを書く
4. テストする
5. Jenkinsにデプロイする
8
雛形を生成する (1/5)
MavenのArchetypeプラグインから生成できる
$ mvn -U archetype:generate 
-Dfilter=io.jenkins.archetypes:hello-world-plugin
9
インターフェースを定義する (2/5)
Jenkinsには2種類の入力がある
1. ジョブごとの設定値
/job/{name}/configure から設定する
2. Jenkins全体の設定値
全てのジョブで共有される
/manage/configure から設定する
10
インターフェースを定義する – ジョブごとの設定
コンストラクタとセッターを
介して取得
11
インターフェースを定義する – Jenkins全体の設定
シリアライズされているので、ヘルパーを介して取得
12
ロジックを書く (3/5)
perform メソッドがエントリーポイント
13
(マニュアル)テストする (4/5)
1. mvn hpi:run
2. localhost:8080/jenkins にアクセス
3. 開発中のプラグインを含んだJenkinsを
利用できる
mvn clean で全てのデータが飛ぶので注意(n敗)
14
デプロイする
1. mvn hpi:hpi でhpiファイル(アーカイブ)を生成
2. Jenkins の /manage/pluginManager/advanced にアクセス
3. hpi ファイルをアップロード
15
出来上がったもの
https://github.com/T45K/Bitbucket-Server-Code-Insights-plugin
16
やってみた結果
チームでは…
• JaCoCoが出力したHTMLを確認する必要がなくなった
• 不足しているテストをレビューで指摘しやすくなった
• テストをしやすくするためのリファクタリングに繋がった
個人では…
• 普段何となく使っているJenkinsをより深く理解できた
• 新しいことを学びたい欲を満たせた
17
一方で…
同僚
• カバレッジ表示機能に興味がある
• しかし、チームでJaCoCoも
Jenkinsも使っていない
https://irasutoya.com/
18
なので
同僚
IntelliJで計測したカバレッジを
送信できるようにしてほしい
19
つまり
コードとテストを書く
テストを実行してカバレッジを取る
得られたカバレッジを変換し
Bitbucket Server API を呼ぶ
Copyright © 2023 JetBrains s.r.o. IntelliJ IDEA and the IntelliJ IDEA logo are registered trademarks of JetBrains s.r.o.
20
IntelliJ IDEAの特徴
• Javaで書かれている
• プラグインで拡張可能
→ プラグインもJavaで書ける!
IntelliJ IDEA のプラグインを自分で書けば解決👍
21
IntelliJプラグインの作り方
1. 雛形を生成する
2. インターフェースを定義する
3. ロジックを書く
4. テストする
5. IntelliJにインストールする
6. 公開する
22
雛形を生成する (1/6)
IntelliJの "New Project" から生成する
23
インターフェースを定義する (2/6)
ビューはSwingを使って定義する(KotlinだとDSLが使える)
24
ロジックを書く (3/6)
AnAction#actionPerformed がエントリーポイント
25
(マニュアル)テストする (4/6)
1. ./gradlew runIde
2. 開発中のプラグインが入った
IntelliJが立ち上がる
./gradlew cleanすると全てのデータが(ry
26
IntelliJにインストールする (5/6)
1. ./gradlew buildPlugin
2. build/libs 下にjarファイルが生成される
3. Preferences > Plugins からインストールする
27
公開する (6/6)
JetBrainsのプラグインマーケットから公開できる
28
出来上がったもの
https://plugins.jetbrains.com/plugin/20589-coverage-uploader-for-bitbucket-server
29
学び
• 色々な設計方針を知った
• Jenkinsでは特定の命名規則に従わないといけない(e.g., doFillXXXItems)
• IntelliJではサービスロケータを多用する
• 普段はWeb一辺倒なので新鮮だった
• 普段自分が使っているツールをより理解できた
• ファイルの抽象化、機密情報の持ち方、etc.
30
苦労した点
• 機能の実現方法が全然分からない時がある
• 周りに知っている人がいない
• ニッチな機能だと記事が全然ない
• ドキュメントが多すぎてどこを見れば良いか分からない
• やっぱりドキュメントが壊れている
• 壊れているのを報告することが大事
31
まとめ
• JenkinsとIntelliJ IDEAのプラグインを自作した
• どちらのツールもJavaで作られている
• プラグインもJavaで書ける
• 「ないのなら作れば良い」という考えが身についた
みなさんも是非プラグインを自作してみてください!
コードレビュー改善のためにJenkinsとIntelliJ IDEAのプラグインを自作してみた話

コードレビュー改善のためにJenkinsとIntelliJ IDEAのプラグインを自作してみた話

Editor's Notes

  • #2 こんにちは、楽天の中川と申します。 今回は「コードレビュー改善のためにJenkinsとIntelliJ IDEAのプラグインを自作してみた話」というタイトルで発表させていただきます。 ぜひ楽しんでいただければと思います。よろしくお願いします。
  • #3 まずはコードレビューについて、質問させてください。 みなさんはコードレビューの際に、どんなことを確認しますか。 コードが仕様通りというのはとても重要なポイントですね。 他にも、コードの質やテストの質、また、テストの質の一環として、カバレッジを確認する方も多いと思います。
  • #4 弊社では、GitリポジトリのホスティングにAttlasianのBitbucket Serverを使っています。 このシステムには、プルリクエストのdiff画面にカバレッジを視覚的に表示する機能があり、この機能を利用するためのAPIが提供されています。 社内では僕が知る限りこの機能を使っているチームはいなくて、知ってる人も少ないと思うんですけど、 僕が初めてこの機能を知った時相当便利だなと感じて、これを利用したらコードレビューのプロセスを改善できるんじゃないかと感じました。
  • #5 私たちは、CIツールとしてJenkinsを使っています。 CIパイプラインとして、今まではプルリクエストを作成するたびにリポジトリのクローンから、コンパイル、テスト、カバレッジ計測までを行なっていました。 ここに、先ほど紹介したカバレッジ表示を組み込みたいと考えました。
  • #6 先ほど、カバレッジ表示機能を利用するためのAPIがあると説明しました。 なので、Jenkins内でJaCoCoのカバレッジ計測結果をAPIのリクエストボディに変換して、APIを呼び出せば良さそうです。 通常、Jenkinsで何らかの処理を行う場合、プラグインを利用するか、Jenkinsfileというジョブを定義するファイルに処理をベタ書きするかの二択だと思います。 しかし、問題点として、今回の目的に合致するプラグインは残念ながら見つかりませんでした。 Jenkinsfileにベタ書きする方法は、Jenkinsfileが肥大化するうえに、書いた処理をテストできないという理由があるため、あまり取りたくありません。
  • #7 ここでJenkinsの知っておいてほしい特徴が二つあります。 まず、Jenkins自体はJavaで書かれています。 また、Jenkinsはプラグインを用いて簡単に拡張できます。 JenkinsはJavaで書かれているため、プラグイン自体もJavaで書けます。 そこで、カバレッジ表示APIを呼ぶプラグインを自分で作ろうという結論に至りました。
  • #8 次に、Jenkinsプラグインの作り方について軽く触れたいと思います。 僕は今回のJenkinsプラグインを次の5つのステップで作りました。
  • #9 まずはJenkinsプラグインの雛形を生成します。 今回はプラグイン作りが初めてだったので、動く雛形を生成し、そこからインクリメンタルに自分の実装を入れていく方法を取りました。 Jenkinsプラグインの雛形はMavenのarchtypeプラグインから生成できます。 次のコマンドは、Hello Worldを出力するJenkinsプラグインを生成します。
  • #10 次にインターフェースを定義します。 ここでいうインターフェースとは、ユーザの入力をプログラム側で受け取る方法を指します。 Jenkinsには2種類の入力方法があります。 1つめはジョブごとの設定値です。 2つめは、Jenkins全体での設定値です。 ここで設定した値は、作成したプラグインを利用するすべてのジョブで共有されます。
  • #11 ジョブごとの設定値は、プラグインのエントリーポイントとなるクラスのフィールド変数として、Jenkinsがコンストラクタやセッターなどから注入します。
  • #12 一方で、Jenkins全体の設定値は、JenkinsのローカルにXMLとして保存されているので、ジョブの実行時にヘルパーを介して取得しに行く必要があります。
  • #13 インターフェースを定義したら、そこからゴリゴリロジックを書いていきます。 performメソッドがエントリポイントなので、そこからメソッドやクラスを呼び出すという形で開発していきます。
  • #14 開発が一通り済んだら、動くものを手で確認します。 Jenkinsのプラグイン開発には、サンドボックスを立ち上げるコマンドが用意されています。 この時に注意なのが、サンドボックス環境で使ったデータは全てtargetディレクトリ下に置かれるため、…
  • #15 プラグインのアーカイブであるhpiファイルが生成される Jenkinsのプラグイン管理画面 プラグインを直接デプロイするという項目があるので、 こうすることで、最終的に作ったプラグインを実際のJenkinsで利用することができます。
  • #16 今回作成したプラグインはGitHubで公開しています。 興味があったら、ぜひコードを見に行ってみてください。
  • #17 Jenkinsのプラグインを自作して、先ほど説明したカバレッジ表示機能をチームで使えるようにしました。 その結果として、まずチームとしては、プルリクエストでのカバレッジの確認が圧倒的に楽になりました。 これまで、カバレッジを視覚的に確認したい場合、JaCoCoのHTMLを確認しにいく必要がありましたが、それがなくなりました。 その結果、不足しているテストをレビューで指摘しやすくなりました。 また、テストを足しやすくするためにリファクタリングしようという意見が出ることもありました。 コードレビュープロセスを改善できたかなぁと感じています。 また、個人としては、 普段何となく使っているJenkinsを深く理解できたのと、新しいことを学びたい欲が満たせたので、やって良かったなぁと思っています。
  • #18 これで僕達のチームのコードレビュー改善は完了したんですが、この話を聞いた隣のチームのメンバにこういう相談を持ちかけられました。 その人曰く、その人を含めたチームメンバーも、Bitbucketのカバレッジ表示機能に興味がある。 そのチームの開発にはJaCoCoもJenkinsも使っていないので、今回僕が作ったプラグインを利用できない。
  • #19 そこで、IntteliJでカバレッジを計測して、その結果をBitbucketに送信できたりしないかなぁという話をしました。
  • #20 つまり、コードとテストを書く、カバレッジを計測する、その結果をAPIのリクエストボディに変換してAPIを呼ぶ、 この一連の流れをIntelliJ上で完結するようにしたいとのことでした
  • #21 ここで、IntelliJの特徴について紹介します。 IntelliJはJavaで作られています。また、プラグインを用いて機能を拡張できます。 つまり、Jenkinsと一緒で、プラグインもJavaで書けるので、IntelliJのプラグインを自作しよう、という発想に至りました。
  • #22 IntelliJのプラグイン開発ですが、Jenkinsの時と同じように、雛形を作るところからIntelliJにインストールするところまで、それに加えて、公開する方法について紹介したいと思います。
  • #23 まずは雛形を生成します。 IntelliJプラグインの生成はIntelliJ自体から行うことができます。 New Projectの画面から"IDE Plugin"を選択してください。
  • #24 次にインターフェースを定義します。 IntelliJでは、UIと入力値の取得はSwingを用いて書きます また、JetBrainsはSwing用のKotlinのDSLを提供しているので、Javaで生のSwingを書くのに比べて、すっきりしたコードを書けます。
  • #25 次にロジックを書いていきます。 エントリーポイントは、AnActionクラスを継承したクラスのactionPerformedメソッドです。
  • #26 ロジックを書いたらテストをします。 runIdeコマンドを実行すると、サンドボックス環境が立ち上がります。 注意点としては、こちらもbuildディレクトリの下にすべてのデータが格納されるため、cleanを実行するとデータが飛びます。
  • #27 buildPluginコマンドでjarファイルを生成できる
  • #28 最後に出来上がったものを公開しましょう。 IntelliJのプラグインは非常に簡単に公開できます。 JetBrainsのプラグインマーケットに"Upload plugin"という項目があるので、そこにアクセスして、アーカイブファイルと必要な情報を登録することで公開できます
  • #30 IntelliJのプラグインの開発方法の説明は以上です。 まとめに入っていきたいと思います