Part of #73.
#73 excluded Spring Data deliberately: its collector reaches for spring-data-commons documentation
that is published nowhere, and its descriptor is a template threaded through a parent-POM chain. Both
facts still hold. What has changed is the evidence around them — #74 shipped 52 Spring Framework
versions through the overlay era, so the converter is no longer assumed to be project-neutral, it is
measured — and a closer look at the two blockers shows both resolve to files that are committed in a
tag rather than to artifacts nobody publishes.
What the collector actually runs
spring-data-jpa/src/main/antora/antora.yml at 3.5.6 — a stub, like Framework's and Security's:
name: data-jpa
version: true
nav: [modules/ROOT/nav.adoc]
ext:
collector:
- run: { command: ./mvnw test-compile -Pantora-process-resources, local: true }
scan: { dir: spring-data-jpa-distribution/target/classes }
- run: { command: ./mvnw package -Pdistribute, local: true }
scan: { dir: target/antora }
Two stages, and they need different things:
antora-process-resources filters src/main/antora/resources/antora-resources/antora.yml,
a template of ${...} Maven properties.
-Pdistribute unpacks spring-data-commons' documentation module into target/antora, so
the built component is the project's own pages plus the shared Commons pages.
Both inputs are in committed files, at a version the POM pins
The Commons template at spring-data-commons 3.5.6, in full, is the shape every store repeats:
version: ${antora-component.version}
prerelease: ${antora-component.prerelease}
asciidoc:
attributes:
version: '${project.version}'
copyright-year: '${current.year}'
springversionshort: '${spring.short}'
springversion: '${spring}'
springdocsurl: '${documentation.baseurl}/spring-framework/reference/{springversionshort}'
springjavadocurl: '${documentation.spring-javadoc-url}'
springhateoasversion: '${spring-hateoas}'
releasetrainversion: '${releasetrain}'
…
Every placeholder resolves from two committed POMs at the same version (probed 2026-09-16):
| Placeholder |
Source |
${project.version} |
the tag |
${spring} = 6.2.13, ${releasetrain} = 2025.0.6, ${documentation.baseurl}, ${documentation.spring-javadoc-url} |
spring-data-build parent/pom.xml at the same version |
${springdata.commons} = 3.5.6 |
the project's own pom.xml — this is the Commons version -Pdistribute needs |
${spring.short} |
an antrun loadresource regex over ${spring} (→ 6.2) |
${antora-component.version} / .prerelease |
antora-component-version-maven-plugin, derived from the project version |
${current.year} |
a build-time yyyy timestamp — the one non-deterministic input; pin it from the tag's commit date, not the clock, or it breaks the reproducibility invariant releases rest on |
So the unpublished-artifact blocker dissolves: springdata.commons names the exact Commons version,
and a second sparse checkout of spring-projects/spring-data-commons at that tag supplies what
dependency:unpack would have. Nothing is downloaded from a repository that does not carry it.
Why it is worth the larger era
One assembly — "filter a committed template through a two-POM property chain, then merge a second
component checked out at the version the POM pins" — covers data-jpa, data-mongodb, data-redis,
data-elasticsearch, data-cassandra, data-couchbase, data-neo4j, data-ldap, data-r2dbc
and data-rest. Every one of them shares the descriptor stub, the resources template and the
spring-data-build parent. It is the highest page count per era in the ecosystem, and the release
train makes the versions line up rather than multiply.
Open questions to settle first
Work
Done when
data-jpa resolves through resolveUpstream, converts under --strict, and one version is
published and recorded in catalog.json.
Part of #73.
#73 excluded Spring Data deliberately: its collector reaches for
spring-data-commonsdocumentationthat is published nowhere, and its descriptor is a template threaded through a parent-POM chain. Both
facts still hold. What has changed is the evidence around them — #74 shipped 52 Spring Framework
versions through the overlay era, so the converter is no longer assumed to be project-neutral, it is
measured — and a closer look at the two blockers shows both resolve to files that are committed in a
tag rather than to artifacts nobody publishes.
What the collector actually runs
spring-data-jpa/src/main/antora/antora.ymlat 3.5.6 — a stub, like Framework's and Security's:Two stages, and they need different things:
antora-process-resourcesfilterssrc/main/antora/resources/antora-resources/antora.yml,a template of
${...}Maven properties.-Pdistributeunpacksspring-data-commons' documentation module intotarget/antora, sothe built component is the project's own pages plus the shared Commons pages.
Both inputs are in committed files, at a version the POM pins
The Commons template at
spring-data-commons3.5.6, in full, is the shape every store repeats:Every placeholder resolves from two committed POMs at the same version (probed 2026-09-16):
${project.version}${spring}=6.2.13,${releasetrain}=2025.0.6,${documentation.baseurl},${documentation.spring-javadoc-url}spring-data-buildparent/pom.xmlat the same version${springdata.commons}=3.5.6pom.xml— this is the Commons version-Pdistributeneeds${spring.short}loadresourceregex over${spring}(→6.2)${antora-component.version}/.prereleaseantora-component-version-maven-plugin, derived from the project version${current.year}yyyytimestamp — the one non-deterministic input; pin it from the tag's commit date, not the clock, or it breaks the reproducibility invariant releases rest onSo the unpublished-artifact blocker dissolves:
springdata.commonsnames the exact Commons version,and a second sparse checkout of
spring-projects/spring-data-commonsat that tag supplies whatdependency:unpackwould have. Nothing is downloaded from a repository that does not carry it.Why it is worth the larger era
One assembly — "filter a committed template through a two-POM property chain, then merge a second
component checked out at the version the POM pins" — covers
data-jpa,data-mongodb,data-redis,data-elasticsearch,data-cassandra,data-couchbase,data-neo4j,data-ldap,data-r2dbcand
data-rest. Every one of them shares the descriptor stub, the resources template and thespring-data-buildparent. It is the highest page count per era in the ecosystem, and the releasetrain makes the versions line up rather than multiply.
Open questions to settle first
Decides whether Commons is fetched once per train version or once per project.
${...}the corpus actually references. Measure it the way Add Spring Framework: its generated component is a single attribute #74 and Add Spring AI: its generated component descriptor carries only version and prerelease #75 were measured:convert one store's checkout with the template unfilled and count unresolved attributes.
(
spring-data-commons4.1.1 exists) may have moved the paths, exactly as Boot did twice.current.yeardeterminism, as above.Work
descriptor: 'template'assembly, orsynthesizedwidened)data-jpa— toPROJECTS, with tests intests/unit/upstream-sources.test.ts--strictNOTICEalready carries Spring Data attribution; update the README table and therelease-pipelineskillDone when
data-jparesolves throughresolveUpstream, converts under--strict, and one version ispublished and recorded in
catalog.json.