feat: Nexus-bootstrap CLI wrapper + LTA 2026.1 manifest refresh#10
Merged
Conversation
The bundled runtime manifest was left at the pre-LTA pins after commit 976a8c4 migrated pom.xml to 2026.1: every artifact except sonar-go-plugin was on the old version, and the manifest's `version` field (the cache key for ~/.sonar/<version>/) still pointed at the old engine. `sonar setup` would land in the wrong directory and verify against stale SHAs. - manifest.json: bump engine 10.24.0.81415 -> 11.3.0.85510 plus all 10 analyzer pins to match pom.xml's LTA 2026.1 properties. All 11 SHA-256s recomputed from the Maven artifacts. - Manifest.java javadoc: drop the stale reference to daemon/plugins/CHECKSUMS.txt (the file does not exist in the single-module layout) and the "all-zeros placeholder" note (the engine SHA has been real for some time). - SetupCommandTest.stubRunner: fix a latent test seam. Production code keys the layout off Manifest.bundled().version(), but the stub paired that bundled-based layout with the test's injected manifest. Both happened to be "10.24.0.81415" so it worked by coincidence; the bump exposed the inconsistency. Build the layout from the test's manifest via RuntimeLayout.forVersion so the test is isolated from future bundled-manifest bumps. - ManifestTest: bump the two hardcoded version constants the bundled manifest is asserted against.
The dist zip already ships bin/sonar (POSIX) and bin/sonar.bat (Windows)
that auto-discover a Java 21+ runtime, but they refuse with exit 2 if
none is found and they assume the user has the bundle on disk already.
For corporate / air-gapped deployments where users do not run the Maven
build themselves and do not have a system JDK 21, neither assumption
holds.
This adds an outer bootstrap wrapper that:
1. Fetches the dist zip from a corporate Nexus raw repo into
~/.sonar-predictor/dist/<version>/sonar-predictor/ (idempotent;
skipped if the bundle marker bin/sonar already exists).
2. Reuses the same Java 21+ discovery as bin/sonar (JAVA_HOME, PATH,
common install paths) so users with a system JDK pay zero JDK
download cost.
3. Otherwise fetches a Temurin JDK 21 archive from the same Nexus into
~/.sonar-predictor/jdk/21/<os>-<arch>/ and exports JAVA_HOME so the
bundle's own launcher picks it up unchanged.
4. exec's the bundle's bin/sonar (POSIX) or bin/sonar.bat (Windows) so
signals propagate cleanly. The daemon launches as a child of bin/sonar
via DaemonLauncher, so a single entrypoint covers both CLI and
daemon use cases.
Env contract:
SONAR_NEXUS_BASE (required) Nexus raw repo base URL, no trailing slash
SONAR_PREDICTOR_VERSION (default 0.3.0-SNAPSHOT)
SONAR_PREDICTOR_HOME (default $HOME/.sonar-predictor)
SONAR_PREDICTOR_FORCE=1 re-download even if cached
Nexus path conventions (one sed if your layout differs):
{base}/sonar-predictor/{version}/sonar-predictor-dist-{version}.zip
{base}/temurin/21/{os}-{arch}.{tar.gz|zip}
POSIX sh: tested with sh and dash syntax checks. PowerShell: tested via
the language parser. Smoke tests:
- missing SONAR_NEXUS_BASE -> exit 2 with a clear "required" message
- unreachable Nexus -> exit 2 with the failing URL surfaced
- pre-cached bundle -> hands off to bin/sonar (picocli help renders)
Known gap: no checksum verification of the dist zip or JDK archive. The
corporate Nexus is the trust boundary; a SHA pin file can be added later
for defence-in-depth.
|
This was referenced May 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Two related changes that close gaps left after the SonarQube LTA 2026.1
migration in #8:
sonar setupactuallyprovisions LTA 2026.1 artifacts. The manifest was stale on engine +
9 of 10 plugins, and its
versionfield (the cache key for~/.sonar/<version>/) still pointed at the old engine —sonar setupwould land in the wrong directory and verify against the wrong SHAs.
scripts/sonar-cli.sh+scripts/sonar-cli.ps1) that pulls the dist zip from a corporateNexus and provisions a Temurin JDK 21 if the system has none, then
hands off to the existing
bin/sonar. Closes the chicken-and-eggproblem for users who don't run the Maven build themselves and don't
have a system JDK 21.
What changed
Bundled manifest refresh (
chore(setup)commit):src/main/resources/manifest.json: cache key10.24.0.81415→11.3.0.85510; all 11 GAVs bumped to LTA 2026.1; all 11 SHA-256srecomputed from the real jars.
Manifest.java: javadoc trimmed (no more reference to nonexistentdaemon/plugins/CHECKSUMS.txtor "all-zeros placeholder").ManifestTest.java: two hardcoded version constants bumped.SetupCommandTest.java: latent test seam fixed —stubRunnerpairedthe bundled-version-based layout with the test's own manifest. Both
happened to be
10.24.0.81415so it worked by coincidence; this bumpexposed it. Rewired to build the layout from the test's manifest via
RuntimeLayout.forVersion, so the test is isolated from futurebundled-manifest bumps.
Wrapper scripts (
feat(scripts)commit):scripts/sonar-cli.sh(POSIX sh, executable) — requiredSONAR_NEXUS_BASE; optionalSONAR_PREDICTOR_VERSION(default0.3.0-SNAPSHOT),SONAR_PREDICTOR_HOME(default~/.sonar-predictor),SONAR_PREDICTOR_FORCE=1. Idempotentbundle/JDK provisioning,
exec'sbin/sonarso signals propagate.scripts/sonar-cli.ps1— Windows mirror, same env contract.Nexus path conventions (one
sedif your layout differs):Test plan
mvn -B test→ 358/358 pass, BUILD SUCCESSsh -n scripts/sonar-cli.sh✓dash -n scripts/sonar-cli.sh✓ (POSIX-clean)scripts/sonar-cli.ps1✓SONAR_NEXUS_BASE→ exit 2 with clear "required" messagehttp://127.0.0.1:1) → exit 2 with failing URLbin/sonar, picocli help renders, exit 0used a placeholder; rename
{base}/sonar-predictor/...and{base}/temurin/21/...if your layout differs).ps1parser-validated only)Known gaps / follow-ups
Trust boundary is your corporate Nexus. Add a pin file later if you
want defence-in-depth.
bin/sonarandbin/sonar.batstill refuse with exit 2when no Java 21+ is found. With the wrapper in front of them, that
error path is unreachable for normal users — but the inner launchers
stay unchanged so direct
bin/sonarinvocation still works.