This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 5d1fb6af9ba6 chore: camel-launcher - the Homebrew validator trusts its
local tap, as recent Homebrew refuses to load a formula from an untrusted tap
(#28699)
5d1fb6af9ba6 is described below
commit 5d1fb6af9ba6f0c45f8ad0904e71d094e08794d6
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Oct 29 20:45:49 2026 +0100
chore: camel-launcher - the Homebrew validator trusts its local tap, as
recent Homebrew refuses to load a formula from an untrusted tap (#28699)
Signed-off-by: Claus Ibsen <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
---
.../src/jreleaser/bin/camel-validate.sh | 10 +++++--
.../launcher/PackageNativeValidationTest.java | 33 ++++++++++++++++++++--
2 files changed, 38 insertions(+), 5 deletions(-)
diff --git a/dsl/camel-jbang/camel-launcher/src/jreleaser/bin/camel-validate.sh
b/dsl/camel-jbang/camel-launcher/src/jreleaser/bin/camel-validate.sh
index 508868cae534..d95b867f7c0a 100755
--- a/dsl/camel-jbang/camel-launcher/src/jreleaser/bin/camel-validate.sh
+++ b/dsl/camel-jbang/camel-launcher/src/jreleaser/bin/camel-validate.sh
@@ -125,12 +125,13 @@ fi
TMPDIR_BASE=$(mktemp -d)
# Name of the throwaway local Homebrew tap created by validate_homebrew()
(empty until it
-# creates one). Kept at script scope so the EXIT trap can always untap it,
even if
+# creates one). Kept at script scope so the EXIT trap can always untrust and
untap it, even if
# validate_homebrew() returns early (SKIP/FAIL) partway through.
BREW_TAP_NAME=""
brew_untap_validator_tap() {
if [ -n "$BREW_TAP_NAME" ] && command -v brew >/dev/null 2>&1; then
+ HOMEBREW_NO_AUTO_UPDATE=1 brew untrust --tap "$BREW_TAP_NAME"
>/dev/null 2>&1 || true
HOMEBREW_NO_AUTO_UPDATE=1 brew untap "$BREW_TAP_NAME" >/dev/null 2>&1
|| true
fi
}
@@ -210,8 +211,10 @@ validate_homebrew() {
# ("Homebrew requires formulae to be in a tap" / "brew audit [path ...] is
disabled");
# empirically confirmed on this machine. A throwaway local tap (removed
via `brew untap`
# in the script's EXIT trap) satisfies that requirement without any
network access or
- # real publication. `brew install` auto-trusts formulae from a tap created
this way (no
- # separate trust command exists or is needed - empirically confirmed).
+ # real publication. Recent Homebrew refuses to load a formula from a tap
that is not trusted
+ # ("Refusing to load formula ... from untrusted tap"), so the tap is
trusted right after it
+ # is created, and untrusted again in the EXIT trap. A Homebrew without
`brew trust`
+ # loads any tap, so a failure of that call is ignored.
local tap_name="camel-cli-validators/formulae"
local tap_dir tap_output
@@ -222,6 +225,7 @@ validate_homebrew() {
return 1
fi
BREW_TAP_NAME="$tap_name"
+ HOMEBREW_NO_AUTO_UPDATE=1 brew trust --tap "$tap_name" >/dev/null 2>&1 ||
true
tap_dir=$(brew --repository "$tap_name")
if ! cp -p "$formula_file" "$tap_dir/Formula/${fmla}.rb"; then
diff --git
a/dsl/camel-jbang/camel-launcher/src/test/java/org/apache/camel/dsl/jbang/launcher/PackageNativeValidationTest.java
b/dsl/camel-jbang/camel-launcher/src/test/java/org/apache/camel/dsl/jbang/launcher/PackageNativeValidationTest.java
index 202cb73d5e8f..104b44c75ef3 100644
---
a/dsl/camel-jbang/camel-launcher/src/test/java/org/apache/camel/dsl/jbang/launcher/PackageNativeValidationTest.java
+++
b/dsl/camel-jbang/camel-launcher/src/test/java/org/apache/camel/dsl/jbang/launcher/PackageNativeValidationTest.java
@@ -333,6 +333,29 @@ class PackageNativeValidationTest {
assertThat(r.out()).contains("FAIL: homebrew audit --strict reported
issues (exit 1)");
}
+ @Test
+ void homebrewValidatorTrustsItsTapForTheAuditAndUntrustsItOnExit(@TempDir
Path tmp) throws Exception {
+ // Recent Homebrew refuses to load a formula from an untrusted tap, so
the validator must
+ // trust its throwaway tap before `brew audit`, and must not leave
that trust behind.
+ Path fakeBinDir = Files.createDirectory(tmp.resolve("fake-bin"));
+ writeFakeBrew(fakeBinDir.resolve("brew"));
+ Path target = Files.createDirectory(tmp.resolve("target"));
+ Path tapDir = Files.createDirectory(tmp.resolve("tap"));
+ stageHomebrewFormula(target, "camel-launcher-9.9.9-bin.tar.gz");
+
+ Result r = sh(null, List.of(
+ "PATH=" + fakeBinDir.toAbsolutePath() + File.pathSeparator +
System.getenv("PATH"),
+ "CAMEL_PACKAGE_TEST_MODE=true",
+ "CAMEL_PACKAGE_TEST_VERSION=" + VERSION,
+ "CAMEL_VALIDATE_TARGET_DIR=" + target.toAbsolutePath(),
+ "FAKE_BREW_TAP_DIR=" + tapDir.toAbsolutePath(),
+ "FAKE_BREW_REQUIRE_TRUST=true"),
+ "/bin/bash " + VALIDATE.toAbsolutePath() + " homebrew");
+
+ assertThat(r.out()).doesNotContain("untrusted tap").contains("PASS:
homebrew style/audit passed");
+ assertThat(tapDir.resolve(".trusted")).doesNotExist();
+ }
+
@Test
void homebrewValidatorSkipsWhenJavaDependencyMissing(@TempDir Path tmp)
throws Exception {
// A `brew install` failure caused by a missing/incompatible Java on
the host is an environment
@@ -424,8 +447,9 @@ class PackageNativeValidationTest {
* heuristics can be pinned without needing a real Homebrew install.
Behavior for the {@code audit} and
* {@code install} subcommands is driven by {@code
FAKE_BREW_AUDIT_RC}/{@code
* FAKE_BREW_AUDIT_OUTPUT} and {@code FAKE_BREW_INSTALL_RC}/{@code
FAKE_BREW_INSTALL_OUTPUT}; the tap directory it
- * reports is {@code FAKE_BREW_TAP_DIR}. Every other subcommand it needs
(tap-new, untap, style, uninstall) just
- * succeeds.
+ * reports is {@code FAKE_BREW_TAP_DIR}. With {@code
FAKE_BREW_REQUIRE_TRUST=true}, {@code audit} refuses the tap
+ * unless {@code trust --tap} was called, as recent Homebrew does. Every
other subcommand it needs (tap-new, untap,
+ * untrust, style, uninstall) just succeeds.
*/
private static Path writeFakeBrew(Path file) throws IOException {
return writeExecutable(file, "#!/bin/sh\n"
@@ -433,8 +457,13 @@ class PackageNativeValidationTest {
+ " tap-new) mkdir -p
\"$FAKE_BREW_TAP_DIR/Formula\"; exit 0 ;;\n"
+ " --repository) echo
\"$FAKE_BREW_TAP_DIR\"; exit 0 ;;\n"
+ " untap) exit 0 ;;\n"
+ + " trust) touch
\"$FAKE_BREW_TAP_DIR/.trusted\"; exit 0 ;;\n"
+ + " untrust) rm -f
\"$FAKE_BREW_TAP_DIR/.trusted\"; exit 0 ;;\n"
+ " style) exit 0 ;;\n"
+ " audit)\n"
+ + " if [
\"$FAKE_BREW_REQUIRE_TRUST\" = true ] && [ ! -f \"$FAKE_BREW_TAP_DIR/.trusted\"
]; then\n"
+ + " echo \"Error: Refusing to
load formula $3 from untrusted tap.\"; exit 1\n"
+ + " fi\n"
+ " [ -n
\"$FAKE_BREW_AUDIT_OUTPUT\" ] && echo \"$FAKE_BREW_AUDIT_OUTPUT\"\n"
+ " exit
\"${FAKE_BREW_AUDIT_RC:-0}\" ;;\n"
+ " install)\n"