Skip to main content

02 - Publishing

1. Why​

Sinew's Kotlin packages ship to Maven Central. They're released together (lockstep), with a BOM so apps write one version. The base Architecture note sets the rules; this note is the mechanics.

2. Shape​

ArtifactHolds
com.srctool.sinew:sinew-<module>:<v>one per library module, with KMP variants for android, iosArm64, iosSimulatorArm64, jvm, wasmJs
com.srctool.sinew:sinew-bom:<v>pins every Sinew module to <v>
// an app
implementation(platform("com.srctool.sinew:sinew-bom:1.0.0"))
implementation("com.srctool.sinew:sinew-network")
implementation("com.srctool.sinew:sinew-paging")
// devtools: one artifact per variant, in the app module (see DevTools)
"productionDebugImplementation"("com.srctool.sinew:sinew-devtools-ui")
"stagingImplementation"("com.srctool.sinew:sinew-devtools-ui")
"productionReleaseImplementation"("com.srctool.sinew:sinew-devtools-noop")
RuleWhy
One publish job, on macOSThe iOS variants need Xcode. Maven Central rejects the same coordinates published from two hosts.
Every module publishes at the same version, from one tagLockstep: any set of Sinew artifacts at one version fits together
Group com.srctool.sinew. If the srctool.com namespace verification fails: io.github.srctool.sinew.Only the srctool { publishing { groupId } } value changes.
A released version is never deleted. A mistake gets a patch release.Maven Central doesn't allow deletion
sinew-camouflage declares the Camouflage version range it was tested withApps can't silently combine incompatible versions

3. API​

The com.srctool.publish convention plugin (vanniktech 0.37.0 + Dokka + signing) configures:

  • coordinates;
  • the POM (name, description, license Apache 2.0, the srctool/sinew-kotlin SCM URL, developer srctool);
  • signing with an in-memory PGP key.

Secrets in CI: ORG_GRADLE_PROJECT_mavenCentralUsername / …Password (a Central Portal user token), ORG_GRADLE_PROJECT_signingInMemoryKey, …KeyPassword.

4. Build steps​

  1. Verify the com.srctool namespace on the Central Portal (a DNS TXT record on srctool.com).
  2. Apply com.srctool.publish to every library module and the BOM.
  3. A dry run: ./gradlew publishToMavenLocal, then build the sample app against mavenLocal() with the BOM.
  4. The publish workflow: on a v* tag, on macOS, ./gradlew publishAndReleaseToMavenCentral.
  5. A changelog per release, shared by all modules.

Done when

  • A fresh Android app and a fresh KMP app resolve sinew-bom:1.0.0 and every module from Maven Central.
  • Publishing runs from one macOS job only.

5. Edge cases​

CaseDecided behavior
One module needs a fixThe whole set is released at the next patch version, even if other modules are unchanged.
Namespace verification still pending at S6Publish under io.github.srctool.sinew, and move to com.srctool.sinew at the next minor version, with a relocation POM for the old coordinates.
Decided by default (revisit during implementation)
  • Relocation POMs if the group has to move later, so old coordinates keep resolving.