Summary
pulumi-java-gen emits a build.gradle whose POM <name>, <inceptionYear>, and <developers> block are populated only when the package metadata satisfies isPublishedByPulumi(pkg). The same gated branch also rewrites groupId to com.pulumi. As a result, a provider that wants a non-com.pulumi groupId (e.g. com.pulumi.labs, or a third-party publisher) cannot get those POM fields filled in at all, even when its schema carries a DisplayName, Publisher, and License that could populate them.
Maven Central rejects publications with an empty <name> (and complains about missing developer information), so any non-Pulumi groupId requires post-codegen string surgery on the generated build.gradle to ship.
Where this lives
pkg/codegen/java/templates_gradle.go — newGradleTemplateContext:
if isPublishedByPulumi(pkg) {
ctx.GroupID = "com.pulumi"
ctx.DeveloperID = "pulumi"
ctx.DeveloperName = "Pulumi"
ctx.DeveloperEmail = "support@pulumi.com"
ctx.ProjectInceptionYear = "2022"
ctx.ProjectName = fmt.Sprintf("pulumi-%s", ctx.Name)
}
isPublishedByPulumi keys off pkg.Publisher == "pulumi" (case-insensitive) or pkg.Homepage host being pulumi.com/pulumi.io.
pkg/codegen/java/package_info.go (the LanguageMap.java payload) exposes only BasePackage, BuildFiles, Repositories, Dependencies, GradleNexusPublishPluginVersion, GradleTest — none of which can override the POM identity fields above.
Net effect: anyone publishing under a non-com.pulumi groupId is forced to pick one of:
- Set
Publisher: "Pulumi" / Homepage: https://pulumi.com/... to trigger the branch, then accept that groupId is silently rewritten to com.pulumi (defeating the original intent).
- Leave
Publisher as something else and live with an empty <name>, no inception year, no developer block — which Maven Central rejects.
- Post-process the generated file in their own build pipeline.
Proposed fix
Decouple POM identity from the publisher gate:
- Always populate
ProjectName (default to ctx.Name or BasePackage + "-" + ctx.Name, or honor a new PackageInfo.ProjectName / schema DisplayName if set).
- Always populate
ProjectInceptionYear from a sensible default (current year, or a new optional PackageInfo.InceptionYear).
- Honor
pkg.Publisher as the developer name and pkg.Repository/pkg.Homepage for SCM, regardless of whether the publisher string equals "pulumi". Optionally add PackageInfo.DeveloperEmail for the developer email (since email is rarely embedded in schema.Package directly).
- Keep the
isPublishedByPulumi branch only for the com.pulumi groupId default, but skip it whenever PackageInfo.BasePackage is explicitly set (so a publisher that asked for com.pulumi.labs keeps it).
This makes the path symmetric: any schema with enough metadata produces a Maven-Central-publishable POM, and the hardcoded com.pulumi defaults stay only as a convenience fallback for Pulumi's own providers.
Repro
Generate a Java SDK from a schema where Publisher: "Pulumi Labs", Homepage: https://github.com/pulumi-labs/<name>, and LanguageMap.java.basePackage: "com.pulumi.labs". Resulting build.gradle pom { ... } block has name = "", inceptionYear = "", and an empty developers { developer { id="" name="" email="" } }. closeAndReleaseSonatypeStagingRepository against Sonatype Central fails with "Project name is missing".
Workaround
String-surgery the generated build.gradle post-codegen to fill name. Tracking-only until this is fixed upstream.
Summary
pulumi-java-genemits abuild.gradlewhose POM<name>,<inceptionYear>, and<developers>block are populated only when the package metadata satisfiesisPublishedByPulumi(pkg). The same gated branch also rewritesgroupIdtocom.pulumi. As a result, a provider that wants a non-com.pulumigroupId (e.g.com.pulumi.labs, or a third-party publisher) cannot get those POM fields filled in at all, even when its schema carries aDisplayName,Publisher, andLicensethat could populate them.Maven Central rejects publications with an empty
<name>(and complains about missing developer information), so any non-Pulumi groupId requires post-codegen string surgery on the generatedbuild.gradleto ship.Where this lives
pkg/codegen/java/templates_gradle.go—newGradleTemplateContext:isPublishedByPulumikeys offpkg.Publisher == "pulumi"(case-insensitive) orpkg.Homepagehost beingpulumi.com/pulumi.io.pkg/codegen/java/package_info.go(theLanguageMap.javapayload) exposes onlyBasePackage,BuildFiles,Repositories,Dependencies,GradleNexusPublishPluginVersion,GradleTest— none of which can override the POM identity fields above.Net effect: anyone publishing under a non-
com.pulumigroupId is forced to pick one of:Publisher: "Pulumi"/Homepage: https://pulumi.com/...to trigger the branch, then accept thatgroupIdis silently rewritten tocom.pulumi(defeating the original intent).Publisheras something else and live with an empty<name>, no inception year, no developer block — which Maven Central rejects.Proposed fix
Decouple POM identity from the publisher gate:
ProjectName(default toctx.NameorBasePackage + "-" + ctx.Name, or honor a newPackageInfo.ProjectName/ schemaDisplayNameif set).ProjectInceptionYearfrom a sensible default (current year, or a new optionalPackageInfo.InceptionYear).pkg.Publisheras the developer name andpkg.Repository/pkg.Homepagefor SCM, regardless of whether the publisher string equals"pulumi". Optionally addPackageInfo.DeveloperEmailfor the developer email (since email is rarely embedded inschema.Packagedirectly).isPublishedByPulumibranch only for thecom.pulumigroupIddefault, but skip it wheneverPackageInfo.BasePackageis explicitly set (so a publisher that asked forcom.pulumi.labskeeps it).This makes the path symmetric: any schema with enough metadata produces a Maven-Central-publishable POM, and the hardcoded
com.pulumidefaults stay only as a convenience fallback for Pulumi's own providers.Repro
Generate a Java SDK from a schema where
Publisher: "Pulumi Labs",Homepage: https://github.com/pulumi-labs/<name>, andLanguageMap.java.basePackage: "com.pulumi.labs". Resultingbuild.gradlepom { ... }block hasname = "",inceptionYear = "", and an emptydevelopers { developer { id="" name="" email="" } }.closeAndReleaseSonatypeStagingRepositoryagainst Sonatype Central fails with "Project name is missing".Workaround
String-surgery the generated
build.gradlepost-codegen to fillname. Tracking-only until this is fixed upstream.