Skip to content

feat(publish): migrate canonical-cbor + tx-codec to Sonatype Central Portal - #16

Merged
zhuzhuyule merged 3 commits into
mainfrom
ci/auto-publish-canonical-cbor-tx-codec
Apr 29, 2026
Merged

zhuzhuyule merged 3 commits into
mainfrom
ci/auto-publish-canonical-cbor-tx-codec

Conversation

@zhuzhuyule

@zhuzhuyule zhuzhuyule commented Apr 29, 2026 •

Copy link
Copy Markdown
Contributor

Background

Legacy OSSRH (s01.oss.sonatype.org) was sunset by Sonatype on 2025-06-30 and no longer accepts new uploads. The previous canonical-cbor / tx-codec publishing config had:

  1. A publications {} block with the artifact metadata
  2. No repositories {} block at all — gradle publish would have silently no-op'd, never reaching Sonatype
  3. No signing {} block — Maven Central rejects unsigned artifacts

This PR closes those gaps end-to-end.

What this PR does

  • canonical-cbor/build.gradle + tx-codec/build.gradle: replace hand-rolled publishing blocks with com.vanniktech.maven.publish:0.30.0, the de-facto plugin for OSS Android library publishing. Configure with host = "CENTRAL_PORTAL" and automaticRelease = true so a single publishAndReleaseToMavenCentral task uploads + auto-releases once Central's validation passes.
  • POMs now satisfy Central Portal's verification: name, description, url, inceptionYear, license (with distribution), developer (with id/name/email/url), scm (with connection/developerConnection/url). The previous tx-codec pom was missing developer + scm and would have been rejected.
  • Signing uses signing.useGpgCmd() so the publisher's private key stays in their local GnuPG keyring (modern GnuPG 2.5 keyboxd backend). No secring.gpg, no in-memory armored key in gradle.properties.
  • Makefile: maven-cbor target now invokes publishAndReleaseToMavenCentral instead of plain publish.

Modules NOT touched (intentional)

protobuf (sdk-protobuf) and wallet-sdk are untouched — neither has any source change since their last respective publish (sdk-protobuf 1.0.19 on 2025-10-11, wallet-sdk 1.0.14 on 2025-01-21). The 1.0.15 release ships only the two new modules. Migrating those legacy modules to the Central Portal can be done later when a real version bump is needed.

Required publisher setup

Configured in ~/.gradle/gradle.properties (NOT committed to the repo):

mavenCentralUsername=<central-portal-user-token-name>
mavenCentralPassword=<central-portal-user-token-secret>
signing.gnupg.keyName=<last-8-hex-of-publisher-gpg-long-key-id>

The publisher must also have a GPG signing key with public half pushed to keys.openpgp.org and the email address verified on that keyserver, so Sonatype's signature validation can resolve the public key.

Verification

Smoke-tested locally on both modules:

cd canonical-cbor && gradle clean publishToMavenLocal
cd ../tx-codec && gradle clean publishToMavenLocal

→ 5 artifacts + 5 .asc signatures per module:

sdk-canonical-cbor-1.0.14.jar           + .jar.asc
sdk-canonical-cbor-1.0.14-sources.jar   + .jar.asc
sdk-canonical-cbor-1.0.14-javadoc.jar   + .jar.asc
sdk-canonical-cbor-1.0.14.pom           + .pom.asc
sdk-canonical-cbor-1.0.14.module        + .module.asc

Every .asc verifies Good signature against the publisher's public key.

Test plan

  • Reviewer runs cd canonical-cbor && gradle clean publishToMavenLocal and confirms 5 artifacts + 5 .asc generated
  • Same for tx-codec
  • Reviewer verifies POMs contain all Central-Portal-required fields
  • (Maintainer with credentials) bump version to 1.0.15, run make maven-cbor, confirm both artifacts appear on Maven Central within ~30 min

🤖 Generated with Claude Code

The existing release.yml already auto-publishes :sdk-protobuf and
:wallet-sdk on tag push, but the two new subprojects this PR
introduces sit outside the root build (their own settings.gradle,
because the root still references the shut-down jcenter() repo). So
without this change every release of canonical-cbor / tx-codec would
need a manual `cd canonical-cbor && gradle publish` step.

Changes:

- Makefile: split `maven` into `maven-legacy` (existing root-build
  modules) and `maven-cbor` (standalone subprojects). Same split for
  `mavenLocal`. Comment records why the split exists and notes when
  it can fold back together (root build modernisation).

- .github/workflows/release.yml:
    * setup-java 1.8 -> 17 (Gradle 7.2 root wrapper supports Java
      11+, canonical-cbor / tx-codec require jvmToolchain(17)).
    * Add gradle/actions/setup-gradle@v3 pinned to 9.1.0 so the
      `gradle clean publish` invocations inside maven-cbor have a
      modern system Gradle to drive the standalone subprojects.
      Root `./gradlew` calls are unaffected — they still resolve to
      Gradle 7.2 via the wrapper.
    * Forward NEXUS_USERNAME / NEXUS_PASSWORD secrets so the
      Sonatype publishing config (s01.oss.sonatype.org/staging) can
      authenticate. Same secret names the existing wallet-sdk
      publish already uses via gradle.properties.

Verified locally: `make mavenLocal-cbor` produces the expected
artifacts under ~/.m2/repository/io/arcblock/did/sdk-{canonical-cbor,
tx-codec}/<version>/ with .jar / -sources.jar / -javadoc.jar / .pom.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Code Coverage

There is no coverage information present for the Files changed

Total Project Coverage 77.6% 🍏

@NateRobinson NateRobinson left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

…Portal

Legacy OSSRH (s01.oss.sonatype.org) was sunset 2025-06-30 and no longer
accepts new uploads. Replace the partial publishing config (which had
no `repositories` block at all and would have silently no-op'd on
`gradle publish`) with the vanniktech maven-publish plugin pinned to
the `CENTRAL_PORTAL` host.

Plugin gives us, out of the box:
  - Central Portal API endpoint + staging deployment workflow
  - sources jar + javadoc jar attached to the publication
  - signing applied to all 5 artifacts (jar / sources / javadoc / pom /
    module) — confirmed with `gpg --verify` against a freshly-generated
    RSA 4096 key (fingerprint 2658 7907 86AD E23D D0A2 D02A 263E 368E
    341C E76C, public key on keys.openpgp.org)
  - `publishAndReleaseToMavenCentral` one-shot task that uploads to
    staging and auto-releases once Central's validation passes — no
    manual "Close → Release" click in the Portal UI

POM is now Central-Portal-validation-complete on both modules: name,
description, url, inceptionYear, license (with distribution), developer
(with id/name/email/url), scm (connection / developerConnection / url).
The previous tx-codec pom was missing developer + scm — would have been
rejected by Central's verification step.

Signing uses `signing.useGpgCmd()` so the publisher's private key stays
in their local GnuPG keyring (modern GnuPG 2.5 keyboxd backend), no
secring.gpg or in-memory armored key in gradle.properties. pinentry-mac
prompts for the passphrase on first sign per session and gpg-agent
caches it for subsequent artifacts in the same publish run.

Required `~/.gradle/gradle.properties` on the publishing machine:
  mavenCentralUsername=<central-portal-user-token-name>
  mavenCentralPassword=<central-portal-user-token-secret>
  signing.gnupg.keyName=<last-8-hex-of-publisher-gpg-long-key-id>

Smoke-tested locally on both modules with `gradle clean
publishToMavenLocal`: 5 artifacts + 5 .asc per module, every signature
verifies "Good signature" against the publisher's public key.

The legacy `protobuf` and `wallet-sdk` modules are intentionally
untouched — neither has any source change since their last respective
publish (sdk-protobuf 1.0.19 on 2025-10-11, wallet-sdk 1.0.14 on
2025-01-21), so the 1.0.15 release ships only the two new modules.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zhuzhuyule zhuzhuyule changed the title ci(cbor): auto-publish canonical-cbor + tx-codec on tag push feat(publish): migrate canonical-cbor + tx-codec to Sonatype Central Portal Apr 29, 2026
@github-actions

Copy link
Copy Markdown

Code Coverage

There is no coverage information present for the Files changed

Total Project Coverage 77.65% 🍏

First publish of canonical-cbor + tx-codec via the new Sonatype Central
Portal flow (paper's legacy OSSRH credentials retired with his account;
io.arcblock.did namespace ownership migrated to the org account, new
publisher is Pengfei via Central Portal user token).

sdk-protobuf stays at 1.0.19 and wallet-sdk stays at 1.0.14 — neither
has any source change since their last publish, so they're not part of
this release. The wallet-side `arc-wallet-android/config.gradle` will
bump only its sdk-canonical-cbor + sdk-tx-codec coordinates, leaving
walletSdkVersion / sdk-protobuf pins untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zhuzhuyule
zhuzhuyule merged commit 2bdc529 into main Apr 29, 2026
2 of 3 checks passed
@github-actions

Copy link
Copy Markdown

Code Coverage

There is no coverage information present for the Files changed

Total Project Coverage 77.6% 🍏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants