Publishing
build-logic handles two publish channels: Maven artifacts to the self-hosted
Reposilite repository, and mod releases to Modrinth. Both are driven from the
matrix so a release fans out across every target without listing versions in a
workflow.
Maven Coordinates
gradle/publishing.properties is the single source of truth for the group and
target repository:
Per-target versioning
Each target is its own Maven version, using a Fabric-style suffix
<base>+<minecraft> (for example 1.22.0+1.21.10). Every target's module
metadata (Java level, transitive deps) is therefore isolated and never collides
with another target's. Consumers still declare the bare base version; the
consumer plugins mirror the suffix from their resolved target.
The main jar carries no Minecraft classifier (the branch is already in the
version, same as fabric-api). Classifiers are reserved for genuinely different
jars: all (shaded fat jar), dev, and sources.
Publishing To Reposilite
Publish tasks are grouped by category so a release can target the right subset:
| Task | What it publishes |
|---|---|
publishDefaultMatrix | Every publishable module on the default target. |
publishCommonMatrix | Common (platform-neutral) modules — use with -Ptarget=. |
publishFabricMatrix | Fabric-matrix modules — use with -Ptarget=. |
Point publishing at the repo and supply credentials via environment variables
(PUBLISH_USER / PUBLISH_TOKEN), read by the publish plugin:
The CI publish job reads printPublishMatrix and runs one unit per target in
parallel, each writing to a disjoint artifact path — so no assembly step is
needed. The build-logic plugins themselves are published to the same repo, so
external consumers resolve them alongside the library.
Publishing To Modrinth
A Modrinth release is declared in magicMatrix { modrinth { } }. It is opt-in:
without a projectId there is nothing to publish.
Loaders per platform
Set platform = "..." on an artifact and the Modrinth loader list is derived
for you (leave loaders empty). The built-in mapping is:
platform | Modrinth loaders |
|---|---|
bukkit | paper, purpur, spigot, bukkit, folia |
bungee | bungeecord, waterfall |
velocity | velocity |
fabric | fabric |
neoforge | neoforge |
Set loaders = listOf(...) explicitly when you need to override the mapping.
The bukkit bundle claims the folia loader — that claim is backed by a real
Folia smoke run (see Dev Server & Smoke), even though
there is no separate folia-bundle jar.
Auto-derived artifacts
You usually don't list artifact(...) blocks at all. When the modrinth { }
block declares none, the release tasks derive one artifact per (platform ×
smoke game-version) straight from the smoke matrix: the platform picks the
loader set, the target picks the jar name
(magicutils-<platform>-bundle-<base>+<mc>.jar), and the smoke entry's
versions expand into the Modrinth game_versions. This keeps the published
release and the smoke gate in lockstep — you never hand-maintain a parallel
artifact list. Smoke-only platforms that ship no bundle of their own (such as
folia) are skipped by the generator. Declare explicit artifact(...) entries
only to override the derived set.
Changelog
Every uploaded version carries a Markdown changelog. Its resolution order:
-PmodrinthChangelogFile=path— read the changelog from that file.- An explicit
changelog = "..."string in themodrinth { }block. - Otherwise it is generated from git history: conventional-commit subjects
since the previous tag are grouped into sections (
feat→ Added,fix→ Fixed,perf→ Improved,refactor→ Changed, the rest → Maintenance). Merge,fixup!/squash!, and version-bump commits are dropped. Override the diff base with-PmodrinthPreviousTag=<tag>.
Then publish one version per declared or derived artifact:
Behaviour:
- The token comes only from
MODRINTH_TOKEN, never from the build script. - The task is idempotent: a version number that already exists on the project is skipped, so re-running a release is safe.
-Pversionsets the base version; each artifact's Modrinth version number is derived from it.
Release Fan-Out
printReleaseMatrix emits one JSON row per (platform × smoke entry) with the
target, artifact classifier, and game-version ranges. A consumer's release
workflow turns each row into a build command and a Modrinth upload, so the same
matrix that builds and smoke-tests also drives the release.