CAMEL-23703: camel-launcher - package distribution (JReleaser packagers + website installers)#24682
CAMEL-23703: camel-launcher - package distribution (JReleaser packagers + website installers)#24682ammachado wants to merge 16 commits into
Conversation
Adds install.ps1 mirroring install.sh's security model (strict manifest parsing, pre-extraction archive validation, staged launcher verification, per-user activation) for Windows, plus its Windows-only JUnit contract suite. Registers a license-maven-plugin comment-style mapping for *.ps1 (SCRIPT_STYLE), which was missing project-wide.
Adds an upgrade-guide entry for install.sh / install.ps1 covering the stable URLs, exact-version syntax, per-user/no-elevation behavior, SHA-256 verification, the Java 17+ staged-launcher check, and the POSIX/Windows install roots.
…on-inherited) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tribution Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… + LTS validation Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Also fixes a MODULE_DIR path bug in both wrappers: it resolved two directory levels up from src/jreleaser/bin instead of three, so it pointed at .../camel-launcher/src instead of the module root. This was latent since Task 4 because --print-plan never touched MODULE_DIR. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ied against 1.25.0
Authors jreleaser.yml with one JAVA_BINARY distribution and the brew, sdkman,
winget, scoop, and chocolatey packagers, per the knowledge-cutoff rule this was
validated against live JReleaser 1.25.0 docs and, more importantly, against
actual jreleaser:config/jreleaser:prepare dry-runs using the pinned plugin JAR
rather than assumed from documentation alone. That empirical pass caught several
real defects:
- pom.xml's <configFile> was wrongly nested inside a <jreleaser> wrapper element
(a bug from the earlier plugin-pinning commit); it must be a direct
<configuration> child.
- `type: BINARY` does not carry Java-distribution semantics; JAVA_BINARY does,
confirmed by the generated Homebrew formula correctly auto-adding
`depends_on "openjdk@17"`.
- `project.java` is deprecated in 1.25.0 in favor of `project.languages.java`.
- `project.vendor` and `distributions.camel-cli.tags` are required in practice
despite docs implying defaults; validation fails without them.
- Every packager defaults to a GitHub-release download URL. Camel publishes to
Maven Central, not GitHub release assets, so each packager now sets an explicit
`downloadUrl` pointing at the same repo1.maven.org coordinates Phase 3A's
installers and docs/getting-started.adoc already use.
- `{{ Env.X }}` templates resolve real OS environment variables
(System#getenv), not Maven -D system properties, so the wrappers now export
CAMEL_PKG_BREW_FORMULA instead of passing -Dcamel.pkg.brewFormula. Enum fields
(active, sdkman.command) are parsed before templates resolve and cannot use
`{{ Env.X }}` at all; a nested system-property override was tried for
sdkman.command and confirmed (via trace.log) not to take effect. SDKMAN has no
local `prepare` output - `command` only affects the live publish-time API call -
so per-channel MAJOR/MINOR selection is deferred to Phase 5.
- Per-channel packager selection (e.g. `lts` excluding `scoop`) uses the
jreleaser:prepare/package Mojo's own -Djreleaser.distributions/-Djreleaser.packagers
include filters (confirmed via `mvn help:describe` on the pinned plugin), not a
templated `active` field.
- A placeholder JRELEASER_GITHUB_TOKEN is exported only when unset, since
-Djreleaser.dry.run=true never performs a network call but config validation
still requires a non-blank token.
Also fixes a recurring camel-package.bat license-header duplication: the
license-maven-plugin's default .bat style doesn't recognize a header following
the required leading `@echo off` line and re-prepends a duplicate on every
`license:format` run. Excluded the file from that goal at the module level
(same pattern already used by components/camel-diagram/pom.xml) rather than
patching the symptom repeatedly.
Known gap: `--channel stable --lts-line X.Y` is specified to publish both an
unversioned and a versioned Homebrew formula from one release; this file
declares only one `brew` packager per distribution, so today it only produces
the formula selected by CAMEL_PKG_BREW_FORMULA. Deferred to a follow-up task.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…aveats/notes) Authored a custom formula.rb.tpl (ground truth extracted via the pinned plugin's jreleaser:template-generate goal, not guessed) that: - depends_on the unversioned Homebrew "openjdk" (Camel only needs 17+, so the always-current formula never goes stale, unlike depends_on "openjdk@17"). - Installs a CAMEL_FALLBACK_JAVA-exporting wrapper via write_env_script instead of a bare symlink, so `camel` works even with no other Java on PATH. - Emits the required caveat text, plus a keg_only :versioned_formula caveat for versioned formulae, gated by a new brewVersionedFormula extraProperty (empty string is Mustache-falsy) computed by both wrapper scripts. Empirical jreleaser:prepare dry-runs against the pinned plugin surfaced two real bugs beyond the plan's stated scope, both fixed here: - distributions.camel-cli.executable had no unixExtension, so distributionExecutableUnix defaulted to "camel" instead of the actual on-disk "camel.sh" (see src/main/assembly/bin.xml), producing a broken symlink in every packager that installs from libexec (Homebrew, and by the same mechanism Scoop/Chocolatey in Task 8). - The brew packager's templateDirectory default resolves against the JReleaser Maven plugin's basedir (the reactor root, confirmed in Task 6), not this module's directory, so formula.rb.tpl was silently ignored until templateDirectory was set explicitly to the module-relative path. Testing a versioned formula name (camel@4.20) also surfaced that JReleaser does not apply Homebrew's "AT" class/filename convention to formulaName, producing an invalid Ruby class and wrong output filename; documented as an extension of the existing "KNOWN GAP" note rather than fixed here, since a correct fix needs formulaName pre-conversion, out of Task 7's scope. SDKMAN has no local template extension point in 1.25.0 (confirmed: template- generate writes no files for packagerName=sdkman); it only exposes releaseNotesUrl, with actual candidate publication via its Vendor API at Phase 5 publish time. The required note text is stored as a plain repo asset for Phase 5 to consume, documented as not yet wired into JReleaser. Also removes the incidental cask.rb.tpl/README.md.tpl scaffold files (this distribution has no cask, and JReleaser falls back to its own embedded default README.md.tpl per-file when one isn't provided). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…m review Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…enerator Replace the lone java.util.Arrays.equals FQCN in writeLatestManifest with the already-imported Arrays.equals, matching writeVersionManifest and the project's no-FQCN convention (the build's OpenRewrite step would otherwise rewrite it and CI would fail on the uncommitted diff). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
🌟 Thank you for your contribution to the Apache Camel project! 🌟 🐫 Apache Camel Committers, please review the following items:
|
|
🧪 CI tested the following changed modules:
🔬 Scalpel shadow comparison — Scalpel: 646 tested, 27 compile-only — current: 1 all testedMaveniverse Scalpel detected 673 affected modules (current approach: 1).
|
Description
This is the package-distribution layer of the unified Camel CLI distribution work (CAMEL-23703),
built on top of the shared Java 17+ runtime discovery that merged in #24664. It gives the
camel-launchermodule a way to publish and install the CLI without any Java-discovery logic ofits own; that already lives in
camel.sh/camel.batfrom the merged discovery PR.What it adds:
jreleaser.yml) for five packagers: Homebrew and SDKMAN (POSIX),and WinGet, Scoop, and Chocolatey (Windows), pinned to JReleaser 1.25.0 (unbound, non-inherited
plugin execution) plus a Homebrew formula template and SDKMAN release notes.
src/install/install.shandsrc/install/install.ps1. Bothresolve the latest (or a pinned
X.Y.Z) release, download the archive from Maven Central, verifyit against a SHA-256 pulled from a manifest served over HTTPS from
camel.apache.org, validatethe archive before extraction (rejecting absolute paths,
../traversal, symlink/hardlink/reparseentries, multiple top-level roots, or a missing launcher), stage and run the launcher once as a
smoke test, then activate atomically. The manifest is parsed line-by-line and never sourced or
eval'd.
WebsiteManifestGenerator.java:per-version manifests cannot change once written, and
latest.propertiescan only move forward toa higher semantic version, never silently re-point or change a checksum. Writes are atomic.
supported-lts.yml) and prepare wrappers(
camel-package.sh/camel-package.bat) that drive a channel plan (stable/lts) with LTSvalidation.
loopback HTTPS fixture), and the channel/prepare plans.
This is the third of four PRs from splitting the original
feature/CAMEL-23703-phase1branch:A (#24664, merged) shared runtime discovery, B (#24665) the native
camel.exe, this PR C thepackage distribution, and D (package-native validation) which will follow stacked on this branch.
Target
mainbranch)Tracking
Apache Camel coding standards and style
I checked that each commit in the pull request has a meaningful subject line and body.
I have run
mvn clean install -DskipTestslocally from root folder and I have committed all auto-generated changes.mvn formatter:format impsort:sortran clean on push (no changes). A fullmvn clean installof
camel-launcherhas not yet been run locally; CI is the source of truth here.AI-assisted contributions
Co-authored-bytrailers) and the PR description identifies the AI tool used.Claude Code (Opus 4.8) on behalf of ammachado