maven-site icon indicating copy to clipboard operation
maven-site copied to clipboard

Clarify Distribution Management field in POM

Open kwin opened this issue 2 months ago • 7 comments

Improvement proposal

According to https://maven.apache.org/pom.html#Repository

distributionManagement specifies where (and how) this project will get to a remote repository when it is deployed

However @cstamas rather thinks this should be used to indicate where consumers can download it (https://maveniverse.eu/docs/njord/migration/#setup-your-project).

I know that currently even maven-deploy-plugin interprets it like the former, but the question is whether the documentation should be adjusted to indicate its intention.

kwin avatar Oct 21 '25 16:10 kwin

Here are some more references: https://maven.apache.org/xsd/maven-4.0.0.xsd

Deployment -> repository

Information needed to deploy the artifacts generated by the project to a remote repository..

Deployment -> repository -> url

The url of the repository, in the form {@code protocol://hostname/path}.

https://maven.apache.org/xsd/maven-4.1.0-rc-4.xsd did not modify the Deployment section at all.

kwin avatar Oct 22 '25 09:10 kwin

Originally in 2000s the "deploy" happened against single server (just look at old ASF parents, apache-parent-4 for example), and things like scp/sftp/etc were used. Later, with advent of MRMs (again, look at ASF parents, apache-parent-5 for example that was first using RAO) were pointing to some service URL, that already lacked information: that alone is not enough information anymore for deployment, as deployment ended up in staging repository, you had to know which one, it needed extra (manual, outside work) from user: close it, release it, wait for sync, etc. But, still "deployment with workflow" happened (that was either finished manually as in ASF, close repo + vote + release repo; or some plugin handled the proprietary APIs - but you still had "something happening outside of m-deploy-p scope").

Today, I am pushing to distinguish between publishing and deploying projects.

Projects that "deploy" (right now ASF ones, but also some in-house development that deploys to in-house MRM) will continue to use m-deploy-p.

But, projects publishing need even more information (aka configuration), and those cannot be expressed with single URL (+ auth), but needs way more.

So, in essence, it boils down what you do: deploy or publish? You can still continue to do both, but sometimes it is unlikely. Typical example are OSS projects outside of some umbrella (outside of ASF, Eclipse, that do have their own MRMs that takes over that "deploy with workflow" part). Just pick any of those "standalone" projects, for example FasterXML (Jackson org).

This project publishes to Central, and has no "forge" (like ASF or Eclipse or any, so no "repo infra"). Their POM contains Sonatype CP service URL, that again, does not tells anything about where the artifacts are ending up.

Hence, the "use of single URL to configure publishing" is not enough anymore.

tl;dr: depends on what you do (what your project does):

  • if you "deploy" (as all Maven projects did so far), but today it implies you have some "repo infra" (usually in-house MRM), then for you all remains same as before, as you are targeting your MRM, and your MRM may perform some extra workflow for you
  • if you "publish" (and not deploy anymore), like "standalone OSS projects do to Central", then as I explained above, the whole publishing is anyway not configurable via single URL, and today used service URLs are really not giving any (valuable/usable) information. Moreover, it requires tools like CycloneDX to "figure out" which service URL means which actual repository.

Note: "publish like setup" (where your POM distributionMgmgt contains "real target URL where artifacts will be available") are still doable even with "deploy" scenario: just define a property for altDeploymentRepository in POM properties, and configure m-deploy-p with that (so override value that m-deploy-p would go directly for, the POM distributionManagement).

cstamas avatar Oct 22 '25 09:10 cstamas

For me it boils down to the question: Is deployment.url for consumers or producers? In most cases those differ. So should deployment.url be rededicated or is it time to introduce a new POM element for consumers?

As you said deployment/publishing most often does require much more than a single hardcoded URL (with credentials) so URLs for producers are in some cases not enough (but should still be part of the POM in a standard element???)

kwin avatar Oct 22 '25 09:10 kwin

IMO, "how I publish" is totally orthogonal to "how I build", as Njord represents that: you can locally stage and publish it as many times you want to as many services you want (assuming you do not automatically drop local store after publishing).

But this also shows interesting connection: "deploying" happens within lifecycle, while "publishing" is outside of it.

Hence, for me personally, the POM element should show info for consumers (again, like in CycloneDX example), and not for producers, as -- again, as I mentioned above -- that single URL is since MRMs simply not enough and never be enough information. Also, how I deploy/publish, is again my own concern, and consumer should not be aware of it.

To draw some parallel: you as a consumer consume my JAR as type=jar, and you do not care HOW I did produce it, was it packaging=jar (the default Maven packaging), or did I use packaging=takari-jar maybe? Or did I use some packaging=my-cool-jar-packaging? This is irrelevant for you, as a consumer.

cstamas avatar Oct 22 '25 10:10 cstamas

Another thing to tinker about: sometimes the URL contains info usable for both! Think about Sonatype Central Portal snapshots for example. Or think about this in-house POM snippet:

  <distributionManagement>
    <repository>
      <id>corp1-releases</id>
      <name>Corporate Repository</name>
      <url>https://repo.company.com/repositories/releases</url>
    </repository>
    <snapshotRepository>
      <id>corp1-snapshots</id>
      <name>Corporate Snapshots</name>
      <url>https://repo.company.com/repositories/snapshots</url>
    </snapshotRepository>
    ...
  </distributionManagement>

With MRMs this is perfectly valid setup (ie this stanza could be in company wide parent POM; combined with deployAtEnd is totally good).

But sometimes, the URL will contain "service URL" (ie like ASF points to Staging API endpoint), that does not tell anything to consumer... but does not cover the "reality" either.

cstamas avatar Oct 22 '25 10:10 cstamas

reading again https://maven.apache.org/pom.html#Repository to guess what makes it hard to read

Whereas the repositories element specifies in the POM the location and manner in which Maven may download remote artifacts for use by the current project, distributionManagement specifies where (and how) this project will get to a remote repository when it is deployed.

I think english phrasing can be enhanced to disambiguate: <project><distributionManagement><repository> (or snapshotRepository>) and <project><repositories><repository>

= what is absolutely not clear at the beginning of the sentence

on @cstamas idea about trying to update the meaning of <project><distributionManagement><repository>, that's another topic: to me, we can seriously clarify wording for https://maven.apache.org/pom.html#Repository first

hboutemy avatar Nov 19 '25 02:11 hboutemy

in parallel to #1466 PR

looking at corresponding reference POM doc: https://maven.apache.org/ref/3.9.11/maven-model/maven.html#class_distributionManagement

there is a bug here? repository linked from distributionManagement element is the one from <project><repositories><repository> (that releases and snapshots RepositoryPolicy)

XML element ambiguity in the model creates issue in the generated documentation: I don't know yet precisely how to fix, but will be near the use of DeploymentRepository class https://github.com/apache/maven/blob/maven-3.9.11/maven-model/src/main/mdo/maven.mdo#L1342 vs the use of Repository https://github.com/apache/maven/blob/maven-3.9.11/maven-model/src/main/mdo/maven.mdo#L520

DeploymentRepository (for distributionManagement) is https://github.com/apache/maven/blob/maven-3.9.11/maven-model/src/main/mdo/maven.mdo#L520 => extends Repository with one attribute

Repository https://github.com/apache/maven/blob/maven-3.9.11/maven-model/src/main/mdo/maven.mdo#L2090

RepositoryBase https://github.com/apache/maven/blob/maven-3.9.11/maven-model/src/main/mdo/maven.mdo#L2037

re-reading again https://maven.apache.org/ref/3.9.11/maven-model/maven.html#class_deployment_repository

releases RepositoryPolicy How to handle downloading of releases from this repository.

talking about "downloading" only is where the ambiguity happens: it's both for download and upload

and finally there is the uniqueVersion field: https://maven.apache.org/ref/3.9.11/maven-model/maven.html#class_deployment_repository which is not present in repositories.repository https://maven.apache.org/ref/3.9.11/maven-model/maven.html#class_repository

I keep all the analysis as i think it is useful to keep in mind but short term is to widen RepositoryPolicy to not only download but also upload: https://github.com/apache/maven/blob/maven-3.9.11/maven-model/src/main/mdo/maven.mdo#L2133

and longer term is perhaps as @kwin suggested add another field to DeploymentRepository: in addition to uniqueVersion, we could perhaps add downloadUrl (even if purely informational: not really used by Maven, but very useful for end users trying to guess from an upload url what will be the associated download url)

hboutemy avatar Nov 19 '25 03:11 hboutemy