Skip to content

java-gen: POM identity fields are coupled to a hardcoded "publisher is Pulumi" gate, so non-Pulumi providers cannot get a valid POM #2201

Description

@pose

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.gonewGradleTemplateContext:

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:

  1. Always populate ProjectName (default to ctx.Name or BasePackage + "-" + ctx.Name, or honor a new PackageInfo.ProjectName / schema DisplayName if set).
  2. Always populate ProjectInceptionYear from a sensible default (current year, or a new optional PackageInfo.InceptionYear).
  3. 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).
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/codegenCode generationkind/bugSome behavior is incorrect or out of spec

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions