OSSRHからCentral Publisher Portalに移行してハマった話

# What's？

OSSRHから、2025年6月30日にサポート終了するという発表がありました。

https://central.sonatype.org/news/20250326_ossrh_sunset/

これに伴いCentral Publisher Portalへ移行を行ったのですが、いくつかハマったポイントがあったのでメモしておきます。

# OSSRHからCentral Publisher Portalへの移行

通常は、以下のドキュメントに従えばよいと思います。

https://central.sonatype.org/faq/what-is-different-between-central-portal-and-legacy-ossrh/

OSSRHとCentral Publisher Portalでアカウントは同じです。

OSSRHで使用していたアカウントでCentral Publisher Portalにログインし、以下を行います。

- [namespaceの移行](https://central.sonatype.org/faq/what-is-different-between-central-portal-and-legacy-ossrh/#process-to-migrate)
- [ユーザートークンの生成](https://central.sonatype.org/publish/generate-portal-token/)

デプロイは、Apache Mavenの場合central-publishing-maven-pluginを使います。

https://central.sonatype.org/publish/publish-portal-maven/

ここで生成したユーザートークンを利用します。

あとは`mvn deploy`し、アップロードされたデプロイメントを公開することになります。

ちなみに、central-publishing-maven-pluginは0.7.0の時点ではプロキシ越しのアクセスができません。  
Apache HttpClientを使っていますが、特にプロキシを考慮した実装にはなっていませんでした。

デプロイするアーティファクトに必要な要件（Javadocやソースの提供、チェックサムやGPG/PGP署名の作成、メタデータの提供など）はOSSRHの時と同じです。

https://central.sonatype.org/publish/requirements/

ちなみに公開はまだ未実施なので、この後でなにかあったら追記します。

# OSSRHとの違いで困った（？）ところ

ここからはOSSRHとの違いで戸惑ったところ、困ったところを書いていきます。

## ステージングリポジトリがない？

OSSRHの時は`mvn deploy`した後に「Close」を行い、ステージングリポジトリで参照可能にした後で「Release」してCentralに公開するという流れでした。

Central Publisher PortalではCloseしてステージングリポジトリに反映するということがなく、デプロイ時に検証が完了すればCentralへ反映する前に確認できるようになります。

イメージ的には、いきなりステージングリポジトリに反映されるようなものですね。

Central公開前の動作確認などで、この状態のデプロイメントを使用するには、以下の手順に従います。

[Publishing By Using the Portal Publisher API / Manually Testing a Deployment Bundle](https://central.sonatype.org/publish/publish-portal-api/#manually-testing-a-deployment-bundle)

アクセス先のリポジトリはこちらになりますね。

```xml
        <repository>
          <id>central.manual.testing</id>
          <name>Central Testing repository</name>
          <url>https://central.sonatype.com/api/v1/publisher/deployments/download</url>
        </repository>
```

アクセスするには認証情報が必要です。  
※Bearerの値はドキュメントのサンプルそのままです

```xml
    <server>
      <id>central.manual.testing</id>
      <configuration>
        <httpHeaders>
          <property>
            <name>Authorization</name>
            <value>Bearer ZXhhbXBsZV91c2VybmFtZTpleGFtcGxlX3Bhc3N3b3Jk</value>
          </property>
        </httpHeaders>
      </configuration>
    </server>
```

認証情報は、生成したユーザートークンのユーザー名とパスワードを結合し、Base64エンコードすることで作成します。

[Publishing By Using the Portal Publisher API / Authentication / Authorization](https://central.sonatype.org/publish/publish-portal-api/#authentication-authorization)

## 親子関係のあるアーティファクトのデプロイ方法によっては、子の検証がパスしない

OSSRHを使用していたアーティファクトでは以下のような運用を行っていたのですが、これが問題になりました。

- 親子関係のあるアーティファクトを別々のリポジトリで管理していた
- OSSRHが`pom.xml`に求めるメタデータは、親アーティファクト側に集約していた
- 各アーティファクトはそれぞれのタイミングで`mvn deploy`していた
- Centralへの公開タイミングは同時にしていた

たとえば以下のように、親子関係のある2つのアーティファクトの新しいバージョンをリリースするとします。

- 親アーティファクト： 2.0.0
- 子アーティファクト： 2.0.0

ここでいう親子関係とは、`pom.xml`の`parent`に設定していることを言います。

各アーティファクトをそれぞれ`mvn deploy`でデプロイする場合、子アーティファクトから見て親アーティファクトが解決できるためには、親アーティファクトがCentralに公開されている必要があります。

これがこちらの環境と合わず、親アーティファクトから継承することを期待していためたーデータが補完されず、子アーティファクトがデプロイ時の検証に合格しませんでした。

検証時に以下のようなエラーを目にすることになりました。

```
- Dependency version information is missing
- Developers information is missing
- License information is missing
- Project URL is not defined
- Project description is missing
- SCM URL is not defined
```

依存関係のバージョンは、親アーティファクトの`dependencyManagement`で依存関係を宣言し、子アーティファクトでは依存ライブラリの`version`を省略しているケースで発生します。

これを回避するには、1回の`mvn deploy`の実行で親子のアーティファクトを同時にデプロイする必要があります。  
同時にデプロイした場合（デプロイするのはすべてのファイルをまとめたzipファイル）、親アーティファクトが公開されていなくても子アーティファクトは親アーティファクトの情報を参照できます。

OSSRHでは`mvn deploy`の単位が別々でもこのような動作にならなかったため、最初は検証がなぜNGになるのかがわかりませんでした。

まあ、まとめてデプロイするようにするか、先に親アーティファクトを公開しておこうという話なのですが…。

なお、`dependency`に書かれているアーティファクトは公開されていなくてもOKです。

ハマる人は少ないような気がするのですが、どこにも情報がなかったのでメモしておきます…