Problem
JitPack does not currently publish usable artifacts for the modular retrofit-graphql modules. This blocks downstream consumers, especially anitrend-app, from moving away from the deprecated :library facade and onto direct module dependencies.
The issue was reproduced against commit 7d56b74166. The same publishing configuration is still present on develop at the time this issue was written.
Impact
anitrend-app cannot safely begin the import migration or modular dependency swap until retrofit-graphql publishes real module artifacts with correct Maven metadata.
Expected downstream usage should be possible with JitPack coordinates similar to:
implementation("com.github.AniTrend.retrofit-graphql:runtime:<sha-or-tag>")
implementation("com.github.AniTrend.retrofit-graphql:api:<sha-or-tag>")
implementation("com.github.AniTrend.retrofit-graphql:android-assets:<sha-or-tag>")
implementation("com.github.AniTrend.retrofit-graphql:annotations:<sha-or-tag>")
implementation("com.github.AniTrend.retrofit-graphql:serialization-kotlinx:<sha-or-tag>")
Exact casing/path should be verified against JitPack output, but the important requirement is that each intended module resolves as its own artifact instead of returning 404 or relying on the broken facade.
Current Behavior
jitpack.yml runs:
./gradlew build --stacktrace --no-daemon -x lint -x lintVitalRelease
./gradlew publishMavenPublicationToMavenLocal --no-daemon
Source: jitpack.yml.
The repository includes the relevant modules:
:annotations
:api
:android-assets
:runtime
:codegen-core
:serialization-gson
:serialization-kotlinx
:library
Source: settings.gradle.kts.
However, only the deprecated facade :library currently creates a Maven publication.
In buildSrc/src/main/java/co/anitrend/retrofit/graphql/buildSrc/plugin/components/AndroidOptions.kt, publication creation is guarded behind:
// Only publish from the facade :library module
if (isFacadeModule()) {
createMavenPublicationUsing(sourcesJar)
}
isFacadeModule() only matches :library.
The Android modules :api, :android-assets, :runtime, :serialization-gson, and :serialization-kotlinx are recognised as library modules and get maven-publish applied, but no publication is registered for them.
The JVM modules :annotations and :codegen-core do not apply the shared Android plugin path and also do not register publications.
Additional Defect: Facade Publication Is Not Component-Backed
The existing publication code uses:
val component = components.findByName("android")
logger.lifecycle("Configuring maven publication options for ${project.path}:maven with component-> ${component?.name}")
The observed JitPack log includes:
Configuring maven publication options for :library:maven with component-> null
That means the current publication is not backed by a real Android software component. The publication then manually attaches:
artifact("${project.layout.buildDirectory.get()}/outputs/aar/${project.name}-release.aar")
from(component)
This is brittle and likely prevents Gradle from emitting correct variant metadata and transitive dependencies into the generated POM/module metadata.
That explains the current symptom: the root/facade artifact behaves like an empty shell and does not bring in the real implementation modules.
Expected Behavior
Every externally consumable module must publish a real Maven artifact:
Android AAR Modules
:api
:android-assets
:runtime
:serialization-gson
:serialization-kotlinx
:library only if keeping the deprecated facade published for backward compatibility
JVM JAR Modules
:annotations
:codegen-core if codegen internals are intended to be consumed by the Gradle plugin or external tooling
Gradle Plugin Module
:gradle-plugin needs an explicit decision.
- If the plugin is intended to be consumed from JitPack, it must publish plugin marker metadata and the plugin artifact correctly.
- If not in scope for this issue, document that exclusion clearly so the implementation does not half-publish it.
Implementation Guidelines
Do not patch this by adding copy-pasted publishing {} blocks to each module unless there is a strong reason. The repo already centralizes build behavior in buildSrc; publishing should stay centralized there.
Recommended direction:
-
Split publishing configuration by module kind:
- Android library modules publish AARs.
- JVM modules publish JARs.
- Gradle plugin module is handled separately or explicitly excluded.
-
For Android libraries, configure AGP publishing explicitly.
Use Android Gradle Plugin publishing APIs, for example:
android {
publishing {
singleVariant("release") {
withSourcesJar()
}
}
}
Then publish from the real release component:
publishing {
publications {
create<MavenPublication>("release") {
from(components["release"])
artifactId = project.name
}
}
}
Do not use components.findByName("android").
Do not manually attach build/outputs/aar/<module>-release.aar unless there is a documented reason. A component-backed publication is required so Gradle can generate correct metadata.
-
For JVM modules, apply maven-publish and publish from the Java component:
publishing {
publications {
create<MavenPublication>("maven") {
from(components["java"])
artifactId = project.name
}
}
}
Add sources JAR support for JVM modules as well.
-
Use stable artifact IDs:
:api -> api
:android-assets -> android-assets
:runtime -> runtime
:annotations -> annotations
:serialization-gson -> serialization-gson
:serialization-kotlinx -> serialization-kotlinx
:codegen-core -> codegen-core, if published
:library -> either retrofit-graphql for backward compatibility, or library only if intentionally breaking old coordinates
-
Keep :library as a backward-compatible facade for now.
Its POM must declare transitive dependencies on the real module artifacts. Consumers of the old aggregate coordinate should still work, but new consumers must be able to depend directly on individual modules.
-
Update documentation if coordinates change or become available:
README.md
MIGRATION.md
AGENTS.md
.agents/skills/retrofit-graphql-build-dependencies/references/build-map.md
Test Strategy
The fix is not complete until it is verified both locally and via JitPack.
1. Clean Local Maven State
Run from the repository root:
rm -rf ~/.m2/repository/co/anitrend/retrofit-graphql
rm -rf ~/.m2/repository/com/github/AniTrend/retrofit-graphql
rm -rf ~/.m2/repository/com/github/anitrend/retrofit-graphql
./gradlew clean --no-daemon
2. Inspect Available Publish Tasks
Run:
./gradlew tasks --all | grep -i publish
Expected result:
There should be publish tasks for each intended module, not only :library.
Examples of acceptable task names depend on the chosen publication name, but the output should include module-specific tasks for:
:api
:android-assets
:runtime
:annotations
:serialization-gson
:serialization-kotlinx
:library
:codegen-core, if published
3. Run the Same Task JitPack Runs
Run:
./gradlew build --stacktrace --no-daemon -x lint -x lintVitalRelease
./gradlew publishMavenPublicationToMavenLocal --stacktrace --no-daemon
If the publication names change from maven, either keep a compatible aggregate task or update jitpack.yml accordingly. JitPack must invoke a task that publishes every intended artifact to Maven local.
4. Verify Files Exist in Maven Local
Check local Maven output. Depending on final group ID, inspect the actual generated path under ~/.m2/repository.
At minimum, each published module must have:
.pom
.module metadata, unless intentionally disabled
.aar for Android modules
.jar for JVM modules
-sources.jar
Suggested verification:
find ~/.m2/repository -path '*retrofit-graphql*' -type f | sort
Then verify the expected module artifacts exist. Example patterns:
find ~/.m2/repository -path '*runtime*' -name '*.pom' -o -path '*runtime*' -name '*.aar'
find ~/.m2/repository -path '*api*' -name '*.pom' -o -path '*api*' -name '*.aar'
find ~/.m2/repository -path '*android-assets*' -name '*.pom' -o -path '*android-assets*' -name '*.aar'
find ~/.m2/repository -path '*annotations*' -name '*.pom' -o -path '*annotations*' -name '*.jar'
Do not rely only on the Gradle task succeeding. The generated files must be inspected.
5. Verify POM Dependencies
Inspect generated POMs directly.
Examples:
cat ~/.m2/repository/**/runtime/**/*.pom
cat ~/.m2/repository/**/library/**/*.pom
cat ~/.m2/repository/**/retrofit-graphql/**/*.pom
Required checks:
:runtime POM declares dependencies on api, android-assets, and annotations where appropriate.
:android-assets POM declares dependency on annotations.
:serialization-gson and :serialization-kotlinx POMs declare dependency on api.
:library facade POM declares dependencies on all modules it re-exports.
- Dependency scopes are sensible. API-facing dependencies should not be accidentally hidden as runtime-only if consumers need them at compile time.
6. Verify Artifact Contents
Inspect archives, not just filenames.
For Android AARs:
unzip -l ~/.m2/repository/**/runtime/**/*.aar | head -100
unzip -l ~/.m2/repository/**/api/**/*.aar | head -100
unzip -l ~/.m2/repository/**/android-assets/**/*.aar | head -100
For JVM JARs:
jar tf ~/.m2/repository/**/annotations/**/*.jar | head -100
jar tf ~/.m2/repository/**/codegen-core/**/*.jar | head -100
Required checks:
runtime contains converter implementation classes.
api contains public API/model contracts.
android-assets contains asset discovery/processor implementation classes.
annotations contains GraphQuery annotation classes.
library may be thin, but if it remains a facade its metadata must be correct.
7. Add a Throwaway Consumer Verification
Create a temporary consumer project outside the repo, or use a detached Gradle init project, and resolve the local Maven artifacts.
Example:
repositories {
google()
mavenCentral()
mavenLocal()
}
dependencies {
implementation("<resolved-group>:runtime:<resolved-version>")
implementation("<resolved-group>:api:<resolved-version>")
implementation("<resolved-group>:android-assets:<resolved-version>")
implementation("<resolved-group>:annotations:<resolved-version>")
}
Then run:
./gradlew dependencies --configuration debugRuntimeClasspath
./gradlew compileDebugKotlin
Required checks:
- Dependencies resolve from
mavenLocal().
- Kotlin imports compile against direct module artifacts.
- No dependency on the deprecated
:library facade is required for modular usage.
8. Verify JitPack After Merge
After merge, trigger or wait for JitPack to build the target commit/tag.
Then verify module URLs resolve with HTTP 200 instead of 404. Example shape:
curl -I https://jitpack.io/com/github/AniTrend/retrofit-graphql/runtime/<sha-or-tag>/runtime-<sha-or-tag>.pom
curl -I https://jitpack.io/com/github/AniTrend/retrofit-graphql/api/<sha-or-tag>/api-<sha-or-tag>.pom
curl -I https://jitpack.io/com/github/AniTrend/retrofit-graphql/android-assets/<sha-or-tag>/android-assets-<sha-or-tag>.pom
curl -I https://jitpack.io/com/github/AniTrend/retrofit-graphql/annotations/<sha-or-tag>/annotations-<sha-or-tag>.pom
If JitPack normalizes owner/repo casing, adjust the URL casing and document the working form in the PR.
Also verify in a real consumer Gradle build using JitPack repository:
repositories {
google()
mavenCentral()
maven("https://jitpack.io")
}
Required checks:
- Direct modular dependencies resolve.
- Old facade coordinate still resolves if backward compatibility is retained.
- No 404 for published modules.
- No empty-root-only artifact behavior.
Acceptance Criteria
References
- JitPack multi-module convention:
com.github.USER.REPO:MODULE:VERSION, where MODULE is the artifact ID.
- Android Gradle Plugin publishing API: use
android.publishing.singleVariant(...) and publish from the generated component, e.g. components["release"].
- Repository canonical build guidance:
AGENTS.md and .agents/skills/retrofit-graphql-build-dependencies/references/build-map.md.
Problem
JitPack does not currently publish usable artifacts for the modular
retrofit-graphqlmodules. This blocks downstream consumers, especiallyanitrend-app, from moving away from the deprecated:libraryfacade and onto direct module dependencies.The issue was reproduced against commit
7d56b74166. The same publishing configuration is still present ondevelopat the time this issue was written.Impact
anitrend-appcannot safely begin the import migration or modular dependency swap untilretrofit-graphqlpublishes real module artifacts with correct Maven metadata.Expected downstream usage should be possible with JitPack coordinates similar to:
Exact casing/path should be verified against JitPack output, but the important requirement is that each intended module resolves as its own artifact instead of returning 404 or relying on the broken facade.
Current Behavior
jitpack.ymlruns:Source:
jitpack.yml.The repository includes the relevant modules:
:annotations:api:android-assets:runtime:codegen-core:serialization-gson:serialization-kotlinx:librarySource:
settings.gradle.kts.However, only the deprecated facade
:librarycurrently creates a Maven publication.In
buildSrc/src/main/java/co/anitrend/retrofit/graphql/buildSrc/plugin/components/AndroidOptions.kt, publication creation is guarded behind:isFacadeModule()only matches:library.The Android modules
:api,:android-assets,:runtime,:serialization-gson, and:serialization-kotlinxare recognised as library modules and getmaven-publishapplied, but no publication is registered for them.The JVM modules
:annotationsand:codegen-coredo not apply the shared Android plugin path and also do not register publications.Additional Defect: Facade Publication Is Not Component-Backed
The existing publication code uses:
The observed JitPack log includes:
That means the current publication is not backed by a real Android software component. The publication then manually attaches:
artifact("${project.layout.buildDirectory.get()}/outputs/aar/${project.name}-release.aar") from(component)This is brittle and likely prevents Gradle from emitting correct variant metadata and transitive dependencies into the generated POM/module metadata.
That explains the current symptom: the root/facade artifact behaves like an empty shell and does not bring in the real implementation modules.
Expected Behavior
Every externally consumable module must publish a real Maven artifact:
Android AAR Modules
:api:android-assets:runtime:serialization-gson:serialization-kotlinx:libraryonly if keeping the deprecated facade published for backward compatibilityJVM JAR Modules
:annotations:codegen-coreif codegen internals are intended to be consumed by the Gradle plugin or external toolingGradle Plugin Module
:gradle-pluginneeds an explicit decision.Implementation Guidelines
Do not patch this by adding copy-pasted
publishing {}blocks to each module unless there is a strong reason. The repo already centralizes build behavior inbuildSrc; publishing should stay centralized there.Recommended direction:
Split publishing configuration by module kind:
For Android libraries, configure AGP publishing explicitly.
Use Android Gradle Plugin publishing APIs, for example:
android { publishing { singleVariant("release") { withSourcesJar() } } }Then publish from the real release component:
publishing { publications { create<MavenPublication>("release") { from(components["release"]) artifactId = project.name } } }Do not use
components.findByName("android").Do not manually attach
build/outputs/aar/<module>-release.aarunless there is a documented reason. A component-backed publication is required so Gradle can generate correct metadata.For JVM modules, apply
maven-publishand publish from the Java component:publishing { publications { create<MavenPublication>("maven") { from(components["java"]) artifactId = project.name } } }Add sources JAR support for JVM modules as well.
Use stable artifact IDs:
:api->api:android-assets->android-assets:runtime->runtime:annotations->annotations:serialization-gson->serialization-gson:serialization-kotlinx->serialization-kotlinx:codegen-core->codegen-core, if published:library-> eitherretrofit-graphqlfor backward compatibility, orlibraryonly if intentionally breaking old coordinatesKeep
:libraryas a backward-compatible facade for now.Its POM must declare transitive dependencies on the real module artifacts. Consumers of the old aggregate coordinate should still work, but new consumers must be able to depend directly on individual modules.
Update documentation if coordinates change or become available:
README.mdMIGRATION.mdAGENTS.md.agents/skills/retrofit-graphql-build-dependencies/references/build-map.mdTest Strategy
The fix is not complete until it is verified both locally and via JitPack.
1. Clean Local Maven State
Run from the repository root:
2. Inspect Available Publish Tasks
Run:
./gradlew tasks --all | grep -i publishExpected result:
There should be publish tasks for each intended module, not only
:library.Examples of acceptable task names depend on the chosen publication name, but the output should include module-specific tasks for:
:api:android-assets:runtime:annotations:serialization-gson:serialization-kotlinx:library:codegen-core, if published3. Run the Same Task JitPack Runs
Run:
If the publication names change from
maven, either keep a compatible aggregate task or updatejitpack.ymlaccordingly. JitPack must invoke a task that publishes every intended artifact to Maven local.4. Verify Files Exist in Maven Local
Check local Maven output. Depending on final group ID, inspect the actual generated path under
~/.m2/repository.At minimum, each published module must have:
.pom.modulemetadata, unless intentionally disabled.aarfor Android modules.jarfor JVM modules-sources.jarSuggested verification:
Then verify the expected module artifacts exist. Example patterns:
Do not rely only on the Gradle task succeeding. The generated files must be inspected.
5. Verify POM Dependencies
Inspect generated POMs directly.
Examples:
Required checks:
:runtimePOM declares dependencies onapi,android-assets, andannotationswhere appropriate.:android-assetsPOM declares dependency onannotations.:serialization-gsonand:serialization-kotlinxPOMs declare dependency onapi.:libraryfacade POM declares dependencies on all modules it re-exports.6. Verify Artifact Contents
Inspect archives, not just filenames.
For Android AARs:
For JVM JARs:
Required checks:
runtimecontains converter implementation classes.apicontains public API/model contracts.android-assetscontains asset discovery/processor implementation classes.annotationscontainsGraphQueryannotation classes.librarymay be thin, but if it remains a facade its metadata must be correct.7. Add a Throwaway Consumer Verification
Create a temporary consumer project outside the repo, or use a detached Gradle init project, and resolve the local Maven artifacts.
Example:
repositories { google() mavenCentral() mavenLocal() } dependencies { implementation("<resolved-group>:runtime:<resolved-version>") implementation("<resolved-group>:api:<resolved-version>") implementation("<resolved-group>:android-assets:<resolved-version>") implementation("<resolved-group>:annotations:<resolved-version>") }Then run:
Required checks:
mavenLocal().:libraryfacade is required for modular usage.8. Verify JitPack After Merge
After merge, trigger or wait for JitPack to build the target commit/tag.
Then verify module URLs resolve with HTTP 200 instead of 404. Example shape:
If JitPack normalizes owner/repo casing, adjust the URL casing and document the working form in the PR.
Also verify in a real consumer Gradle build using JitPack repository:
repositories { google() mavenCentral() maven("https://jitpack.io") }Required checks:
Acceptance Criteria
:library.:libraryremains a valid backward-compatible facade or its removal is explicitly documented as a breaking change.publishMavenPublicationToMavenLocaloutput has been inspected and documented in the PR.mavenLocal().References
com.github.USER.REPO:MODULE:VERSION, whereMODULEis the artifact ID.android.publishing.singleVariant(...)and publish from the generated component, e.g.components["release"].AGENTS.mdand.agents/skills/retrofit-graphql-build-dependencies/references/build-map.md.