eraFor returns undefined for 4.0.0–4.0.7, so detect-upstream-versions.ts never offers them and
fetch-upstream.ts refuses them. They sit between the two Boot eras: the 4.x component path, but no
published content archive.
What is actually missing (probed 2026-09-16)
| Coordinate |
HEAD |
spring-boot-docs/4.0.0/…-root-aggregate-content.zip |
404 |
spring-boot-docs/4.0.7/…-root-aggregate-content.zip |
404 |
spring-boot-docs/4.0.8/…-root-aggregate-content.zip |
200 |
spring-boot-docs/4.1.0/…-root-aggregate-content.zip |
404 (already handled — a publication fact caught by the availability gate, not an era gap) |
spring-boot-docs/4.1.1/…-root-aggregate-content.zip |
200 |
The authored half is present and in the 4.x location:
v4.0.0 documentation/spring-boot-docs/src/docs/antora/ -> antora.yml, modules/, nav.adoc
So this is exactly the situation that produced the synthesized era for 3.3–3.x (ADR-0004): the prose
is in the tag, the generated half is not published, and it has to be rebuilt.
Why a third era rather than widening the second
eraFor picks by range, and each era pins a component path and an assembly. 4.0.0–4.0.7 share the
4.x path with the archive era but must not take its assembly — merging an archive that does not
exist is a 404, and taking the checkout alone converts with unresolved attributes (measured for
3.5.16 in ADR-0004: 350 unresolved attributes, 837 unresolved configprop:, 326 empty
include-code:: groups).
Declared oldest first, the table becomes: 3.3.0–<4.0.0 synthesized, 4.0.0–<4.0.8 synthesized (4.x
paths), >=4.0.8 archive.
The synthesis inputs exist at v4.0.0, at moved paths
SynthesisSources field |
3.3–3.x |
v4.0.0 |
examplesPath |
spring-boot-project/spring-boot-docs/src/main |
documentation/spring-boot-docs/src/main |
staticAttributesPath |
buildSrc/…/build/antora/antora-asciidoc-attributes.properties |
unchanged — confirmed present |
bomBuildScriptPath |
spring-boot-project/spring-boot-dependencies/build.gradle |
platform/spring-boot-dependencies/build.gradle |
gradlePropertiesPath |
gradle.properties |
unchanged |
metadataArtifacts |
8 spring-boot-* jars |
unverified — see below |
spring-boot, spring-boot-autoconfigure and spring-boot-actuator all publish a 4.0.0 jar
(HEAD 200), so the mechanism carries over.
Open questions to settle first
- Which 4.0.x jars still ship
META-INF/spring-configuration-metadata.json. Boot 4 restructured
its modules, so BOOT_3_METADATA_ARTIFACTS is not transferable. Measure it against a real 4.0.x
jar set the way that list was measured against 3.5.16 — spring-boot-test was excluded there
because it publishes a jar and no metadata file.
- Whether the attributes properties file kept its shape across the 4.x restructure, since
antora-attributes.ts parses it.
- Whether the BOM script is still readable by
bom-libraries.ts at platform/.
Work
Done when
bun run scripts/detect-upstream-versions.ts --project boot reports 4.0.0–4.0.7 as buildable, and
the catalog carries them.
eraForreturnsundefinedfor 4.0.0–4.0.7, sodetect-upstream-versions.tsnever offers them andfetch-upstream.tsrefuses them. They sit between the two Boot eras: the 4.x component path, but nopublished content archive.
What is actually missing (probed 2026-09-16)
spring-boot-docs/4.0.0/…-root-aggregate-content.zipspring-boot-docs/4.0.7/…-root-aggregate-content.zipspring-boot-docs/4.0.8/…-root-aggregate-content.zipspring-boot-docs/4.1.0/…-root-aggregate-content.zipspring-boot-docs/4.1.1/…-root-aggregate-content.zipThe authored half is present and in the 4.x location:
So this is exactly the situation that produced the synthesized era for 3.3–3.x (ADR-0004): the prose
is in the tag, the generated half is not published, and it has to be rebuilt.
Why a third era rather than widening the second
eraForpicks by range, and each era pins a component path and an assembly. 4.0.0–4.0.7 share the4.x path with the archive era but must not take its assembly — merging an archive that does not
exist is a 404, and taking the checkout alone converts with unresolved attributes (measured for
3.5.16 in ADR-0004: 350 unresolved attributes, 837 unresolved
configprop:, 326 emptyinclude-code::groups).Declared oldest first, the table becomes: 3.3.0–<4.0.0 synthesized, 4.0.0–<4.0.8 synthesized (4.x
paths), >=4.0.8 archive.
The synthesis inputs exist at v4.0.0, at moved paths
SynthesisSourcesfieldexamplesPathspring-boot-project/spring-boot-docs/src/maindocumentation/spring-boot-docs/src/mainstaticAttributesPathbuildSrc/…/build/antora/antora-asciidoc-attributes.propertiesbomBuildScriptPathspring-boot-project/spring-boot-dependencies/build.gradleplatform/spring-boot-dependencies/build.gradlegradlePropertiesPathgradle.propertiesmetadataArtifactsspring-boot-*jarsspring-boot,spring-boot-autoconfigureandspring-boot-actuatorall publish a 4.0.0 jar(HEAD 200), so the mechanism carries over.
Open questions to settle first
META-INF/spring-configuration-metadata.json. Boot 4 restructuredits modules, so
BOOT_3_METADATA_ARTIFACTSis not transferable. Measure it against a real 4.0.xjar set the way that list was measured against 3.5.16 —
spring-boot-testwas excluded therebecause it publishes a jar and no metadata file.
antora-attributes.tsparses it.bom-libraries.tsatplatform/.Work
PROJECTS.boot.eraswith the 4.x synthesis pathstests/unit/upstream-sources.test.ts(era selection at 4.0.0, 4.0.7, 4.0.8)--strict, and compare the unresolved-attributecount against the 4.0.8 archive build
catalog.jsonREADME.mdand therelease-pipelineskillDone when
bun run scripts/detect-upstream-versions.ts --project bootreports 4.0.0–4.0.7 as buildable, andthe catalog carries them.