こんにちは。電通総研ITの寺尾です。
前回に続き、以前ご紹介したIntelliJ向けプラグイン「Doma Tools」の開発経験を基にした、プラグイン開発方法についてお話していきたいと思います。
前回はこちら:IntelliJプラグイン「Doma Tools」のご紹介~OSSなプラグイン開発~
まず今回は、環境構築からリリースまでの大まかな流れをご説明します。
※Gradle、GitHubの基本的な知識があると本記事の内容が理解しやすくなります
※記事内のGitHubリポジトリのリンクは、本記事作成時点での最新のコミットをリンクしています
IntelliJプラグインを作ってみよう
日本国内からマーケットプレイスにあげられているIntelliJ向けプラグインは、比較的少ない傾向にあります。
「プラグイン開発に興味はあるけど始め方がわからない」、「マーケットプレイスに出すって難しそう」
…と感じられている方に、本記事が取っ掛かりになれば幸いです。
前提
プラグイン開発で用意するものは以下になります。
1.環境構築
「Doma Tools」はJetBrainsが用意しているIntelliJプラットフォームプラグインテンプレートをベースにしています。
まずはこのリポジトリをクローンすることで、基本的なプロジェクト構成を構築できます。
プロジェクトはGradleプロジェクトとして構成されており、ビルド、リリースを実行するためのGradleタスクやGitHub Actionsも、テンプレートに用意されています。
- GitHub Actions:.github/workflows
- Gradleビルドスクリプト:build.gradle.kts
参考
- Gradleとは?
- GitHub Actionsとは?
2.プラグイン設定
プラグインの名前やサポートするバージョンなどを、自身のプラグインの設定に変更します。
プラグインの設定は以下のファイルを編集して管理します。
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.kts
とGitHub Actionsの追加実装で自動化しています。
参考:パッケージのバージョン管理
build.gradle.kts
に記載するライブラリやプラグインバージョンは、Gradleのバージョンカタログで管理することがおすすめです。
カタログファイルlibs.versions.toml
にまとめて記載しておくことで、依存パッケージのバージョン管理ツールが自動で最新バージョンへのアップデートを提案してくれます。
【補足】
Doma ToolsではRenovateを採用しており、依存パッケージに最新バージョンがリリースされると、カタログファイルに記載のバージョンを更新するPull Requestを作成してくれます。
3.実装
アクションやコード補完などIntelliJに追加したい機能を実装します。
公式ドキュメントやOSSのプラグインコードも参考にしてみましょう。
機能によって、IntelliJプラットフォームで指定されたサブクラスを作成します。
継承するクラスや実装するインタフェースの一覧は公式ドキュメントをご参照ください。
機能実装やテストに関する詳細な説明は、順次投稿していく予定です。
先に基本的な実装方法が気になる方は、IntelliJのサンプルプロジェクトやドキュメントをご覧ください。
参考:開発で役立つプラグイン
- Plugin DevKit: IntelliJプラットフォームプラグインの開発で推奨されているプラグインです。アクション機能の実装に必要な設定やクラスを簡単に生成できるようになります。
- PsiViewer: カスタム言語を使った機能を実装する際、エディタ上のファイル内の要素情報を確認する際に便利なプラグインです。
- GitHub Copilot: プラグイン実装に限らず、ロジックの実装に悩んだ時の相談相手やリファクタリング、ビルドまでの一貫したタスクなどの開発作業を依頼できます。
参考:コードの品質を高める
プロジェクトの品質を向上させるために、コードフォーマットを統一します。
「Doma Tools」では以下プラグインを使用しています。
また、タイプミスや変数のアクセスレベルなどを検査することもプロジェクトの品質向上につながります。
IntelliJはQodanaと連携したコード解析が可能です。詳細は公式ドキュメントをご参照ください。
参考:OSSとコミュニティの活用
拡張ポイントやインタフェースを実装しているOSSリポジトリを検索できるサイトです。
IntelliJプラットフォームプラグイン開発者の集うコミュニティです。
実装の悩みについては、こちらでアイデアを探してみましょう。
4.動作確認
デバッグ起動する
Run Plugin
をデバッグモードで起動し、開発したプラグインをインストールした想定の仮想的なIntelliJ環境を立ち上げます。
別ウィンドウで起動するIntelliJ上で実際にプラグイン機能を試し、バグ調査や動作確認が行えます。
【補足】
Run Plugin
起動設定は、テンプレートプロジェクトですでに設定が用意されているため、デフォルトで選択可能です。
5.(省略可)プラグインのビルドファイルを生成する
プラグインのビルドファイルは、Gradleタスクを実行することで生成できます。
ZIPファイルの生成はリリース作業上必須ではありませんが、何らかの理由で後述のリリースができない場合や、内部的にプラグインファイルを共有する際の方法としてご参考ください。
ローカルで生成する
ローカル環境で./gradlew buildPlugin
を実行することで、プロジェクト内のbuild/distributions
にZIPファイルが生成されます。
生成されたZIPファイルをIntelliJの設定 > プラグイン
画面からインストールすることで、プラグインが利用可能になります。
GitHub Actionsで生成する
テンプレートプロジェクトで用意されているGitHubActionsのビルドワークフローを実行することで、GitHub上からも同様のZIPファイルがダウンロードできます。
テンプレートでは、Pull Request作成時、またはmainブランチにプッシュされた時にこのワークフローが実行されます。
生成されたファイルは、GitHubリポジトリのActionsタブ > Build > 実行されたワークフロー > Summary
を選択し、画面下部のArtifactからダウンロードします。
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 variables
へGitHubの環境変数設定と同様の環境変数を設定してください。
この方法で設定した環境変数は、起動設定と同じ/.run
内のXMLファイルに保存されます。
XMLファイルを外部に公開しないように、リポジトリへのプッシュ時などの取り扱いにご注意ください。
リリース公開
mainブランチへのマージ忘れがなければ、以上で準備完了です。
リリース作業は非常に簡潔で、GitHub上のリリースノート公開をするだけで自動でマーケットプレイスにリリースされます。
リリース処理の実体はテンプレートで用意されているGitHub Actionsとなっており、そのまま利用可能です。
「Doma Tools」では、このワークフロー実行時に次回リリースの仮バージョンを生成するなどの実装を追加しています。
- GitHubのリリース画面を開く
- 下書き状態のリリースノートの編集を編集する
- リリースノートの内容を必要に応じて編集する
- リリースタグをマーケットプレイスにリリースしたいバージョンと同じ名前で設定する
- 画面下部で
Set as the latest release
にチェックを入れ、Publish release
を押下
リリースノートが公開されると同時に、GitHub Actionsのreleaseワークフローが起動します。
ワークフロー正常終了後、自身のマーケットプレイス管理画面やIntelliJのプラグイン検索画面で、最新バージョンのプラグインがアップロードされていることを確認しましょう!
【補足】
マーケットプレイスへプラグインをアップロードすると、JetBrainsによる審査が開始されます。
審査完了後に、正式にマーケットプレイス画面で最新バージョンが表示されます。
その他マーケットプレイスに関する詳細は、 マーケットプレイス公式ドキュメントをご参照ください。
参考:マーケットプレイスチャネルの使い分け
JetBrainsのマーケットプレイスにはチャネルという概念があります。
普段マーケットプレイス画面の検索で表示されるプラグインは、デフォルトの「Stable」チャネルにアップロードされているものになります。
例えば、開発者内に限定でマーケットプレイスにあげたい場合や、テスター向けのバージョンを限定公開したい場合などには、任意のチャネルにアップロードすることが可能です。
マーケットプレイス画面で直接アップロードする
publishPlugin
を実行せずとも、プラグインのビルドファイルを生成するで生成したZIPファイルを、マーケットプレイス管理画面から直接アップロードすることでもリリースが可能です。
管理画面右上の「Upload Update」ボタンを押すと、アップロードするプラグインファイルとチャネルの設定ダイアログが表示されます。
「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を登録する画面が表示されます。
ここに任意のチャネルのURLを追加することで、任意のチャネルにリリースされたプラグインバージョンが使用可能になります。
さいごに
今回はプラグイン開発の始め方ということで、環境構築からリリースまでの簡単な流れをご紹介しました。
開発を始めてから、IntelliJプラットフォームのルールやGitHub Actionsの動きなど分からないことがたくさんありましたが、
他のOSSやコミュニティの投稿などを参考にしていくことで段々と機能を実現していけるようになりました。
今後も「Doma Tools」をベースにした機能実装方法について投稿していきますので、引き続きよろしくお願いいたします。
ご興味を持たれた方は、是非プラグイン開発に挑戦してみてください!
レビューも投稿していただけますと大変励みになります🙇♀️
本プラグインはOSSとしてDomaコミュニティへ寄贈されています。
不具合修正や機能要望、ディスカッションにもぜひご参加ください。
採用ページ
執筆:@terao.haruka、レビュー:@nakamura.toshihiro
(Shodoで執筆されました)