電通総研 テックブログ

電通総研が運営する技術ブログ

IntelliJプラグイン開発の始め方~環境構築編~

こんにちは。電通総研ITの寺尾です。
前回に続き、以前ご紹介したIntelliJ向けプラグインDoma Tools」の開発経験を基にした、プラグイン開発方法についてお話していきたいと思います。

前回はこちら:IntelliJプラグイン「Doma Tools」のご紹介~OSSなプラグイン開発~

まず今回は、環境構築からリリースまでの大まかな流れをご説明します。

※Gradle、GitHubの基本的な知識があると本記事の内容が理解しやすくなります
※記事内のGitHubリポジトリのリンクは、本記事作成時点での最新のコミットをリンクしています

IntelliJプラグインを作ってみよう

日本国内からマーケットプレイスにあげられているIntelliJ向けプラグインは、比較的少ない傾向にあります。

プラグイン開発に興味はあるけど始め方がわからない」、「マーケットプレイスに出すって難しそう」
…と感じられている方に、本記事が取っ掛かりになれば幸いです。

前提

プラグイン開発で用意するものは以下になります。

1.環境構築

Doma Tools」はJetBrainsが用意しているIntelliJプラットフォームプラグインテンプレートをベースにしています。
まずはこのリポジトリをクローンすることで、基本的なプロジェクト構成を構築できます。

プロジェクトはGradleプロジェクトとして構成されており、ビルド、リリースを実行するためのGradleタスクやGitHub Actionsも、テンプレートに用意されています。

参考

2.プラグイン設定

プラグインの名前やサポートするバージョンなどを、自身のプラグインの設定に変更します。
プラグインの設定は以下のファイルを編集して管理します。

IntelliJ公式ドキュメント

plugin.xml

plugin.xmlは、マーケットプレイス上のプラグイン識別IDやプラグイン名、開発元情報、プラグインで提供する機能を設定するファイルです。
実装をしても、このファイルへの設定を忘れると機能を利用できないためお忘れずに!

例えば、「Doma Tools」ではアクション機能をプラグインで提供する場合は以下のように記述しています。

  • actions: アクションメニューをグループ化するタグ
  • group: アクショングループの設定。グループ名やどのメニューにアクションを追加するなどを設定
  • action: アクション情報を記載するタグ
    • id: アクション機能の識別ID(任意のID)
    • class: 実装したAnActionのサブクラスの完全修飾クラス名
    • text: アクション表示名
    • description: アクションの説明
    • keyboard-shortcut: デフォルトのショートカットキーを登録するタグ
<actions>
    <group
      id="org.domaframework.doma.intellij.DomaToolGroupActions"
      text="Doma Tools"
      popup="true"
      icon="AllIcons.Nodes.AbstractClass">
      <add-to-group
        group-id="EditorPopupMenu"
        anchor="last"
       />
      <action
        id="org.domaframework.doma.intellij.action.JumpToSQLFromDao"
        class="org.domaframework.doma.intellij.action.dao.JumpToSQLFromDaoAction"
        text="Jump to SQL"
        description="Jump from DAO file to SQL file">
        <keyboard-shortcut keymap="$default" first-keystroke="alt D"/>
      </action>
    </group>
  </actions>

拡張ポイントの実装はextensionsタグ内に記述します。以下はコード検査機能の設定例です。

  • inspectionToolProvider: コード検査機能を登録するタグ
  • implementation: 実装したInspectionToolProviderサブクラスの完全修飾クラス名
<extensions defaultExtensionNs="com.intellij">
<inspectionToolProvider implementation="org.domaframework.doma.intellij.inspection.dao.provider.SqlFileExistProvider" />
</extensions>

gradle.properties

gradle.propertiesは、ビルドスクリプトで参照されるプロジェクトプロパティを設定するファイルです。
テンプレートでは、ビルド時のプラグインバージョンやプラットフォームバージョンの設定をこのプロパティファイルから参照します。

【補足】 一部のプロパティはplugin.xmlと同様の項目を表すものがありますが、ビルドスクリプトによってgradle.propertiesの内容で設定が参照、上書きされます。

build.gradle.kts

build.gradle.ktsは、Gradleのビルドスクリプトを実装するファイルです。
プロジェクトの依存関係や、IntelliJプラットフォームプラグインのビルド、テスト、リリースに関わる設定も記載されています。

テンプレートではリリースに必要なプラグイン情報の収集処理などが実装されており、基本的には追加の実装なしで利用することが可能です。

【補足】 Doma Toolsでは、リリースノートやCHANGELOG.md内容の更新、次リリースの仮バージョン生成など、運用に関わる処理をbuild.gradle.ktsGitHub Actionsの追加実装で自動化しています。

参考:パッケージのバージョン管理

build.gradle.ktsに記載するライブラリやプラグインバージョンは、Gradleのバージョンカタログで管理することがおすすめです。

カタログファイルlibs.versions.tomlにまとめて記載しておくことで、依存パッケージのバージョン管理ツールが自動で最新バージョンへのアップデートを提案してくれます。

【補足】 Doma ToolsではRenovateを採用しており、依存パッケージに最新バージョンがリリースされると、カタログファイルに記載のバージョンを更新するPull Requestを作成してくれます。
Renovate

3.実装

アクションやコード補完などIntelliJに追加したい機能を実装します。
公式ドキュメントやOSSプラグインコードも参考にしてみましょう。

機能によって、IntelliJプラットフォームで指定されたサブクラスを作成します。
継承するクラスや実装するインタフェースの一覧は公式ドキュメントをご参照ください。

機能実装やテストに関する詳細な説明は、順次投稿していく予定です。
先に基本的な実装方法が気になる方は、IntelliJのサンプルプロジェクトやドキュメントをご覧ください。

参考:開発で役立つプラグイン

参考:コードの品質を高める

プロジェクトの品質を向上させるために、コードフォーマットを統一します。
Doma Tools」では以下プラグインを使用しています。

また、タイプミスや変数のアクセスレベルなどを検査することもプロジェクトの品質向上につながります。
IntelliJはQodanaと連携したコード解析が可能です。詳細は公式ドキュメントをご参照ください。

参考:OSSとコミュニティの活用

拡張ポイントやインタフェースを実装しているOSSリポジトリを検索できるサイトです。

IntelliJプラットフォームプラグイン開発者の集うコミュニティです。
実装の悩みについては、こちらでアイデアを探してみましょう。

4.動作確認

実装したプラグイン機能をデバッグ環境で確認します。

デバッグ起動する

Run Pluginデバッグモードで起動し、開発したプラグインをインストールした想定の仮想的なIntelliJ環境を立ち上げます。
別ウィンドウで起動するIntelliJ上で実際にプラグイン機能を試し、バグ調査や動作確認が行えます。

【補足】 Run Plugin起動設定は、テンプレートプロジェクトですでに設定が用意されているため、デフォルトで選択可能です。
runIdle

5.(省略可)プラグインのビルドファイルを生成する

プラグインのビルドファイルは、Gradleタスクを実行することで生成できます。

ZIPファイルの生成はリリース作業上必須ではありませんが、何らかの理由で後述のリリースができない場合や、内部的にプラグインファイルを共有する際の方法としてご参考ください。

ローカルで生成する

ローカル環境で./gradlew buildPluginを実行することで、プロジェクト内のbuild/distributionsにZIPファイルが生成されます。

生成されたZIPファイルをIntelliJ設定 > プラグイン画面からインストールすることで、プラグインが利用可能になります。
LocalInstall

GitHub Actionsで生成する

テンプレートプロジェクトで用意されているGitHubActionsのビルドワークフローを実行することで、GitHub上からも同様のZIPファイルがダウンロードできます。

テンプレートでは、Pull Request作成時、またはmainブランチにプッシュされた時にこのワークフローが実行されます。

生成されたファイルは、GitHubリポジトリActionsタブ > Build > 実行されたワークフロー > Summaryを選択し、画面下部のArtifactからダウンロードします。
Build

6.マーケットプレイスに公開する

JetBrainsマーケットプレイスへのプラグインリリースでは、GradleタスクpublishPluginを実行します。
このタスクにはアカウント設定やリリース公開トークンが必要になります。

ここでは、ローカルやGitHub Actionsで必要な作業のみを記載しますので、
事前にアカウント登録やトークン生成の詳細な手順は公式ドキュメントを参照し、JetBrainsアカウント情報とトークンを作成してください。

リリース作業で用意するもの

プラグインの署名情報を生成する

プラグイン署名に使用する秘密鍵と証明書生成コマンドは公式ドキュメントを参照してください。

ここで生成された秘密鍵、パスワードなどはハードコードせず、環境変数として設定します。
後で確認できるように保管しておきましょう。

【補足】 文字列として登録するため、「Doma Tools」ではGradleタスクを実装しBase64に変換しています。
Base64に変換するためのGradleタスク実装

シークレット環境変数を設定

GitHub環境変数設定

署名情報は非公開にして扱う必要があるため、GitHubで扱う際はリポジトリシークレットとして登録します。

GitHubリポジトリ設定のSercrets and variables > Actions > Sercretsタブ > Repository secretsで、以下を登録します。

環境変数
CERTIFICATE_CHAIN 証明書チェーン(chain.crtをBase64化)
PRIVATE_KEY 秘密鍵(private.pemをBase64化)
PRIVATE_KEY_PASSWORD 秘密鍵のパスワード
PUBLISH_TOKEN JetBrainsアカウントページで生成したToken

ローカルでの環境変数設定

ローカルからリリースする場合、以下のようにGradleタスクpublishPluginの起動設定を用意し、
Enviroment variablesGitHubの環境変数設定と同様の環境変数を設定してください。

この方法で設定した環境変数は、起動設定と同じ/.run内のXMLファイルに保存されます。
XMLファイルを外部に公開しないように、リポジトリへのプッシュ時などの取り扱いにご注意ください。

LocalPublishPlugin

リリース公開

mainブランチへのマージ忘れがなければ、以上で準備完了です。

リリース作業は非常に簡潔で、GitHub上のリリースノート公開をするだけで自動でマーケットプレイスにリリースされます。
リリース処理の実体はテンプレートで用意されているGitHub Actionsとなっており、そのまま利用可能です。
Doma Tools」では、このワークフロー実行時に次回リリースの仮バージョンを生成するなどの実装を追加しています。

  1. GitHubのリリース画面を開く
  2. 下書き状態のリリースノートの編集を編集する
    1. リリースノートの内容を必要に応じて編集する
    2. リリースタグをマーケットプレイスにリリースしたいバージョンと同じ名前で設定する
  3. 画面下部でSet as the latest releaseにチェックを入れ、Publish releaseを押下

PublishRelease

リリースノートが公開されると同時に、GitHub Actionsのreleaseワークフローが起動します。

ワークフロー正常終了後、自身のマーケットプレイス管理画面やIntelliJプラグイン検索画面で、最新バージョンのプラグインがアップロードされていることを確認しましょう!

【補足】 マーケットプレイスプラグインをアップロードすると、JetBrainsによる審査が開始されます。
審査完了後に、正式にマーケットプレイス画面で最新バージョンが表示されます。

その他マーケットプレイスに関する詳細は、 マーケットプレイス公式ドキュメントをご参照ください。

参考:マーケットプレイスチャネルの使い分け

JetBrainsのマーケットプレイスにはチャネルという概念があります。

普段マーケットプレイス画面の検索で表示されるプラグインは、デフォルトの「Stable」チャネルにアップロードされているものになります。

例えば、開発者内に限定でマーケットプレイスにあげたい場合や、テスター向けのバージョンを限定公開したい場合などには、任意のチャネルにアップロードすることが可能です。

IntelliJ公式ドキュメント

マーケットプレイス画面で直接アップロードする

publishPluginを実行せずとも、プラグインのビルドファイルを生成するで生成したZIPファイルを、マーケットプレイス管理画面から直接アップロードすることでもリリースが可能です。

管理画面右上の「Upload Update」ボタンを押すと、アップロードするプラグインファイルとチャネルの設定ダイアログが表示されます。
UploadUpdate
Chanel」で任意の文字列を入力するか、既存のチャネルを選択することでアップロード先を選択できます。
一般的に、ベータ版は「beta」、先行リリース版は「eap」とチャネル名が名付けられます。

Gradleタスクでもチャネルを自動制御する

実はテンプレートのpublishPlugin設定でも、プラグインバージョンを基にリリース先のチャネルを切り替えられるようになっています。

GradleタスクpublishPlugin実行時、セマンティック バージョニングに従ってプレリリース識別子を取得し、識別子名と同じチャネルにリリースされます。
(プレリリース識別子がないバージョンは、デフォルトの「Stable」チャネルにリリースされます)

プラグインバージョンの識別とチャネル判定処理

【例】 プラグインバージョン:1.1.0-beta.123.0でリリースした場合 、 チャネル「beta」にver1.1.0-beta.123.0のプラグインが登録されます。

IntelliJ上から任意のチャネルのプラグインを取得する

任意のチャネルにアップロードされたプラグインは、IntelliJに設定を追加することでそのバージョンを参照することも可能になります。

IntelliJ上で、設定 > プラグインを開き、上部の歯車アイコンからManagePluginRepositories...を選択すると、参照したいチャネルのURLを登録する画面が表示されます。

ManagePluginRepositories

ここに任意のチャネルのURLを追加することで、任意のチャネルにリリースされたプラグインバージョンが使用可能になります。

さいごに

今回はプラグイン開発の始め方ということで、環境構築からリリースまでの簡単な流れをご紹介しました。

開発を始めてから、IntelliJプラットフォームのルールやGitHub Actionsの動きなど分からないことがたくさんありましたが、
他のOSSやコミュニティの投稿などを参考にしていくことで段々と機能を実現していけるようになりました。

今後も「Doma Tools」をベースにした機能実装方法について投稿していきますので、引き続きよろしくお願いいたします。
ご興味を持たれた方は、是非プラグイン開発に挑戦してみてください!

レビューも投稿していただけますと大変励みになります🙇‍♀️

Doma Tools マーケットプレイスページ

プラグインOSSとしてDomaコミュニティへ寄贈されています。
不具合修正や機能要望、ディスカッションにもぜひご参加ください。

採用ページ

執筆:@terao.haruka、レビュー:@nakamura.toshihiro
Shodoで執筆されました