Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

プログラミング言語が抱える課題を解決するには言語を乗り換えるのが一番いい、かもしれない

この記事は集まれKotlin好き!Kotlin愛好会 vol.47の懇親会でちょっと触れた内容を、膨らましてブログ用にまとめ直したものです。

注意点として、Java用静的解析OSSの開発保守を長年やってきたJavaプログラマがKotlinに乗り換えて1年経ったころに書いている、という強力なコンテキストがあります。また「何十年前の話をしてんの?」という部分が多く存在しますが見逃してください 🙇‍♂️

プログラミング言語の成長はすべてを解決する

どんなプログラミング言語にも固有の問題は必ずあります。私が一番長く書いてきたプログラミング言語であるJavaでも、いくつかの課題が指摘されてきました:

  • 不要な同期を取りすぎている(StringBuffer, Hashtable, Vectorなど)
  • シリアライズ・デシリアライズが遅い(Serializableインタフェース)
  • コレクションにどのようなインスタンスが入っているのかわからない
  • null安全ではない
  • 記述が長くなりやすい

こうした問題に対して、Javaとそのコミュニティはとても良く対応してきたと思います:

  • StringBuilder, HashMap, ArrayListなどの同期を取らないクラスが標準で提供された
  • シリアライズ・デシリアライズ用ライブラリが充実した
  • ジェネリクスが実装されてコレクションに入っているインスタンスがわかりやすくなった
  • Optional が標準で提供されるようになった
  • より抽象的に扱えるように、try-with-resourcesやStream APIなどを順次導入してきた

これに限らず様々な改良も進んでおり、JVM(Java仮想マシン)の改善も相まってこれからも強力な言語で有り続けるだろうと思っています。また言語とは別の外付けの改良も進んでいて、インクリメンタルビルドの実現、アノテーションによるコンパイラやツールへの情報提供、ツールやIDEによる静的解析なども盛んです。

実行環境に対するコントロールが効かないアプリやオンプレサーバの開発ではわかりませんが、一般にこうした言語や周辺環境の成長の恩恵を受けることは近年とても容易になってきています。こうしたアップデートを即座に取り込む、あるいは自分で作りに行くことは、多くの生産性の課題を解決するうえでとても重要です。

それでも成長による課題解決には限界がある、特に初学者にとっては

それではJava言語にはもうコーディングの現場で考慮すべき問題はないのでしょうか。もちろんあります。むしろ解決済みのはずの問題にすら気を配らなければならないケースがほとんどです。

StringBuffer, Hashtable, VectorなどのクラスはまだJava言語に存在します。個人的につらいなと思っているのは Stack クラスです。「スタック構造がほしいときは Stack じゃなくて Deque を使いましょう!」なんて一見意味の分からない注意事項が現役なので。。。 Properties が現役なのもわかりにくい。

シリアライズやデシリアライズは言語機能ではなくライブラリを使いましょう、というのも初学者にはつまづきやすいポイントだと思います。しかも聞く人によってkryoがいいよ、いやGSONでしょ、あれJacksonじゃないの?なんてことにもなるわけで、やはり標準が定まっていないのはわかりにくいなと思います。

ジェネリクスや Optional は便利ですが、プロジェクトの依存先を含め多くのインタフェースで利用されて初めて価値が出ます。特に長命のプロジェクトでは、導入が難しいこともあるでしょう。また「 null が入りそうだからこのフィールドは Optional にしよう」みたいな誤用の機会も多く潜んでおり、正しく使うのはいつでも難しいものです。

強調したいのは、自分はJavaとJVMが提供する強力な互換性はとても好ましいと思っています。またJava Platform Module System (JPMS、旧称Project Jigsaw)を使って不要な部分を取り除いたJVMを自分で作れる未来は来るだろうとも期待しています。

が、それが実現したとしてもそれは今ではないですし、ここに挙げられていないいくつかの課題はきっと残るでしょう。そのうえ更に「ここは歴史的経緯で2つ選択肢があって、今はこっちを使います」のような要考慮点はきっと増えていると考えると、初学者にとってはちょっと辛そうだな、という印象です。

外付けの改良は中長期的には開発体験を損なう方向に作用する

ではアノテーションやIDE、ツールなどを駆使していけば良いのでは?という発想が次に来ます。SonarQubeのようなサービスを導入し、こうした課題をPull Requestレビューの段階で洗い出せば、初学者でも学びながらプログラムを書いていけるのではないでしょうか。

実際にこれは可能だと思います。私自身、JenkinsやTravis CI、GitHub ActionsなどでJSR305やPMDやFindBugs、SpotBugsにGoogle erorr-proneなどを組み合わせて使ってきました。IDE組み込みの解析機も良いものですし、GitHub code scanningやSonarLintも魅力的な選択肢です。

ではこれが永続的な解決かというと、ちょっとそうは思えないなというのが私の意見です。プロジェクトの成長に伴って実行時間がかかるようになりますし、どの警告を受け入れてどの警告を無視するかという判断も必要になりますし、棚上げした課題の棚卸しも必要です。インクリメンタル分析によって速度を改善しようとすると変更しなかった部分との咬み合わせがうまくいかなかったりしますし、俯瞰的に見て初めて見つかる課題をどうやって見つけて対応しようという課題もあります。

ので外付けツールはケアレスミスを洗い出したり中期的な改善施策を検討するうえでの材料にはなりますが、経験者によるPull Requestレビューに比べての教育効果はそこまででもないのでは…と思っています。そもそも言語の課題なのにさらに計算機資源と時間をつっこんで解決しないといけないということ自体が非効率という思いもあり、頼り切りたくは無い感じです。

言語を乗り換えると問題を一網打尽にできる、かもしれない

Kotlinに乗り換えれば、null安全やジェネリクスの課題は改善されます。またコードの長さも短縮されます(愛好会で事例をひとつ紹介しました)。ひとつのアクションで多くの課題が解決されるのは、新しい言語が人類が発見した知見を取り入れて設計されているからです。

外部ツールへの依存が減ることで、開発体験を改善することも期待できます。残念ながらKotlinのコンパイルはまだ遅いですが(手元で試した限りではK2もあまり解決にならない)、静的解析ツールの必須度が大きく減っていることから、相対的には改善されているかなと思っています。

もちろん言語を乗り換えても解決されない問題はあります。Kotlinでも古いコレクションは使えますし、外付けツールに頼っている問題発見もまだまだあります。ので私はここ5年とか10年とかはこうした解決を積み上げながら、また一網打尽にできる言語の登場を待つのでしょう。Flixみたいな実験的な言語をウォッチしているのも、新しい言語が得た知見を不格好でも今の言語に持ち込めないかと期待しているからです。

生成AIがすべてを解決するかもという期待

生成AIによるゲームチェンジを期待しているのが、こうした「人間が気をつけなければいけない」問題を劇的になくしてくれるのではということです。外付けツールとして今まで以上に優秀な解決を提供してくれるかもしれないですし、そもそも人間に書かせないことで問題を根っこから解決してくれるかもしれません。

ただ実行時間がどうしても遅いというところで、まだ自分が期待する「1分以内にフィードバックを返してくれる、開発体験を改善する存在」には遠いかなというイメージですが、これもあと数ヶ月したら変わってるかもしれないですよね。楽しみです。

あわせてよみたい

spotbugs-gradle-plugin v6のリリース候補版(RC版)をお試しください

spotbugs-gradle-plugin v6のリリース候補版(RC版)が出たので、GradleでSpotBugsを実行している方はぜひお試しください。

github.com

主なBreaking Changes

effortreportLevel を型安全に書けるようにした関係で、ビルドスクリプトの更新が必要なケースがあります。 特にGroovyでビルドスクリプトを記述している場合に対応が必要です。

またAndroidプラグインとビルドする都合上、classファイルをJava 11で出力するように変更しています。 いまだと最終成果物としてJava 8のclassファイルが必要な場合でもGradleはJava 17以降で実行していることが多いと思いますので、ブロッカーになることはないと思いますが注意してください。

他にも今まで明示的に有効にする必要のあったJava Toolchain対応が標準で有効になったり、非推奨になったGradleのAPIへの依存を減らしたりしています。 リリースノートを踏まえて使ってみて気になる点や分からない点があれば、Issueを起票していただけると助かります。 よろしくお願いします。

元toB系プログラマが医療情報技師の勉強をして面白かった部分

今年の医療情報技師能力検定試験に向けて、医学医療編・医療情報システム編の学習を進めてきました。toB系プログラマとして働き始めてから見てこなかった単語や発想がたくさんあって面白かったので、印象的だったところをまとめます。

医療現場はロールベースかつイベントドリブン

医療現場では(乱暴に言うと)各部門やシステムの間を「オーダ」をはじめとしたメッセージが飛び交っている、というモデル化ができそうです。 多くの役職だと何ができるかが法で定められていて、そうした役割をどう組み合わせるかも予め想定されており、そのコラボレーションをメッセージで行っているということです。

これはけっこう医療現場というものを特徴づけるものだと思っていて、パッと思いつくところでも以下のような事が考えられます:

  • 業務の属人性を下げるための仕組みとして機能することが期待される。
    • アクターのTODOや期待されるアウトプットが明確。特に医療行為や看護行為は国際的なマスタがあり、世界的に定義が明確っぽい。
    • アクターの専門性に対する期待も明確なので、教育や評価も(簡単とは言わないけど)比較的やれそう。
  • アクターのロールやコミュニケーション方法が全医療機関共通なので、転職も比較的しやすそう。
    • プログラマだと言語や利用してるクラウドが同じでも現場の働き方はぜんぜん違うけど、医療現場だと少なくとも部署間コミュニケーションは似ていると期待できそう。
    • 紙カルテ&電子カルテみたいな、採用している仕組みが違うと細かいやり方は大きく違ってくるとは思うけど。
  • アクター=部署あるいは資格持ちの人間なので、病院というシステムを動かすための最低限の人数が多くなる。
    • コーダー兼デザイナー兼テスター兼広報です!みたいなことが法的にやりにくい。医師ひとりの診療所で在宅医療やるぞみたいな例はあるみたいだけど……。
    • 情報の交通整理や決断が困難かつボトルネックになる可能性が高い。実際医師や看護師の長時間労働などが問題になっている。

Team Topologiesに親しんでるとStream-aligned Teamに権限を移譲していかにスムーズに動かすかという発想になるんですけど、病院というシステムだとそもそもどこがStreamなんだっけとか、各種検査というComplicated Subsystemをどう動かすべきなんだろうとか、普段使ってない頭の部分を使っている感じがしていいですね。

科学的知見を幅広く活用するための「ガイドライン」

コロナ禍を通じて私にもランダム化比較試験が強いらしいみたいな雑な理解はあったのですが、医療情報技師の学習をきっかけにEvidence-Based Medicine(EBM)という考え方があってランダム化比較試験よりも強いやつがあるということを知りました。システマティックレビューやメタアナリシスがそれです。強い研究を統合してもっと強くするみたいな雑な理解でいますが、人間の叡智を集結して現在のベストを導き出すというのはなんか知性の総力戦という感じでいいですね。

さて医療の世界には診療ガイドラインというものがあり、医療機関ごとの医療の質を底上げしたり医療資源を効率的に扱ったり提供された医療の評価に使ったりしています。日本では医師会や厚生労働省から出ているものが多数あるようです。国立研究開発法人国立がん研究センターがシステマティックレビューやメタアナリシスも含めた説明をしているのでおすすめです:

ganjoho.jp

医療が研究の山の上に成り立っていることはなんとなく知っていたつもりでも、医療関係者がどう知識をアップデートしているかとかはイメージがなかったため、なるほどこうやって国として知識を共有し医療の質を保っているのだと感心しました。

ちなみに医療機関向け情報セキュリティの世界でも3省2ガイドラインというものが提供されています。医療情報技師なら内容を把握していることが求められますし、医療業界向けのサービス提供をする場合も必ずこれを読むことになります。これは診療ガイドラインではないのでメタアナリシスとかは関係ないかもしれないですが、少なくともIT業界標準の考えは多く盛り込まれているように感じます:

www.mhlw.go.jp

www.meti.go.jp

医師の相互監視に課題がありそう

転職する前に医療業界に抱いていたイメージとしては、インシデント対応ができてなさそうというのがありました。いや、個人的体験としては特に不満を感じることもなかったですし、インシデントにぶち当たったこともたぶん無いのですが、「失敗の科学」の印象が強かったのです。この本は「航空業界にあって、医療業界にないもの」とデカデカと書いてあるレベルで(アメリカの)医療業界にダメ出ししています。

失敗の科学

失敗の科学

Amazon

ところで医療情報技師の学習範囲にはインシデントの扱いや医療安全や医療過誤、原因分析や再発防止などが含まれています。RCA(Root Cause Analysis)やProblem SolvingあたりはtoBプログラマなら扱ったことあることも多いと思うのですが、これに加えて4M5E分析とかSHELモデルとかも扱っていて自分は初見だったので勉強になりました。また国内の事例や記事なんかを追いかけても真摯に課題に向かっている方が多く、結構やれてるじゃんという感想になった、んですが、残念ながらこの事件が起こってやっぱダメなところはダメなんだなという現実を思い知ったところがあります:

www3.nhk.or.jp

少なくとも医師同士の相互監視は、セカンド・オピニオン(厳密には監視ではない)やカウンターサインを除けばあまりなさそうだなというのが今の自分の認識です。もちろん日頃から院内で情報交換(カンファレンス)を行っていたり、インシデントレポートが提出されれば然るべき検討が行われたりするはずですが、少なくとも前述の事例ではカルテを読み合うようなことはやっていなかったのでしょう。

医師が長時間労働していることを踏まえるとここはシステムが余力を創出することで貢献できる部分かもしれないなとは思いますし、カルテ記載事項の質の判断とかは機械学習でなんとかできそうな気もします。

病院の壁を超えたPDCAサイクルが回せるように情報が公開されている

診療ガイドラインの実施率であるとか、病床機能の割合であるとか、様々な各病院から提出されたデータが統計されたうえで公開されています。例えばこのへんとかです:

hospia.jp www.mhlw.go.jp

これ普通の企業の活動だとちょっと考えにくいというか。強いて言えば離職率とか初任給とかは他と比較して改善の参考にはすると思うのですが、じゃぁ他社製品の単体テストカバレッジとか変更のリードタイムとかMTTRとかはそもそも公開されていないので参照できない事が多いと思うのですよね。ところが医療機関の場合は医療サービスというコア機能のデータが世に出ているわけで、いやこれすごいなって思います。もちろん病院側だけじゃなくて、ガイドラインとか政策とかの側でも参考にしているのでしょう。

ちなみに海外だと病院ごとだけじゃなくて医師ごとのデータとかも見られるらしいです。すごい。

まとめ

元toB系プログラマが医療情報技師の勉強をして面白かった部分として、医療現場がロールベースかつイベントドリブンっぽいなぁということと、診療ガイドラインやデータに基づく改善が回る仕組みがあってすごいなということを書きました。またインシデントを隠さず業界全体として次に活かすための体制や仕組みはありそうなので、あとは実行の浸透が重要=やっぱり医療DX大事だなぁと改めて感じました。

医療情報技師の資格試験は医学・医療編がちょっと重いものの、医療システムのおおまかな構造や他施設との連携などについても学べるので、私みたいに医療業界の外から来たプログラマは齧って損はないと思いました。おすすめです。

2023年10月5日 追記

合格しました。

twitter.com

私がとあるOSS開発から手を引いた経緯

ホットな話題に乗っかって、私がSpotBugsというJava向け静的解析ツールのOSS開発から手を引いた理由をまとめてみます。

自分がJavaを使わなくなった

先のブログでも指摘されている通りで、自分がそのソフトウェアを必要としなくなったというのは大きな理由になりました。Kotlinに乗り換えたことでJavaを書く機会がなくなり、Kotlinが生成したclassファイルの解析はSpotBugsには向かなかったので、SpotBugsを使わなくなりました。

SpotBugsにKotlin対応させることは技術的には可能ですが、ソースコードも考慮して解析できるdetekt(ktlint, diktat)がある世界でわざわざやることではないという感想です。

リターンが無かった

自分が使わないツールのメンテナンスを継続するには、やはりある程度の見返りを求めたいというのが自分の気持ちとしてありました。Github Sponsorsをはじめてみたり、Who uses SpotBugs?をまとめてみたりしましたが、いずれも自分が納得できる程度には至りませんでした。

冗談半分で「控えめに言っても日本人で、ひょっとするとAPACでもclassファイル静的解析で片手の指に入るんじゃないですかね」とか言うことがあるんですが、これは6年間の活動の結果を分かりやすく人に伝えることで少しでもリターンを稼ぎたいなという気持ちが裏にあるわけです。

まぁ世の中にはOSS開発者を表彰するような動きもいくつかありますし、金銭的フィードバックをコントリビュータに返せているコミュニティもいくつかあるようなので、あと数年続けていれば結果が出た可能性はあります。ただ私としてはその時間を新しいことに使いたいと思い、資格試験や副業に充てることにしました。

個人的には、Javaで中~大規模開発してる会社なんてだいたいSpotBugsを使ってるだろうし、Javaバージョンを上げる際などに課題もいくつか出ているだろうし、ひとつくらいSponsorしてくれる会社が出てきてもおかしくなかったんじゃないかなぁどうかなぁとは未だに思っています。が、そういうところもSonarQubeのような有償ソリューションに鞍替えした方がトータルではベターだろうなとも思います。Java使ってる会社だと、有償ソリューションの方が稟議の通りが良さそうというかなんというか。

ユーザ対応がきつい

どこでも言われていることなので割愛します。リリース依頼を有償化する動きが一部であって、これがあたりまえになるのもひとつの解決のカタチなのかもしれないですね。

次があったらどうするか

コントリビュータを大切にする企業のプロジェクトに絞って貢献するとか、not open contributionなプロジェクトを立ち上げるとかを試してみたいと思っています。

それはそれとして課題を見つけたプロジェクトに対して“辻PR”を送る活動は続けていますし、Github Sponsorsで四半期ごとに自分の活動を報告すること自体は自分自身学びも多く継続していきたいと思っていますので。少しでも面白そうだなと思った方は、ご支援いただけると嬉しいです。スポンサーの方は報告のバックナンバーをご覧いただけるようにもしています。

追記

ティール組織わからん、を掘り下げる

組織の話が好物なので色々読んできたのですが、結局ティール組織はよくわからないままでした。最初に本を読んだのが5年も前なんですね。

で、自分なりに考えた結果、大きく2点においてよくわからないのだと思ったのでメモしておきます。

以下、「ティール組織」と書いた場合は書籍「ティール組織」を指します。なお昔読んだ本を読み返しながら書いているので読み飛ばしによる誤解などはあるかもしれませんし、ここ5年で新しい発見があったとしても私はそれをキャッチアップできていないことにご留意ください。

組織に人間の弱みを補う機能を求めたいのに、スキル常時発動を前提に議論が展開される

やっぱ組織を作るのは「専門家を集めてひとりじゃできないことをやる」に加えて「ひとりがダメでも他の人がいる」ことを実現したいというのはあると思うんですよ。 多様性だVUCAだバス係数だなんて難しい話は置いといて、さて自分や家族が体調を崩したときにどうするんだっけ?って単純な話ですよね。

体調管理ができてないなんて社会人失格だァなんて考え方もあるにはありますが、自分はもちろん特に家族の体調はcontrollableではないなぁというのがひとりの父親としての実感としてあります。 のでやはり柔軟にスケジュールを調整できたり他の人がフォローに入れたりしたほうが、組織としては強いと思うわけです。

で、ティール組織では以下の記述があります:

私達が自分自身のエゴから自らを切り離せるようになると、進化型への移行が起こる

進化型では、意思決定の基準が外的なものから内的なものへと移行する

なるほど。で、自らをエゴから切り離せない日はどうするんですかね? 意思決定が外的なものになってしまいがちな日は?

階層型組織では組織を機能させられない場合のためにエスカレーションがあり、Scrumだと透明度・検査・適応ができない日のためにスクラムマスターがいます。うまくいかないときに他者の助力を得る仕組みがあるわけです(そしてこれが上司の能力が組織の能力のキャップとして機能するとか、スクラムマスターに超人性を求めてしまうとかの失敗に繋がったりする)。

しかしティール組織の記述には、「上司の不在」の節におけるビュートゾルフをはじめとしたいくつかの具体的な事例が出てくるだけで、一般化が見られません。「たしかにそこに難しさがあるよね、でもうまく行ってる組織もあるしなんとかなるよ!」と言われてハイそうですかとは、さすがにならないかなと。

個人的には、組織の構成員がお互いがカバーしあうことや「助言プロセス」による意思決定を期待するのであれば、適切なタイミングでカバーに入るための情報公開・共有であったり持続可能な評価制度であったりまで踏み込んで初めて組織論と呼べるものになると思います。こうした事柄に関する記述は確かにこの本にもありますが、いずれも既存組織に多く共通するものを紹介するに留まっていて、個人的には再現性を感じませんでした。

問題解決のための手法ではない

めちゃくちゃ粗い理解として、この手の本は「上司が存在しない」ことに一定の価値を見出しています。上司がなくても組織は回る、そのために意思決定や権限管理や解雇をどうするか?という論理展開が行われます。これは一見課題に対する解決案の提示に見えますが、そもそもの「なぜ上司がいると問題なのか」の掘り下げが行われていませんし、「上司を取り除くことで解決されるのか」「上司がなくなって表面化するリスクとどう向き合うか」もあまり検討されていません。

例えば「経営陣はなく、ミーティングもほとんどない」の節にはミーティングが増えて生産性が下がることを問題として、定例ミーティングをなくし有機的なコミュニケーションで置き換えることで解決とする記述がありますが、これは上司がいるからダメというよりはマネジメントとリーダシップを混同するからコミュニケーションがうまくいってなかったやつなのでは?というように私には見えます。Team Topologyのようなチーム間コミュニケーション整理であったりチームへの権限移譲(Empowerment)であったりは今どきの階層型組織でも普通に行われることなので、何も上司をなくすなんて劇薬を持ち出さなくても……という「目的と手段のはき違い」感があるのです。

ので「上司がいなくても組織は回る」のは真だと思いますが、「上司がいても組織は回る」のも「上司がいると便利」なのも真なので、あまり組織論としては魅力的ではないなという感想になりました。Project Oxygenにぶつけて打ち勝てる本じゃないなというか。

個人的にはやっぱりこういう本は問題に対する解決手法を提示してほしいんですよね。わかりやすい例としては組織論ではないですがドラッカーの「お前の仕事は顧客の創造だ、顧客の創造にはマーケティングとイノベーションが必要だ、それぞれのためにこう考えて動け」というMECEな説明が入りやすかったです。 仮に解決を論理的に提示できず、世の成功事例を集めてその傾向を分析するに留まるとしても、Accelerateくらいのファクトに立脚した考察はほしいですね。

まとめ

結局は良い上司に恵まれてきたので「上司、いいじゃん!」が自分の意識の根底にあって、これが違和感を作ってるんだろうなと。あとまぁ人間の可能性を信じすぎというか、負の可能性から目を離しすぎというか。

今から読み直すような本ではないと思うので、マネジメントだけがリーダシップを握ることに限界を感じている方には「チームワーキング」をおすすめします。これは再現性があると感じさせてくれるというか、問題を要素に分解したうえで現状を変えるためのTODOが整理されているのでとっつきやすいです。

Threaddump, JFR, JMC周りの知識のアップデート

久々に古い知識を整理していて、けっこう更新されているものが多いのでここにまとめる。

JDK Mission Control (JMC)

JMCはOracleのウェブサイトからダウンロードできる。

標準ではOS標準のロケールが利用される。UIを日本語化する場合は jmc.iniuser.language システムプロパティを設定する。これはJVMに渡す設定なので必ず -vmargs よりも後ろに書く(Eclipseの設定と同じ)。

-Duser.language=ja

利用するJVMは jmc.ini-vm システムプロパティを設定する。これはJVM起動前に使うので -vmargs よりも前に書く。

-vm
C:\Program Files\Java\jdk-17.0.7.7\bin\javaw.exe

ThreaddumpとJFR

昔はThreaddumpファイルを複数取ってIBM Thread Dump Analyzerなどで解析していたが、今ならJFRファイルにスレッドダンプの情報が含まれるためJFRを取得すれば充分そう。

JMCで取得したJFRファイルには、期間中のスレッドダンプの情報が含まれている

JFRファイルはJMCで取得するのが一番手軽。

Gradle用のGitHub Actions勘どころ(2023年夏)

前回書いたのがもう4年前でビビったのと、最近いろいろ進展があったのでまとめてみます。

actions/setup-java の依存キャッシュを使わない

これ自分が実装した機能なのでホント申し訳ないんですけど、今なら gradle/gradle-build-action を使ったほうが良いです。 利点は公式が説明しているので読んどいてください。

github.com

spotlessApplyして差分が出たらSuggest Changeする

reviewdogが action-suggester という素敵なアクションを提供しています。GitHub Actionsでフォーマッタを実行して差分ができた状態でこのアクションを実行すると、GitHub Pull RequestのSuggest Change機能を使ってフォーマットを提案してくれます。

github.com

フォーマット適用箇所が多いと手元で ./gradlew spotlessApply したほうが早いなってケースもまぁあるとは思うんですが、やって損は無さそうです。 もちろんSpotlessに限らずktlintやPrettierのような他のフォーマッタでも利用できます。

まとめ

だいたいこんな感じじゃないですかね。リリース自動化には release-please とか semantic-release とかお好きなソリューションをご利用いただければと思います。

on:
  pull_request:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read # actions/checkoutのために必要
      pull_requests: write # reviewdog/action-suggesterのために必要
    steps:
      - uses: actions/checkout@v3
      - uses: gradle/wrapper-validation-action@v1
      - uses: actions/setup-java@v3
        with:
          distribution: microsoft
          java-version: 17 # toolchainで指定したバージョンと同じものを使う
      - uses: gradle/gradle-build-action@v2
        with:
          arguments: spotlessApply build --scan
      - uses: actions/upload-artifact@v3
        if: always()
        with:
          name: Gradle reports
          path: build/reports
      - uses: reviewdog/action-suggester@v1
        if: github.event_name == 'pull_request'
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          tool_name: spotless

またワークフロー最適化の観点ではGradleのRemote Build Cacheが非常に効果的です。勤め先ではgradle-gcs-build-cacheを使ってGoogle Cloud Storageを活用した最適化を行っています。