Repository navigation
[WP11] Build config & dependency hygiene: unpinned plugins, no Maven update lane, EOL Boot line, jar build-info pollution #183
Copy link
Copy link
Closed as not planned
Closed as not planned
Copy link
Labels
dependenciesPull requests that update a dependency filePull requests that update a dependency filestatus: pending-design-work動工前需要更多的設計或研究動工前需要更多的設計或研究type: enhancementNew feature or requestNew feature or request
Description
此內容由 AI 產生(specification-mapper 全庫審查 2026-07-16)。
Work package WP11 · findings: DEP-03, DEP-01, DEP-04, COR-03 · worst severity: medium
From the 2026-07-16 whole-codebase review (branch jakarta, modules mapper/ + starter/). Each finding below is CONFIRMED by independent adversarial verification. File paths and line numbers reflect the review snapshot and may drift — treat them as starting points, not exact coordinates.
DEP-03 — spring-boot-maven-plugin and native-maven-plugin have no pinned version and currently resolve to Boot 4.1.0 against the 3.5.15 BOM
- Category / severity: dependencies / medium · effort S · confidence high
- Location:
mapper/pom.xml:83 - Evidence: mapper/pom.xml:81-91 and starter/pom.xml:61-64 declare org.springframework.boot:spring-boot-maven-plugin with no , and the parent's pluginManagement (pom.xml:124-190) manages only spotless/license/compiler/surefire; the nativeTest profile (pom.xml:329-359) declares spring-boot-maven-plugin and org.graalvm.buildtools:native-maven-plugin unversioned too.
mvn -pl mapper help:effective-pomwarns "'build.plugins.plugin.version' for org.springframework.boot:spring-boot-maven-plugin is missing" and resolves it to version 4.1.0 — a different major than the imported spring-boot-dependencies 3.5.15 BOM (importing a BOM does not import pluginManagement). - Failure scenario: Every Spring Boot plugin release silently changes this build with no commit: the day 4.x shipped, all builds switched plugin majors overnight. Running
make test-nativeexecutes 4.1.0's process-test-aot against a Boot 3.5 test classpath, which can fail or generate incompatible AOT artifacts; the mapper's build-info goal likewise runs a Boot-4 plugin on a 3.5 project. Builds are non-reproducible across time. - Suggested fix: Add spring-boot-maven-plugin (version ${spring-boot.version}) and native-maven-plugin to the parent's pluginManagement so both modules and the nativeTest profile inherit pinned versions that move with the BOM.
- Verification: [CONFIRMED] Traced and reproduced every structural claim. mapper/pom.xml:81-91 and starter/pom.xml:61-64 declare org.springframework.boot:spring-boot-maven-plugin with no . The parent pom.xml pluginManagement (lines 124-190) manages only spotless/license/compiler/surefire — not spring-boot-maven-plugin. The nativeTest profile (pom.xml:329-359) declares both spring-boot-maven-plugin and org.graalvm.buildtools:native-maven-plugin unversioned. The dependencyManagement import of spring-boot-dependencies 3.5.15 (pom.xml:97-107) is scope=import, which imports only dependencyManagement, not pluginManagement — correct per Maven semantics. Empirical verification via `mvn -o -pl mapper help:e…
DEP-01 — No automated update lane for any Maven dependency or plugin except spring-boot.version; visible staleness confirms the gap
- Category / severity: dependencies / medium · effort S · confidence high
- Location:
.github/dependabot.yml:5 - Evidence: dependabot.yml configures only the github-actions ecosystem; bump-spring.yml updates only the spring-boot.version property; Makefile:49-51 has a
bump-depstarget (versions:update-properties -DexcludeProperties=spring-boot.version) but nothing schedules or CI-invokes it. Resulting staleness in pom.xml: maven-gpg-plugin 3.0.1 (released 2021; 3.2.x is current and is what signs the Central releases), archunit-junit5 1.3.0 (mid-2024; 1.4.x current), maven-jar-plugin 3.3.0, maven-surefire-plugin 3.5.2. - Failure scenario: A CVE or breaking bug in jandex, archunit, or a build plugin never surfaces as a PR; versions drift for years (gpg plugin already ~5 years behind) until a Maven/JDK upgrade suddenly breaks the release pipeline during a time-sensitive release.
- Suggested fix: Add a
package-ecosystem: mavenentry to dependabot.yml (dependabot supports ignoring spring-boot artifacts so the existing bump-spring lane stays authoritative for the BOM), or schedule a workflow that runsmake bump-depsand opens a PR like bump-spring.yml does. - Verification: [CONFIRMED] Traced every structural claim. .github/dependabot.yml (lines 3-8) declares only one update entry: package-ecosystem "github-actions"; there is no maven ecosystem. bump-spring.yml runs
make bump-spring-bootwhich sets only spring-boot.version (Makefile:versions:set-property -Dproperty=spring-boot.version). The Makefile bump-deps target (versions:update-properties -DexcludeProperties=spring-boot.version) exists, but grep across .github/ forbump-deps/update-propertiesreturns nothing — no workflow schedules or invokes it, so it is manual-only. Version staleness confirmed directly in pom.xml: maven-gpg-plugin.version 3.0.1 (line 59), archunit-junit5.version 1.3.0 (line 66…
DEP-04 — Spring Boot 3.5.x baseline is at/past OSS end-of-support and the auto-bump lane is capped at ~3.x, so the lane will go silently stale
- Category / severity: dependencies / medium · effort M · confidence medium
- Location:
pom.xml:63 - Evidence: pom.xml:63 pins spring-boot.version 3.5.15; bump-spring.yml:33 constrains the daily bump to
boot-version: "~3.x". Spring Boot 3.5 (the final 3.x line) left OSS support on 2026-06-30; Boot 4.x has been the current line since Nov 2025. The workflow even includes a keepalive job (bump-spring.yml:94-101) that keeps the daily cron alive indefinitely even after it can never find a newer 3.x version. - Failure scenario: Once 3.5 patches stop, the daily workflow keeps running and green while producing nothing; CVE fixes in Spring Data JPA / Spring Framework land only in Boot 4.x trains, leaving the library's build/test baseline (and its compatibility claims to consumers) on an unpatched line with no alerting that the lane is dead.
- Suggested fix: Decide the Boot 4 story for the jakarta branch (new branch or major bump), and make the bump lane fail loudly or notify when the constrained line stops receiving releases instead of silently no-oping.
- Verification: [CONFIRMED] Traced all cited code. pom.xml:63 pins spring-boot.version=3.5.15. bump-spring.yml:33 sets go-spring-version boot-version="~3.x", which caps the daily auto-bump at the 3.x major and cannot reach Boot 4.x. The pipeline (current-version → latest-version → compare-version → bump-spring gated on comparison-result=='>') silently skips when no newer 3.x is found, and the keepalive job (lines 94-101, liskin/gh-workflow-keepalive) keeps the daily cron alive indefinitely; there is no step that fails or notifies when the constrained line stops receiving releases. Upstream premises are accurate: Spring Boot 4.0 GA'd Nov 2025 as the current line, 3.5 is the final 3.x line with OSS support en…
COR-03 — Library jar ships META-INF/build-info.properties, hijacking consumers' BuildProperties//actuator/info
- Category / severity: correctness / medium · effort S · confidence high
- Location:
mapper/pom.xml:87 - Evidence: mapper/pom.xml binds spring-boot-maven-plugin's build-info goal (lines 82-91), writing META-INF/build-info.properties into target/classes; verified present in the released artifact (specification-mapper-3.1.1.jar contains META-INF/build-info.properties). Nothing in mapper or starter source consumes it (grep for build-info/BuildProperties in src/main is empty).
- Failure scenario: A Spring Boot app that depends on specification-mapper but does not generate its own build-info satisfies ProjectInfoAutoConfiguration's @ConditionalOnResource on classpath:META-INF/build-info.properties; the app's /actuator/info and BuildProperties bean then report the library's group/artifact/version/time as the application's build info; with both files present, classpath ordering silently decides which wins.
- Suggested fix: Remove the build-info execution from mapper/pom.xml (no code reads it), or relocate the file outside META-INF/build-info.properties if build metadata is wanted in the jar.
- Verification: [CONFIRMED] mapper/pom.xml lines 82-91 bind spring-boot-maven-plugin's build-info goal with no custom outputFile, so it writes to the default ${project.build.outputDirectory}/META-INF/build-info.properties. Verified the file exists at mapper/target/classes/META-INF/build-info.properties, meaning it is packaged into the mapper jar. Grep across mapper/starter src shows nothing consumes build-info/BuildProperties (only hit is the pom goal itself). The hijacking is directly reproduced by the repo's own starter surefire reports (e.g. SpecificationResolverBuilderTest.xml lines 246-248): ProjectInfoAutoConfiguration#buildProperties matched because @ConditionalOnResource found classpath:META-INF/bui…
Full report: see the codebase-review-2026-07-16 branch (linked on the parent tracking issue).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
dependenciesPull requests that update a dependency filePull requests that update a dependency filestatus: pending-design-work動工前需要更多的設計或研究動工前需要更多的設計或研究type: enhancementNew feature or requestNew feature or request
Activity
shihyuho commentedon Jul 16, 2026
Triage Notes - needs human
Category: enhancement (build config / dependency & supply-chain hygiene; includes one packaging-correctness item)
Summary: WP11 bundles four confirmed build-config findings — two are clean, agent-safe POM edits (DEP-03, COR-03); two require human policy/infrastructure decisions (DEP-01 dependency update-lane, DEP-04 Boot EOL strategy) — so the package as a whole is held for a human call.
Current behavior
spring-boot-maven-pluginis declared with no<version>in thespecification-mapper(mapper) module, thespecification-mapper-startermodule, and the parentnativeTestprofile; thenative-maven-pluginin that same profile is likewise unversioned. The parent'spluginManagementpins only spotless / license / compiler / surefire. The parent importsspring-boot-dependencieswithscope=import, which contributesdependencyManagementonly — it does not manage plugin versions. As a result the Spring Boot plugin version floats to whatever Maven resolves as latest, independent of the pinnedspring-boot.version(currently 3.5.15), and the build emits a "plugin version is missing" warning and is not reproducible across time.spring-boot-maven-pluginbuild-infogoal with no customoutputFile, so it writesMETA-INF/build-info.propertiesinto the module output and ships it inside the released library jar. No source in either module reads build-info /BuildProperties. A downstream Spring Boot app that does not generate its own build-info will matchProjectInfoAutoConfiguration's@ConditionalOnResource(classpath:META-INF/build-info.properties)off the library's file, so itsBuildPropertiesbean and/actuator/inforeport the library's coordinates as the application's build info.dependabot.ymldeclares only thegithub-actionsecosystem. The scheduledbump-springworkflow updates only thespring-boot.versionproperty. Abump-depsMakefile target (versions:update-properties -DexcludeProperties=spring-boot.version) exists but no workflow invokes it, so every non-Boot dependency and plugin is updated manually only. Confirmed staleness in the parent POM:maven-gpg-plugin3.0.1,archunit-junit51.3.0,maven-jar-plugin3.3.0,maven-surefire-plugin3.5.2.spring-boot.versionis 3.5.15; thebump-springworkflow constrains the auto-bump toboot-version: "~3.x", which cannot reach Boot 4.x. Akeepalivejob keeps the daily cron alive indefinitely. Once the 3.5 line stops publishing, the workflow keeps running green while producing nothing, and there is no step that fails or notifies when the constrained line goes silent.Desired behavior
spring-boot-maven-pluginmoves withspring-boot.version, and the "missing plugin version" warning disappears.META-INF/build-info.properties, so it cannot hijack a consuming application'sBuildProperties//actuator/info.make bump-deps) that opens PRs, without conflicting with the authoritative Boot lane.jakartabranch, and an auto-bump lane that alerts (fails or notifies) rather than silently no-op'ing when its constrained version line stops receiving releases.Key interfaces
pom.xml:build/pluginManagement, thespring-boot.version/ plugin-version properties, and thenativeTestprofile plugin declarations.specification-mapper(mapper) modulepom.xml: thespring-boot-maven-pluginexecution binding thebuild-infogoal.specification-mapper-startermodulepom.xml: itsspring-boot-maven-plugindeclaration (no execution)..github/dependabot.yml;.github/workflows/bump-spring.yml;Makefiletargetsbump-depsandbump-spring-boot.ProjectInfoAutoConfiguration+@ConditionalOnResource(classpath:META-INF/build-info.properties).Acceptance criteria
Agent-safe subset (DEP-03 + COR-03), if scoped out for autonomous work:
spring-boot-maven-pluginis pinned (version trackingspring-boot.version) so the mapper module, the starter module, and thenativeTestprofile all inherit it;native-maven-pluginin thenativeTestprofile is pinned to an explicit version.mvn help:effective-pom(or the build) no longer warns that the Spring Boot plugin version is missing, and the resolved version matches the pinned Boot line rather than a floating latest.META-INF/build-info.propertiesin its build output, and the packaged jar does not contain that resource.mvn testpasses for both modules.Human-gated items (DEP-01 + DEP-04) — criteria depend on the decisions below and are intentionally left open here.
Out of scope
Needs human because
jakartabranch stays on the EOL 3.5 line, cuts a new branch, or takes the breaking Boot 4 major bump is a compatibility-contract judgment for the library's consumers — not something an autonomous agent should decide. The related "alert when the lane goes dead" change is CI/release-infrastructure work needing sign-off.shihyuho commentedon Jul 20, 2026
Superseded by #200 in the execution map #204, which carries the same findings (DEP-01, DEP-03, DEP-04, COR-03). This 2026-07-16 static plan is being retired in favour of that map.