新しくなったMaven CentralにScalaプロジェクトをパブリッシュできたのでその手順をまとめた。
- 背景
- パブリッシュとは
- おおまかな流れ
- 事前に準備するもの
- Maven Centralのページからnamespaceを取っておく
- テスト用リポジトリを作る
- sbt-sonatypeの最新版を手でビルドする
- sbt再設定
- クレデンシャル準備
- 署名用GPG鍵準備
- プロジェクトのビルド
- Further Reading
背景
2024年より、Maven Centralはパブリッシュ用のAPIを変更した上、新サイトからしかアカウントを作成できなくなった。Mavenなどはこれに適合しているが、Scala + sbtのデファクトパブリッシングプラグインであるsbt-sonatype
は何の告知も受けられなかったのか突然新システムでは利用不能な状態になってしまった(以前に旧システムに登録した人はそのまま使えているはず)。さいわいコントリビューターの手によってワークアラウンド用のPRが提供され、いまだ正式なリリースはされていないものの手元でビルドすることで対応可能な状態になっているので、これを利用してテスト用リポジトリをpublishしてみる。
旧手順はこちら。
ちなみに一度パブリッシュしたアーティファクトは二度と消せなくなるので、くれぐれもヘンなデータには注意しよう。今回はただのHello, Worldをパブリッシュする。
パブリッシュとは
Publish。自作のアプリケーションやライブラリをJARファイルにコンパイル・バンドルし、Maven Centralにアップロードして誰でも利用できるようにすること。パブリッシュするにはアカウントの登録と、JARファイルに署名を行う必要がある。Maven Central以外のリポジトリも存在しており、そちらに登録することも一般にパブリッシュと言うが、大抵の場合はMaven Centralにパブリッシュする。 他の言語でいうところのnpmやgemに登録するのと同じである。
おおまかな流れ
新Maven CentralはAPIやブラウザ上のUIだけが異なるので、本質的にはあまり手順の変更はない。
sbt-sonatype
のパッチ版をダウンロードしてビルドする- Scalaのサンプルプロジェクトを作成し、パブリッシュに必要なプロジェクト設定を行う
- サンプルプロジェクトが、前述のプラグインを使うようにする
- プロジェクト用のGPG鍵を作成する
- サンプルプロジェクトをビルドし、署名付きJARを生成する
- 署名付きJARをMaven Centralにパブリッシュする
事前に準備するもの
- Scalaの開発環境
- Maven Centralのアカウント(GitHubでログインするとよい)
- 英語だが難しいことはない。 https://central.sonatype.org/register/central-portal/ を見ればよい
- Maven Central上のnamespace(Group IDに相当する部分の権限)
- GitHubログインすると
io.github.{GitHubユーザ名}
というnamespaceがもらえる - ドメインを持っている場合はそれを認証することでnamespaceにできる
- 今のところ、通常の方法でアカウント作成した後でGitHubでログインしてもアカウント統合が行われないので注意すること
- パブリッシュする前に設定しておく必要がある
- GitHubログインすると
gpg
コマンド(アーティファクトの署名に必要)cs
コマンド(あると動作確認できて便利)
cs
コマンド(Couriser)については以下の記事で扱っている。
ユーザ登録に関しては、Gradle版の記事が参考になるかもしれない:
準備ができたらはじめよう。
Maven Centralのページからnamespaceを取っておく
namespaceはここで確認できる:
namespaceを取るには、GitHubログインしてio.github.{GitHubユーザ名}
を自動的に付与してもらうか、独自ドメインを利用してDNSの設定でそのドメインをnamespaceとして使えるようにするかのどちらかとなる。
今回はdev.capslock
を持っているので、これを利用する。namespaceは後程build.sbt
に書き込む。
テスト用リポジトリを作る
まずはパブリッシュ対象となるダミーコードをGitHubに作る。
これはsbt new scala/scala3.g8
で作っただけの、hello worldが出るだけのコードから始める。
まずはパブリッシュするときに必須となるパッケージ名などを設定しておく。
// build.sbt val scala3Version = "3.3.3" // Scala 3.3系はLTSなので、ライブラリをパブリッシュするときは3.3にしておくとよい lazy val root = project .in(file(".")) .settings( organization := "dev.capslock", // ここに取得済みのnamespaceを入力する organizationName := "capslock.dev", // organizationの名前はわかりやすければなんでもいい startYear := Some(2024), // 作った年 // ライセンスを指定する。License.以下に定番のライセンスが用意されているが、それに無い場合は(名前, そのライセンスのURL)のタプルを渡す licenses += License.MIT, homepage := Some( // そのプロジェクトのホームページを指定する。GitHubの場合はそのプロジェクトページでよい url( "https://github.com/windymelt/scala-new-maven-central-exercise" ) ), scmInfo := Some( ScmInfo( // ソースコード管理システムの情報を与える。1つめはURL、2つめはgit cloneするときの文字列を与える url("https://github.com/windymelt/scala-new-maven-central-exercise"), "https://github.com/windymelt/scala-new-maven-central-exercise.git" ) ), developers += Developer( // 開発者情報。ID、名前、メール、ホムペの順 "windymelt", "windymelt", "windymelt@3qe.us", url("https://www.3qe.us/") ), name := "scala-new-maven-central-exercise", version := "0.0.1", // バージョンを指定する。semantic versioningするとよい scalaVersion := scala3Version, libraryDependencies += "org.scalameta" %% "munit" % "0.7.29" % Test )
sbt-sonatype
の最新版を手でビルドする
sbt-sonatype
はまだ新Maven Central向けのリリースを出していないが、既にPull-Reqが作成されており、パブリッシュ可能な状態になっている。よってこれを利用するための手順を行う。
具体的にはこれを行う。対応版のフォークブランチでsbt-sonatype
をビルドしてローカルで利用できるようにする。
% git clone git@github.com:Andrapyre/sbt-sonatype.git % cd sbt-sonatype % git switch adding-sonatype-central-client % git pull % sbt "compile; publishLocal" [info] published ivy to /home/windymelt/.ivy2/local/org.xerial.sbt/sbt-sonatype/scala_2.12/sbt_1.0/0.0.0-734-5b5db727/ivys/ivy.xml
するとこの通りxmlファイル出したと言われるのでそれを見にいく。中にrevisionがあるのでこれをコピーする。
<info organisation="org.xerial.sbt" module="sbt-sonatype" revision="0.0.0-734-5b5db727" status="integration" publication="20240323224111" e:sbtVersion="1.0" e:scalaVersion="2.12">
この場合は0.0.0-734-5b5db727
をコピーしておく。
sbt再設定
プラグインがローカルで使えるようになったので、パブリッシュしたいリポジトリのproject/plugins.sbt
にこれを追加する:
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "0.0.0-734-5b5db727") // ここに指定する addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2")
このように書くことで、sbt
はローカルにあるビルド済みのプラグインを利用してくれるようになる。
build.sbt
には以下を追加する:
import xerial.sbt.Sonatype.sonatypeCentralHost // パブリッシュ先はMaven Centralであることを指定している ThisBuild / publishTo := sonatypePublishToBundle.value ThisBuild / sonatypeCredentialHost := sonatypeCentralHost
クレデンシャル準備
sbt-sonatype
は環境変数からMaven Centralへのログインに必要な情報を読み取るので、環境変数でsonatypeのクレデンシャルを設定する。
これは直接ユーザ/パスワードではなく、ユーザ画面からトークンを作っておくとよい。
このへんはop
コマンドで1Passwordと連携してもいいと思う。
% export SONATYPE_USERNAME="<sonatype_username>" % export SONATYPE_PASSWORD="<sonatype_password>"
署名用GPG鍵準備
Maven Centralは、JARファイルがGPGで署名されていることを要求しているので、GPG鍵の設定もやっておく。鍵は開発者のをそのまま使うのではなく、プロジェクトごとに1つ作るのがよい。
手順は以下の項目に準じている。
% gpg --gen-key Real name: {プロジェクト名 bot} Email address: {ここは自分のメールアドレスにする} You selected this USER-ID: "scala-new-maven-central-exercise bot <windymelt@3qe.us>" Change (N)ame, (E)mail, or (O)kay/(Q)uit? o # これでいいのでoを押す # パスワードを訊かれるので、1Passowrdとかで生成して保存する % LONG_ID=DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF # 生成したPGP鍵の長いIDを環境変数に入れる # 公開鍵を公開する(Linuxの場合) % gpg --keyserver hkp://keyserver.ubuntu.com --send-key $LONG_ID && \ gpg --keyserver hkp://pgp.mit.edu --send-key $LONG_ID && \ gpg --keyserver hkp://pool.sks-keyservers.net --send-key $LONG_ID
プロジェクトのビルド
ついに準備ができたので署名付きJARを生成する。
% sbt "publishSigned"
途中で署名のためにPGP鍵のパスワードを訊かれるので入力する。
最後にMaven Centralにパブリッシュする。
% sbt "sonatypeBundleRelease"
ちなみにコケるとその旨出力されるし、ブラウザからもわかるような通知が出る。
PublishコーナーのDeploymentsに行くと理由が出てるので、これを直す。
ちなみにコケたときはその都度sbtでclean
とcleanIvy
すると成果物が綺麗になるのでヘンなトラブルを回避できる。
うまくいくとこういう出力が出てくる:
2024-03-23 23:27:00.383+0900 info [SonatypeCentralClient] Uploading bundle /home/windymelt/src/github.com/windymelt/scala-new-maven-central-exercise/target/sonatype-staging/0.1.0-SNAPSHOT-bundle/bundle.zip to Sonatype Cent ral - (SonatypeCentralClient.scala:72) 2024-03-23 23:27:02.930+0900 info [SonatypeCentralService] Checking if deployment succeeded for deployment id: 45ea0223-28b8-4a3c-8557-2fe9e2954bef... - (SonatypeCentralService.scala:27) 2024-03-23 23:34:12.115+0900 info [SonatypeCentralClient] Deployment succeeded for deployment id: 45ea0223-28b8-4a3c-8557-2fe9e2954bef. Current deployment state: PUBLISHED - (SonatypeCentralClient.scala:107)
パブリッシュに成功した場合、cs
コマンドから直接起動できるようになるので確認するとよい:
% cs launch dev.capslock::scala-new-maven-central-exercise:0.0.1 Hello world! I was compiled by Scala 3. :)
Further Reading
より本格的なリリースを行うときはここの記述を参考にするとよい。リリース手順だけ手で行うようにすれば、正式にsbt-sonatype
が新Maven Centralに対応するまでのつなぎにできる。