Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/reusable-homebrew-bottle-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ jobs:
systemd_run_bin="/usr/bin/systemd-run"
systemctl_bin="/usr/bin/systemctl"
getent_bin="/usr/bin/getent"
findmnt_bin="/usr/bin/findmnt"
pgrep_bin="/usr/bin/pgrep"
pkill_bin="/usr/bin/pkill"
useradd_bin="/usr/sbin/useradd"
Expand All @@ -443,7 +444,7 @@ jobs:
[ $((8#$sudo_mode & 0022)) -ne 0 ]; then
echo "::error::runner sudo boundary is unavailable"; exit 2
fi
for protected_bin in "$systemd_run_bin" "$systemctl_bin" "$getent_bin" "$pgrep_bin" \
for protected_bin in "$systemd_run_bin" "$systemctl_bin" "$getent_bin" "$findmnt_bin" "$pgrep_bin" \
"$useradd_bin" "$userdel_bin"; do
protected_mode="$(stat -c '%a' "$protected_bin" 2>/dev/null || true)"
if [ ! -f "$protected_bin" ] || [ -L "$protected_bin" ] || \
Expand Down Expand Up @@ -1662,6 +1663,7 @@ jobs:
systemd_run_bin="/usr/bin/systemd-run"
systemctl_bin="/usr/bin/systemctl"
getent_bin="/usr/bin/getent"
findmnt_bin="/usr/bin/findmnt"
pgrep_bin="/usr/bin/pgrep"
pkill_bin="/usr/bin/pkill"
useradd_bin="/usr/sbin/useradd"
Expand All @@ -1672,7 +1674,7 @@ jobs:
[ $((8#$sudo_mode & 0022)) -ne 0 ]; then
echo "::error::runner sudo boundary is unavailable"; exit 2
fi
for protected_bin in "$systemd_run_bin" "$systemctl_bin" "$getent_bin" "$pgrep_bin" \
for protected_bin in "$systemd_run_bin" "$systemctl_bin" "$getent_bin" "$findmnt_bin" "$pgrep_bin" \
"$useradd_bin"; do
protected_mode="$(stat -c '%a' "$protected_bin" 2>/dev/null || true)"
if [ ! -f "$protected_bin" ] || [ -L "$protected_bin" ] || \
Expand Down
15 changes: 9 additions & 6 deletions docs/homebrew-publishing.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,12 +299,15 @@ only per `(tap, formula)`, so unrelated Formulae retain parallel throughput:
`/home/linuxbrew/.linuxbrew` prefix. This preserves the selected prefix and
Cellar so ordinary host build-dependency bottles remain usable. Within that
read-only build, all Formula-evaluating Homebrew commands run as a distinct
unprivileged user. Kandelo, tap, and patched Homebrew source are recursively
non-writable and non-replaceable by that identity; only a root-provisioned
shared temporary root, Homebrew cache/temp, prefix, and build home are
writable. Dependency lists and install logs used by the workflow identity
live in a separate mode-0700 control directory under the protected output
root; Formula processes cannot preplant or replace those paths. The wrapper
unprivileged user. The original Kandelo and tap checkouts remain hidden from
that identity. Each transient service receives root-created, read-only bind
aliases for those exact trees, and the Kandelo SDK environment points only
at the alias. The patched Homebrew source is recursively non-writable and
non-replaceable; only a root-provisioned shared temporary root, Homebrew
cache/temp, prefix, and build home are writable. Dependency lists and install
logs used by the workflow identity live in a separate mode-0700 control
directory under the protected output root; Formula processes cannot preplant
or replace those paths. The wrapper
uses an explicit host `sudo` boundary, a fixed
environment allowlist, and a transient systemd service with control-group
kill semantics and `NoNewPrivileges=yes` for every Brew invocation. A final
Expand Down
14 changes: 9 additions & 5 deletions scripts/check-homebrew-publish-workflow-trust.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
DOWNLOAD_ACTION = "actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c"
BREW_COMMIT = "34c40c18ffa2029b611b61c73273e32c003d0842"
PUBLISHER_PLAN_DIGEST = "75468bd935146ca1c78e1a757a314bb6355bce63f01707c3345936d3f9ccaf07"
PUBLISHER_BUILD_DIGEST = "682e73ef771a9beebb0bbfaea2770d6f1cd7062882b4bb3145958d204e1436b5"
PUBLISHER_BUILD_DIGEST = "aa18e5d12e4e38bd1e631899444fb8f14d56a1eb05f41b00ceb1288774f78dab"
PUBLISHER_UPLOAD_DIGEST = "329ff7dfafc8f3c262ae8c817187d875db451da05d7d98a12eafda45cdbf2213"
PUBLISHER_INDEX_DIGEST = "2c5988c9b840dcc1e845f40b58e47ed8263a9babccdae08140bea145a4199de3"
PUBLISHER_VERIFY_DIGEST = "73cc22e389c4fb449f32976860178dc40bce686739c6662cb769ca2ad93b7003"
PUBLISHER_VERIFY_DIGEST = "b9da6e384260ac4e6a036a9734ccce78e43cb144866ec91895c03922aa0e78bb"
PUBLISHER_FINALIZE_DIGEST = "2e7a24cdcaa63e631cee1a967bff1c41bb0f8f8e57e2039929efda5d069cf9f9"
MAINTENANCE_VALIDATE_DIGEST = "9ab856fe40640172500d82b5179a096aa028763bf696aeac865d732298617a22"
MAINTENANCE_ROLLBACK_DIGEST = "45ff220697da9604dbe69c82761f285ba2e3e5182ef0819360128b82dd169efc"
Expand Down Expand Up @@ -771,6 +771,7 @@ def check_publisher(workflow)
'systemd_run_bin="/usr/bin/systemd-run"',
'systemctl_bin="/usr/bin/systemctl"',
'getent_bin="/usr/bin/getent"',
'findmnt_bin="/usr/bin/findmnt"',
'pgrep_bin="/usr/bin/pgrep"',
'pkill_bin="/usr/bin/pkill"',
'useradd_bin="/usr/sbin/useradd"',
Expand Down Expand Up @@ -819,8 +820,7 @@ def check_publisher(workflow)
'homebrew_patched_launcher_isolate "$BUILD_USER"',
'homebrew_patched_launcher_teardown "$BUILD_USER"',
"homebrew_patched_launcher_verify_isolation",
'homebrew_assert_tree_not_writable_by_user "$BUILD_USER" "$OUT_DIR"',
'homebrew_assert_tree_not_replaceable_by_user "$BUILD_USER" "$OUT_DIR"',
'"$WORK_DIR" "$KANDELO_ROOT" "$TAP_ROOT" "$OUT_DIR"',
"CI Formula execution requires KANDELO_HOMEBREW_BUILD_USER",
'mktemp -d "$SHARED_TEMP/homebrew-build.XXXXXX"',
'CONTROL_DIR="$(mktemp -d "$OUT_DIR/.control.XXXXXX")"',
Expand Down Expand Up @@ -932,13 +932,17 @@ def check_publisher(workflow)
"systemd-run", "--wait", "--collect", "--pipe",
"--property=KillMode=control-group", "--property=SendSIGKILL=yes",
"--property=NoNewPrivileges=yes", "--expand-environment=no",
"--property=BindReadOnlyPaths=", "--property=InaccessiblePaths=",
'"--uid=$build_user"', '"--gid=$build_group"',
'env_bin="$(command -v env)"',
'printf \' --working-directory="$working_directory" -- %q -i\'',
'printf \'bottle_tag_env=()\\n\'',
'for variable in KANDELO_HOMEBREW_BOTTLE_TAG HOMEBREW_KANDELO_BOTTLE_TAG',
'bottle_tag_env+=("%s=${%s}")',
'printf \' "${bottle_tag_env[@]}" %q "$@"\\n\' "$protected_brew"',
'HOMEBREW_KANDELO_ROOT=$source_alias_dir/kandelo',
'KANDELO_HOMEBREW_KANDELO_ROOT=$source_alias_dir/kandelo',
'printf \' "${bottle_tag_env[@]}" "$command_path" "$@"\\n\'',
"__kandelo_verify_source_aliases", "/usr/bin/findmnt",
'"$sudo_bin" install -o root -g root -m 0555 "$wrapper_source" "$wrapper_path"',
"-writable -print -quit", "! -readable -o ! -executable", "-prune",
"homebrew_patched_launcher_uid_has_processes", "homebrew_patched_launcher_teardown",
Expand Down
5 changes: 2 additions & 3 deletions scripts/homebrew-bottle-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,8 @@ if [ -n "$BUILD_USER" ]; then
# loading TypeScript sources. Do that while the workflow identity still owns
# the checkout; the isolated build identity receives no source write access.
rm -rf "$KANDELO_ROOT/host/dist"
homebrew_patched_launcher_isolate "$BUILD_USER" "$WORK_DIR" "$KANDELO_ROOT" "$TAP_ROOT"
homebrew_assert_tree_not_writable_by_user "$BUILD_USER" "$OUT_DIR"
homebrew_assert_tree_not_replaceable_by_user "$BUILD_USER" "$OUT_DIR"
homebrew_patched_launcher_isolate "$BUILD_USER" \
"$WORK_DIR" "$KANDELO_ROOT" "$TAP_ROOT" "$OUT_DIR"
BREW_BIN="$HOMEBREW_PATCHED_BREW_BIN"
elif [ "${GITHUB_ACTIONS:-}" = "true" ]; then
echo "homebrew-bottle-build.sh: CI Formula execution requires KANDELO_HOMEBREW_BUILD_USER" >&2
Expand Down
114 changes: 96 additions & 18 deletions scripts/homebrew-patched-launcher.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ HOMEBREW_PATCHED_OVERLAY=""
HOMEBREW_PATCHED_LAUNCHER=""
HOMEBREW_PATCHED_BREW_BIN=""
HOMEBREW_PATCHED_PROTECTED_DIR=""
HOMEBREW_PATCHED_SOURCE_ALIAS_DIR=""
HOMEBREW_PATCHED_INTEGRITY_SHA256=""
HOMEBREW_PATCHED_SUDO_BIN=""
HOMEBREW_PATCHED_SYSTEMD_RUN_BIN=""
Expand Down Expand Up @@ -50,11 +51,13 @@ homebrew_assert_tree_not_writable_by_user() {
echo "homebrew-patched-launcher: privileged host boundary is not initialized" >&2
return 2
}
writable="$("$HOMEBREW_PATCHED_SUDO_BIN" -H -u "$user" -- \
if ! writable="$("$HOMEBREW_PATCHED_SUDO_BIN" -H -u "$user" -- \
find "$tree" -xdev \
\( -writable -print -quit \) -o \
\( -type d \( ! -readable -o ! -executable \) -prune \) \
2>/dev/null)"
\( -type d \( ! -readable -o ! -executable \) -prune \))"; then
echo "homebrew-patched-launcher: could not inspect protected source as $user: $tree" >&2
return 2
fi
if [ -n "$writable" ]; then
echo "homebrew-patched-launcher: build user can write protected source: $writable" >&2
return 1
Expand Down Expand Up @@ -137,6 +140,11 @@ homebrew_patched_launcher_cleanup() {
>/dev/null 2>&1 || true
HOMEBREW_PATCHED_PROTECTED_DIR=""
fi
if [ -n "$HOMEBREW_PATCHED_SOURCE_ALIAS_DIR" ]; then
"$HOMEBREW_PATCHED_SUDO_BIN" rm -rf "$HOMEBREW_PATCHED_SOURCE_ALIAS_DIR" \
>/dev/null 2>&1 || true
HOMEBREW_PATCHED_SOURCE_ALIAS_DIR=""
fi
if [ -n "$HOMEBREW_PATCHED_LAUNCHER" ] && [ -L "$HOMEBREW_PATCHED_LAUNCHER" ]; then
rm -f "$HOMEBREW_PATCHED_LAUNCHER" 2>/dev/null || \
"$HOMEBREW_PATCHED_SUDO_BIN" rm -f "$HOMEBREW_PATCHED_LAUNCHER" \
Expand Down Expand Up @@ -164,16 +172,17 @@ homebrew_patched_launcher_cleanup() {
# to a dedicated user inside a transient systemd service. KillMode=control-group
# makes double-forked or session-detached descendants part of the call lifecycle.
homebrew_patched_launcher_isolate() {
if [ "$#" -ne 4 ]; then
echo "homebrew_patched_launcher_isolate: expected BUILD_USER WORK_DIR KANDELO_ROOT TAP_ROOT" >&2
if [ "$#" -ne 5 ]; then
echo "homebrew_patched_launcher_isolate: expected BUILD_USER WORK_DIR KANDELO_ROOT TAP_ROOT OUTPUT_ROOT" >&2
return 2
fi
local build_user="$1" work_dir="$2" kandelo_root="$3" tap_root="$4"
local build_group build_home protected_brew wrapper_source wrapper_path
local build_user="$1" work_dir="$2" kandelo_root="$3" tap_root="$4" output_root="$5"
local build_group build_home protected_brew protected_audit
local wrapper_source wrapper_path audit_source
local mutable_root protected_root
local sudo_bin sudo_mode env_bin variable value patched_prefix patched_repo
local systemd_run_bin systemctl_bin getent_bin pgrep_bin pkill_bin
local build_uid systemd_slice unit_prefix
local build_uid systemd_slice unit_prefix source_alias_dir
local -a preserved_variables

[ "$(uname -s)" = "Linux" ] || {
Expand Down Expand Up @@ -218,6 +227,8 @@ homebrew_patched_launcher_isolate() {
"$build_user" "$pgrep_bin" /usr/bin/pgrep pgrep
homebrew_assert_protected_host_executable \
"$build_user" "$pkill_bin" /usr/bin/pkill pkill /usr/bin/pgrep
homebrew_assert_protected_host_executable \
"$build_user" /usr/bin/findmnt /usr/bin/findmnt findmnt
[ -d /run/systemd/system ] || {
echo "homebrew-patched-launcher: systemd is not the active service manager" >&2
return 2
Expand All @@ -235,6 +246,19 @@ homebrew_patched_launcher_isolate() {
return 2
}

for protected_root in "$kandelo_root" "$tap_root" "$output_root"; do
if [ ! -d "$protected_root" ] || [ -L "$protected_root" ]; then
echo "homebrew-patched-launcher: protected root is not a real directory: $protected_root" >&2
return 2
fi
case "$protected_root" in
*:*)
echo "homebrew-patched-launcher: protected root cannot contain ':' for a systemd bind: $protected_root" >&2
return 2
;;
esac
done

for mutable_root in "$work_dir" "$HOMEBREW_CACHE" "$HOMEBREW_TEMP"; do
if [ ! -d "$mutable_root" ] || [ -L "$mutable_root" ]; then
echo "homebrew-patched-launcher: mutable build root is not a real directory: $mutable_root" >&2
Expand Down Expand Up @@ -262,9 +286,43 @@ homebrew_patched_launcher_isolate() {

HOMEBREW_PATCHED_PROTECTED_DIR="$HOMEBREW_PATCHED_PREFIX/.kandelo-homebrew-$$-${RANDOM}"
"$sudo_bin" install -d -o root -g root -m 0755 "$HOMEBREW_PATCHED_PROTECTED_DIR"
source_alias_dir="$work_dir/source-aliases"
"$sudo_bin" install -d -o root -g root -m 0555 \
"$source_alias_dir" "$source_alias_dir/kandelo" "$source_alias_dir/tap"
HOMEBREW_PATCHED_SOURCE_ALIAS_DIR="$source_alias_dir"
protected_brew="$HOMEBREW_PATCHED_PROTECTED_DIR/brew"
"$sudo_bin" ln -s "$HOMEBREW_PATCHED_OVERLAY/bin/brew" "$protected_brew"

audit_source="$work_dir/audit-source-aliases"
protected_audit="$HOMEBREW_PATCHED_PROTECTED_DIR/audit-source-aliases"
{
printf '#!/usr/bin/env bash\nset -euo pipefail\n'
printf 'expected_kandelo=%q\n' "$source_alias_dir/kandelo"
printf 'expected_tap=%q\n' "$source_alias_dir/tap"
printf 'if [ "${HOMEBREW_KANDELO_ROOT:-}" != "$expected_kandelo" ] || '
printf '[ "${KANDELO_HOMEBREW_KANDELO_ROOT:-}" != "$expected_kandelo" ]; then\n'
printf ' echo "homebrew-patched-launcher: isolated Kandelo root does not use the protected alias" >&2\n'
printf ' exit 2\nfi\n'
printf 'for source_alias in "$expected_kandelo" "$expected_tap"; do\n'
printf ' if [ ! -d "$source_alias" ] || [ ! -r "$source_alias" ] || [ ! -x "$source_alias" ]; then\n'
printf ' echo "homebrew-patched-launcher: protected source alias is inaccessible: $source_alias" >&2\n'
printf ' exit 2\n fi\n'
printf ' mount_options="$(/usr/bin/findmnt --noheadings --output VFS-OPTIONS --target "$source_alias")" || {\n'
printf ' echo "homebrew-patched-launcher: could not inspect protected source mount: $source_alias" >&2\n'
printf ' exit 2\n }\n'
printf ' case ",${mount_options// /}," in\n'
printf ' *,ro,*) ;;\n'
printf ' *) echo "homebrew-patched-launcher: protected source mount is writable: $source_alias" >&2; exit 1 ;;\n'
printf ' esac\ndone\n'
printf 'for hidden_root in %q %q %q; do\n' \
"$kandelo_root" "$tap_root" "$output_root"
printf ' if [ -e "$hidden_root" ] || [ -r "$hidden_root" ] || [ -x "$hidden_root" ]; then\n'
printf ' echo "homebrew-patched-launcher: original protected root is visible to Formula execution: $hidden_root" >&2\n'
printf ' exit 1\n fi\ndone\n'
} >"$audit_source"
"$sudo_bin" install -o root -g root -m 0555 "$audit_source" "$protected_audit"
rm -f "$audit_source"

wrapper_source="$work_dir/run-isolated-brew"
wrapper_path="$HOMEBREW_PATCHED_PROTECTED_DIR/run-brew"
systemd_slice="kandelo-homebrew-build-${build_uid}.slice"
Expand All @@ -274,8 +332,8 @@ homebrew_patched_launcher_isolate() {
PATH XDG_CONFIG_HOME
HOMEBREW_CACHE HOMEBREW_TEMP HOMEBREW_NO_AUTO_UPDATE
HOMEBREW_NO_INSTALL_CLEANUP HOMEBREW_NO_ANALYTICS HOMEBREW_DEVELOPER
KANDELO_HOMEBREW_ARCH KANDELO_HOMEBREW_KANDELO_ROOT
HOMEBREW_KANDELO_ARCH HOMEBREW_KANDELO_ROOT HOMEBREW_KANDELO_NODE
KANDELO_HOMEBREW_ARCH
HOMEBREW_KANDELO_ARCH HOMEBREW_KANDELO_NODE
HOMEBREW_KANDELO_LLVM_BIN HOMEBREW_KANDELO_ABI
HOMEBREW_KANDELO_NODE_RECEIPT_PATH
LLVM_BIN WASM_POSIX_LLVM_DIR
Expand All @@ -288,9 +346,11 @@ homebrew_patched_launcher_isolate() {
printf 'if [ -n "${%s+x}" ]; then bottle_tag_env+=("%s=${%s}"); fi\n' \
"$variable" "$variable" "$variable"
done
# The workflow checkout may live below a home directory that the isolated
# build identity cannot traverse. The mutable work root was already
# verified for that identity, so use it as the service working directory.
printf 'command_path=%q\n' "$protected_brew"
printf 'if [ "${1:-}" = __kandelo_verify_source_aliases ]; then\n'
printf ' [ "$#" -eq 1 ] || { echo "homebrew-patched-launcher: source audit accepts no arguments" >&2; exit 2; }\n'
printf ' command_path=%q\n' "$protected_audit"
printf ' shift\nfi\n'
printf 'working_directory=%q\n' "$work_dir"
printf 'unit=%q-$$-${RANDOM}.service\n' "$unit_prefix"
printf 'exec %q -n -- %q --quiet --wait --collect --pipe' \
Expand All @@ -300,6 +360,11 @@ homebrew_patched_launcher_isolate() {
"--uid=$build_user" "--gid=$build_group" \
"--property=KillMode=control-group" "--property=SendSIGKILL=yes" \
"--property=TimeoutStopSec=10s" "--property=NoNewPrivileges=yes" \
"--property=BindReadOnlyPaths=$kandelo_root:$source_alias_dir/kandelo" \
"--property=BindReadOnlyPaths=$tap_root:$source_alias_dir/tap" \
"--property=InaccessiblePaths=$kandelo_root" \
"--property=InaccessiblePaths=$tap_root" \
"--property=InaccessiblePaths=$output_root" \
"--service-type=exec" \
"--expand-environment=no"
printf ' --working-directory="$working_directory" -- %q -i' "$env_bin"
Expand All @@ -311,14 +376,17 @@ homebrew_patched_launcher_isolate() {
printf ' %q' "$variable=$value"
fi
done
printf ' "${bottle_tag_env[@]}" %q "$@"\n' "$protected_brew"
printf ' %q %q' "HOMEBREW_KANDELO_ROOT=$source_alias_dir/kandelo" \
"KANDELO_HOMEBREW_KANDELO_ROOT=$source_alias_dir/kandelo"
printf ' "${bottle_tag_env[@]}" "$command_path" "$@"\n'
} >"$wrapper_source"
"$sudo_bin" install -o root -g root -m 0555 "$wrapper_source" "$wrapper_path"
rm -f "$wrapper_source"
"$sudo_bin" chmod 0555 "$HOMEBREW_PATCHED_PROTECTED_DIR"

for protected_root in \
"$kandelo_root" "$tap_root" "$HOMEBREW_PATCHED_REPO" "$HOMEBREW_PATCHED_OVERLAY"; do
# The overlay is a Git worktree, so its backing repository must remain
# traversable. Protect the Formula-executing overlay itself instead.
for protected_root in "$source_alias_dir" "$HOMEBREW_PATCHED_OVERLAY"; do
homebrew_assert_tree_not_writable_by_user "$build_user" "$protected_root"
homebrew_assert_tree_not_replaceable_by_user "$build_user" "$protected_root"
done
Expand All @@ -338,8 +406,18 @@ homebrew_patched_launcher_isolate() {
"$sudo_bin" rm -f "$HOMEBREW_PATCHED_LAUNCHER"
HOMEBREW_PATCHED_LAUNCHER="$protected_brew"
HOMEBREW_PATCHED_BREW_BIN="$wrapper_path"
patched_prefix="$("$HOMEBREW_PATCHED_BREW_BIN" --prefix)" || return
patched_repo="$("$HOMEBREW_PATCHED_BREW_BIN" --repository)" || return
"$HOMEBREW_PATCHED_BREW_BIN" __kandelo_verify_source_aliases || {
echo "homebrew-patched-launcher: isolated source aliases failed verification" >&2
return 1
}
if ! patched_prefix="$("$HOMEBREW_PATCHED_BREW_BIN" --prefix)"; then
echo "homebrew-patched-launcher: isolated wrapper could not report the Homebrew prefix" >&2
return 1
fi
if ! patched_repo="$("$HOMEBREW_PATCHED_BREW_BIN" --repository)"; then
echo "homebrew-patched-launcher: isolated wrapper could not report the Homebrew repository" >&2
return 1
fi
[ "$patched_prefix" = "$HOMEBREW_PATCHED_PREFIX" ] || {
echo "homebrew-patched-launcher: isolated wrapper changed Homebrew prefix" >&2
return 1
Expand Down
5 changes: 2 additions & 3 deletions scripts/homebrew-verify-poured-bottle.sh
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,8 @@ TAPPED_TAP_ROOT="$("$BREW_BIN" --repository "$TAP_NAME")"

if [ -n "$BUILD_USER" ]; then
rm -rf "$KANDELO_ROOT/host/dist"
homebrew_patched_launcher_isolate "$BUILD_USER" "$WORK_DIR" "$KANDELO_ROOT" "$TAP_ROOT"
homebrew_assert_tree_not_writable_by_user "$BUILD_USER" "$OUT_PARENT"
homebrew_assert_tree_not_replaceable_by_user "$BUILD_USER" "$OUT_PARENT"
homebrew_patched_launcher_isolate "$BUILD_USER" \
"$WORK_DIR" "$KANDELO_ROOT" "$TAP_ROOT" "$OUT_PARENT"
BREW_BIN="$HOMEBREW_PATCHED_BREW_BIN"
elif [ "${GITHUB_ACTIONS:-}" = "true" ]; then
echo "homebrew-verify-poured-bottle.sh: CI Formula execution requires KANDELO_HOMEBREW_BUILD_USER" >&2
Expand Down
Loading
Loading