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
| Artifact | Holds |
|---|---|
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")
| Rule | Why |
|---|---|
| One publish job, on macOS | The iOS variants need Xcode. Maven Central rejects the same coordinates published from two hosts. |
| Every module publishes at the same version, from one tag | Lockstep: 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 with | Apps 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-kotlinSCM URL, developersrctool); - 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
- Verify the
com.srctoolnamespace on the Central Portal (a DNS TXT record onsrctool.com). - Apply
com.srctool.publishto every library module and the BOM. - A dry run:
./gradlew publishToMavenLocal, then build the sample app againstmavenLocal()with the BOM. - The publish workflow: on a
v*tag, on macOS,./gradlew publishAndReleaseToMavenCentral. - A changelog per release, shared by all modules.
Done when
- A fresh Android app and a fresh KMP app resolve
sinew-bom:1.0.0and every module from Maven Central. - Publishing runs from one macOS job only.
5. Edge cases
| Case | Decided behavior |
|---|---|
| One module needs a fix | The whole set is released at the next patch version, even if other modules are unchanged. |
| Namespace verification still pending at S6 | Publish 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.