commit 7a5f0b4704f8403302bf1036a376df4a80e292a2
parent 4c9054172553e738e769c741f1b29add17bf6f6f
Author: triesap <tyson@radroots.org>
Date: Sat, 18 Apr 2026 00:17:26 +0000
app: harden macos host run lane
Diffstat:
5 files changed, 325 insertions(+), 117 deletions(-)
diff --git a/platforms/macos/Scripts/build-macos-host.sh b/platforms/macos/Scripts/build-macos-host.sh
@@ -4,16 +4,9 @@ set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
platform_root="$(cd "${script_dir}/.." && pwd -P)"
repo_root="$(git -C "${script_dir}" rev-parse --show-toplevel)"
-configuration="${CONFIGURATION:-Debug}"
+requested_configuration="${CONFIGURATION:-Debug}"
bundle_name="Radroots.app"
-bundle_root="${platform_root}/.derived-data/Build/Products/${configuration}/${bundle_name}"
-contents_root="${bundle_root}/Contents"
-executable_root="${contents_root}/MacOS"
-resources_root="${contents_root}/Resources"
plist_template="${platform_root}/App/Resources/Info.plist"
-plist_path="${contents_root}/Info.plist"
-binary_target="${executable_root}/Radroots"
-app_icon_path="${resources_root}/AppIcon.icns"
require_command() {
if command -v "$1" >/dev/null 2>&1; then
@@ -41,7 +34,27 @@ PY
}
cargo_target_dir() {
- cargo metadata --format-version 1 --no-deps | python3 -c 'import json, sys; print(json.load(sys.stdin)["target_directory"], end="")'
+ (
+ cd "${repo_root}"
+ cargo metadata --format-version 1 --no-deps | python3 -c 'import json, sys; print(json.load(sys.stdin)["target_directory"], end="")'
+ )
+}
+
+configure_build_lane() {
+ case "${requested_configuration}" in
+ Debug|debug)
+ bundle_configuration="Debug"
+ cargo_profile="debug"
+ ;;
+ Release|release)
+ bundle_configuration="Release"
+ cargo_profile="release"
+ ;;
+ *)
+ echo "unsupported CONFIGURATION: ${requested_configuration}" >&2
+ exit 1
+ ;;
+ esac
}
require_command cargo
@@ -49,12 +62,26 @@ require_command git
require_command python3
require_command /usr/libexec/PlistBuddy
+configure_build_lane
+
+bundle_root="${platform_root}/.derived-data/Build/Products/${bundle_configuration}/${bundle_name}"
+contents_root="${bundle_root}/Contents"
+executable_root="${contents_root}/MacOS"
+resources_root="${contents_root}/Resources"
+plist_path="${contents_root}/Info.plist"
+binary_target="${executable_root}/Radroots"
+app_icon_path="${resources_root}/AppIcon.icns"
+
(
cd "${repo_root}"
- cargo build -p radroots_app
+ if [[ "${cargo_profile}" == "release" ]]; then
+ cargo build -p radroots_app --release
+ else
+ cargo build -p radroots_app
+ fi
)
-binary_source="$(cargo_target_dir)/debug/radroots_app"
+binary_source="$(cargo_target_dir)/${cargo_profile}/radroots_app"
if [[ ! -x "${binary_source}" ]]; then
echo "missing desktop launcher binary: ${binary_source}" >&2
diff --git a/platforms/macos/Scripts/run-macos-host.sh b/platforms/macos/Scripts/run-macos-host.sh
@@ -2,6 +2,7 @@
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
+date_utc="$(date -u +%F)"
require_command() {
if command -v "$1" >/dev/null 2>&1; then
@@ -11,7 +12,27 @@ require_command() {
exit 1
}
+require_env() {
+ local name="$1"
+
+ if [[ -z "${!name:-}" ]]; then
+ echo "missing required environment variable: ${name}" >&2
+ exit 1
+ fi
+}
+
+forward_signal() {
+ local signal="$1"
+
+ if [[ -n "${app_pid:-}" ]] && kill -0 "${app_pid}" 2>/dev/null; then
+ kill "-${signal}" "${app_pid}" 2>/dev/null || kill "${app_pid}" 2>/dev/null || true
+ fi
+}
+
+require_command grep
require_command /usr/libexec/PlistBuddy
+require_env RADROOTS_APP_RUNTIME_CONFIG_JSON
+require_env RADROOTS_APP_LOCAL_LOG_ROOT
app_path="$("${script_dir}/build-macos-host.sh")"
plist_path="${app_path}/Contents/Info.plist"
@@ -19,6 +40,43 @@ executable_name="$(
/usr/libexec/PlistBuddy -c 'Print :CFBundleExecutable' "${plist_path}"
)"
executable_path="${app_path}/Contents/MacOS/${executable_name}"
+app_log_root="${RADROOTS_APP_LOCAL_LOG_ROOT}/apps/local/app/app-macos-native"
+structured_log_file="${app_log_root}/${date_utc}.jsonl"
+stdout_file="${app_log_root}/raw/stdout.${date_utc}.log"
+stderr_file="${app_log_root}/raw/stderr.${date_utc}.log"
+
+mkdir -p "${app_log_root}/raw"
+export RUST_LOG="${RADROOTS_APP_RUST_LOG:-info}"
+
+trap 'forward_signal TERM' TERM
+trap 'forward_signal INT' INT
+trap 'forward_signal HUP' HUP
+
+"${executable_path}" "$@" >>"${stdout_file}" 2>>"${stderr_file}" &
+app_pid="$!"
+
+launch_confirmed=false
+for _ in $(seq 1 100); do
+ if [[ -f "${structured_log_file}" ]] && grep -q '"event":"runtime.launch"' "${structured_log_file}" 2>/dev/null; then
+ launch_confirmed=true
+ break
+ fi
+
+ if ! kill -0 "${app_pid}" 2>/dev/null; then
+ wait "${app_pid}"
+ exit $?
+ fi
+
+ sleep 0.1
+done
+
+if [[ "${launch_confirmed}" != "true" ]]; then
+ if kill -0 "${app_pid}" 2>/dev/null; then
+ kill "${app_pid}" 2>/dev/null || true
+ wait "${app_pid}" || true
+ fi
+ echo "app launch did not emit runtime.launch within startup timeout" >&2
+ exit 1
+fi
-"${executable_path}" "$@" &
-disown
+wait "${app_pid}"
diff --git a/platforms/macos/Scripts/test-macos-host.sh b/platforms/macos/Scripts/test-macos-host.sh
@@ -2,6 +2,11 @@
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
+platform_root="$(cd "${script_dir}/.." && pwd -P)"
+repo_root="$(git -C "${script_dir}" rev-parse --show-toplevel)"
+date_utc="$(date -u +%F)"
+
+source "${repo_root}/scripts/launch-config.sh"
require_command() {
if command -v "$1" >/dev/null 2>&1; then
@@ -12,6 +17,7 @@ require_command() {
}
require_command /usr/libexec/PlistBuddy
+require_command mktemp
app_path="$("${script_dir}/build-macos-host.sh")"
plist_path="${app_path}/Contents/Info.plist"
@@ -47,3 +53,95 @@ icon_name="$(
echo "missing bundle icon: ${app_path}/Contents/Resources/${icon_name}.icns" >&2
exit 1
}
+
+release_app_path="$(
+ CONFIGURATION=Release "${script_dir}/build-macos-host.sh"
+)"
+[[ "${release_app_path}" == "${platform_root}/.derived-data/Build/Products/Release/Radroots.app" ]] || {
+ echo "unexpected release bundle path: ${release_app_path}" >&2
+ exit 1
+}
+[[ -x "${release_app_path}/Contents/MacOS/Radroots" ]] || {
+ echo "missing release bundle executable: ${release_app_path}/Contents/MacOS/Radroots" >&2
+ exit 1
+}
+
+tmp_root="$(mktemp -d)"
+cleanup() {
+ if [[ -n "${runner_pid:-}" ]] && kill -0 "${runner_pid}" 2>/dev/null; then
+ kill "${runner_pid}" 2>/dev/null || true
+ wait "${runner_pid}" || true
+ fi
+ rm -rf "${tmp_root}"
+}
+trap cleanup EXIT
+
+runtime_mode="localhost-dev"
+run_id="$(radroots_app_run_id "${runtime_mode}")"
+platform_name="$(radroots_app_platform_name)"
+bundle_identifier="$(radroots_app_bundle_identifier)"
+local_log_root="${tmp_root}/logs"
+structured_log_file="${local_log_root}/apps/local/app/app-macos-native/${date_utc}.jsonl"
+latest_log_path="${local_log_root}/apps/local/app/app-macos-native/latest.jsonl"
+stdout_file="${local_log_root}/apps/local/app/app-macos-native/raw/stdout.${date_utc}.log"
+stderr_file="${local_log_root}/apps/local/app/app-macos-native/raw/stderr.${date_utc}.log"
+
+RADROOTS_APP_RUN_ID="${run_id}" \
+RADROOTS_APP_LOCAL_LOG_ROOT="${local_log_root}" \
+RADROOTS_APP_RUNTIME_CONFIG_JSON="$(
+ radroots_app_build_runtime_config_json \
+ "${repo_root}" \
+ "${runtime_mode}" \
+ "${run_id}" \
+ "${bundle_identifier}" \
+ "${platform_name}" \
+ "${local_log_root}"
+)" \
+"${script_dir}/run-macos-host.sh" &
+runner_pid="$!"
+
+launch_verified=false
+for _ in $(seq 1 150); do
+ if [[ -f "${structured_log_file}" ]] && grep -q '"event":"runtime.launch"' "${structured_log_file}" 2>/dev/null; then
+ launch_verified=true
+ break
+ fi
+
+ if ! kill -0 "${runner_pid}" 2>/dev/null; then
+ wait "${runner_pid}"
+ exit $?
+ fi
+
+ sleep 0.1
+done
+
+[[ "${launch_verified}" == "true" ]] || {
+ echo "runtime.launch was not recorded by run-macos-host.sh" >&2
+ exit 1
+}
+
+[[ -e "${latest_log_path}" ]] || {
+ echo "missing latest structured log alias: ${latest_log_path}" >&2
+ exit 1
+}
+
+[[ -f "${stdout_file}" ]] || {
+ echo "missing raw stdout log: ${stdout_file}" >&2
+ exit 1
+}
+
+[[ -f "${stderr_file}" ]] || {
+ echo "missing raw stderr log: ${stderr_file}" >&2
+ exit 1
+}
+
+kill "${runner_pid}" 2>/dev/null || true
+set +e
+wait "${runner_pid}"
+exit_code="$?"
+set -e
+[[ "${exit_code}" == "0" ]] || [[ "${exit_code}" == "143" ]] || [[ "${exit_code}" == "130" ]] || {
+ echo "unexpected runner exit code after termination: ${exit_code}" >&2
+ exit 1
+}
+runner_pid=""
diff --git a/scripts/launch-config.sh b/scripts/launch-config.sh
@@ -0,0 +1,117 @@
+#!/usr/bin/env bash
+
+radroots_app_workspace_version() {
+ local repo_root="$1"
+
+ python3 - <<'PY' "${repo_root}/Cargo.toml"
+import re
+import sys
+
+path = sys.argv[1]
+with open(path, "r", encoding="utf-8") as handle:
+ cargo_toml = handle.read()
+
+match = re.search(r'^\[workspace\.package\][\s\S]*?^version\s*=\s*"([^"]+)"', cargo_toml, re.MULTILINE)
+if not match:
+ raise SystemExit("missing workspace.package.version")
+
+print(match.group(1), end="")
+PY
+}
+
+radroots_app_runtime_mode() {
+ printf '%s' "${RADROOTS_APP_RUNTIME_MODE:-localhost-dev}"
+}
+
+radroots_app_run_id() {
+ local runtime_mode="$1"
+
+ if [[ -n "${RADROOTS_APP_RUN_ID:-}" ]]; then
+ printf '%s' "${RADROOTS_APP_RUN_ID}"
+ return
+ fi
+
+ RADROOTS_APP_RUNTIME_MODE_FOR_RUN_ID="${runtime_mode}" python3 - <<'PY'
+import os
+import secrets
+import time
+
+runtime_mode = os.environ["RADROOTS_APP_RUNTIME_MODE_FOR_RUN_ID"].strip().lower() or "unknown"
+timestamp = time.strftime("%Y%m%dT%H%M%SZ", time.gmtime())
+suffix = secrets.token_hex(8)
+print(f"app-{runtime_mode}-{timestamp}-{suffix}", end="")
+PY
+}
+
+radroots_app_platform_name() {
+ case "$(uname -s)" in
+ Darwin) printf 'macos' ;;
+ Linux) printf 'linux' ;;
+ *) uname -s | tr '[:upper:]' '[:lower:]' ;;
+ esac
+}
+
+radroots_app_bundle_identifier() {
+ if [[ "$(uname -s)" == "Darwin" ]]; then
+ printf 'org.radroots.app.macos'
+ return
+ fi
+
+ printf 'org.radroots.app.desktop'
+}
+
+radroots_app_os_version() {
+ printf '%s-%s' "$(radroots_app_platform_name)" "$(uname -r)"
+}
+
+radroots_app_local_log_root() {
+ local repo_root="$1"
+
+ if [[ -n "${RADROOTS_APP_LOCAL_LOG_ROOT:-}" ]]; then
+ printf '%s' "${RADROOTS_APP_LOCAL_LOG_ROOT}"
+ return
+ fi
+
+ printf '%s' "${repo_root}/logs"
+}
+
+radroots_app_build_runtime_config_json() {
+ local repo_root="$1"
+ local runtime_mode="$2"
+ local run_id="$3"
+ local bundle_identifier="$4"
+ local platform_name="$5"
+ local local_log_root="$6"
+
+ RADROOTS_APP_RUNTIME_CONFIG_SCHEMA="radroots.app.runtime-config.v1" \
+ RADROOTS_APP_RUNTIME_MODE="${runtime_mode}" \
+ RADROOTS_APP_RUN_ID="${run_id}" \
+ RADROOTS_APP_BUNDLE_IDENTIFIER="${bundle_identifier}" \
+ RADROOTS_APP_BUNDLE_NAME="Radroots" \
+ RADROOTS_APP_MARKETING_VERSION="$(radroots_app_workspace_version "${repo_root}")" \
+ RADROOTS_APP_BUILD_NUMBER="${RADROOTS_APP_BUILD:-dev}" \
+ RADROOTS_APP_PLATFORM_NAME="${platform_name}" \
+ RADROOTS_APP_OS_VERSION="$(radroots_app_os_version)" \
+ RADROOTS_APP_HOST_LOCALE="${LANG:-system-default}" \
+ RADROOTS_APP_RUNTIME_ORIGIN="gpui://localhost" \
+ RADROOTS_APP_LOCAL_LOG_ROOT="${local_log_root}" \
+ python3 - <<'PY'
+import json
+import os
+
+print(json.dumps({
+ "schema_version": os.environ["RADROOTS_APP_RUNTIME_CONFIG_SCHEMA"],
+ "runtime_mode": os.environ["RADROOTS_APP_RUNTIME_MODE"],
+ "run_id": os.environ["RADROOTS_APP_RUN_ID"],
+ "bundle_identifier": os.environ["RADROOTS_APP_BUNDLE_IDENTIFIER"],
+ "bundle_name": os.environ["RADROOTS_APP_BUNDLE_NAME"],
+ "marketing_version": os.environ["RADROOTS_APP_MARKETING_VERSION"],
+ "build_number": os.environ["RADROOTS_APP_BUILD_NUMBER"],
+ "platform_name": os.environ["RADROOTS_APP_PLATFORM_NAME"],
+ "operating_system_version": os.environ["RADROOTS_APP_OS_VERSION"],
+ "host_locale": os.environ["RADROOTS_APP_HOST_LOCALE"],
+ "runtime_origin": os.environ["RADROOTS_APP_RUNTIME_ORIGIN"],
+ "local_log_root": os.environ["RADROOTS_APP_LOCAL_LOG_ROOT"],
+}, sort_keys=True, separators=(",", ":")), end="")
+PY
+}
diff --git a/scripts/run.sh b/scripts/run.sh
@@ -4,119 +4,27 @@ set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
repo_root="$(git -C "${script_dir}" rev-parse --show-toplevel)"
-workspace_version() {
- python3 - <<'PY' "${repo_root}/Cargo.toml"
-import re
-import sys
-
-path = sys.argv[1]
-with open(path, "r", encoding="utf-8") as handle:
- cargo_toml = handle.read()
-
-match = re.search(r'^\[workspace\.package\][\s\S]*?^version\s*=\s*"([^"]+)"', cargo_toml, re.MULTILINE)
-if not match:
- raise SystemExit("missing workspace.package.version")
-
-print(match.group(1), end="")
-PY
-}
-
-current_runtime_mode() {
- printf '%s' "${RADROOTS_APP_RUNTIME_MODE:-localhost-dev}"
-}
-
-current_run_id() {
- if [[ -n "${RADROOTS_APP_RUN_ID:-}" ]]; then
- printf '%s' "${RADROOTS_APP_RUN_ID}"
- return
- fi
-
- RADROOTS_APP_RUNTIME_MODE_FOR_RUN_ID="$(current_runtime_mode)" python3 - <<'PY'
-import os
-import secrets
-import time
-
-runtime_mode = os.environ["RADROOTS_APP_RUNTIME_MODE_FOR_RUN_ID"].strip().lower() or "unknown"
-timestamp = time.strftime("%Y%m%dT%H%M%SZ", time.gmtime())
-suffix = secrets.token_hex(8)
-print(f"app-{runtime_mode}-{timestamp}-{suffix}", end="")
-PY
-}
-
-current_platform_name() {
- case "$(uname -s)" in
- Darwin) printf 'macos' ;;
- Linux) printf 'linux' ;;
- *) uname -s | tr '[:upper:]' '[:lower:]' ;;
- esac
-}
-
-current_bundle_identifier() {
- if [[ "$(uname -s)" == "Darwin" ]]; then
- printf 'org.radroots.app.macos'
- return
- fi
-
- printf 'org.radroots.app.desktop'
-}
-
-current_os_version() {
- printf '%s-%s' "$(current_platform_name)" "$(uname -r)"
-}
-
-build_runtime_config_json() {
- local runtime_mode="$1"
- local run_id="$2"
- local bundle_identifier="$3"
- local platform_name="$4"
-
- RADROOTS_APP_RUNTIME_CONFIG_SCHEMA="radroots.app.runtime-config.v1" \
- RADROOTS_APP_RUNTIME_MODE="${runtime_mode}" \
- RADROOTS_APP_RUN_ID="${run_id}" \
- RADROOTS_APP_BUNDLE_IDENTIFIER="${bundle_identifier}" \
- RADROOTS_APP_BUNDLE_NAME="Radroots" \
- RADROOTS_APP_MARKETING_VERSION="$(workspace_version)" \
- RADROOTS_APP_BUILD_NUMBER="${RADROOTS_APP_BUILD:-dev}" \
- RADROOTS_APP_PLATFORM_NAME="${platform_name}" \
- RADROOTS_APP_OS_VERSION="$(current_os_version)" \
- RADROOTS_APP_HOST_LOCALE="${LANG:-system-default}" \
- RADROOTS_APP_RUNTIME_ORIGIN="gpui://localhost" \
- RADROOTS_APP_LOCAL_LOG_ROOT="${repo_root}/logs" \
- python3 - <<'PY'
-import json
-import os
-
-print(json.dumps({
- "schema_version": os.environ["RADROOTS_APP_RUNTIME_CONFIG_SCHEMA"],
- "runtime_mode": os.environ["RADROOTS_APP_RUNTIME_MODE"],
- "run_id": os.environ["RADROOTS_APP_RUN_ID"],
- "bundle_identifier": os.environ["RADROOTS_APP_BUNDLE_IDENTIFIER"],
- "bundle_name": os.environ["RADROOTS_APP_BUNDLE_NAME"],
- "marketing_version": os.environ["RADROOTS_APP_MARKETING_VERSION"],
- "build_number": os.environ["RADROOTS_APP_BUILD_NUMBER"],
- "platform_name": os.environ["RADROOTS_APP_PLATFORM_NAME"],
- "operating_system_version": os.environ["RADROOTS_APP_OS_VERSION"],
- "host_locale": os.environ["RADROOTS_APP_HOST_LOCALE"],
- "runtime_origin": os.environ["RADROOTS_APP_RUNTIME_ORIGIN"],
- "local_log_root": os.environ["RADROOTS_APP_LOCAL_LOG_ROOT"],
-}, sort_keys=True, separators=(",", ":")), end="")
-PY
-}
+source "${script_dir}/launch-config.sh"
cd "${repo_root}"
-runtime_mode="$(current_runtime_mode)"
-run_id="$(current_run_id)"
-platform_name="$(current_platform_name)"
-bundle_identifier="$(current_bundle_identifier)"
+runtime_mode="$(radroots_app_runtime_mode)"
+run_id="$(radroots_app_run_id "${runtime_mode}")"
+platform_name="$(radroots_app_platform_name)"
+bundle_identifier="$(radroots_app_bundle_identifier)"
+local_log_root="$(radroots_app_local_log_root "${repo_root}")"
export RADROOTS_APP_RUN_ID="${run_id}"
+export RADROOTS_APP_LOCAL_LOG_ROOT="${local_log_root}"
+export RUST_LOG="${RADROOTS_APP_RUST_LOG:-info}"
export RADROOTS_APP_RUNTIME_CONFIG_JSON="$(
- build_runtime_config_json \
+ radroots_app_build_runtime_config_json \
+ "${repo_root}" \
"${runtime_mode}" \
"${run_id}" \
"${bundle_identifier}" \
- "${platform_name}"
+ "${platform_name}" \
+ "${local_log_root}"
)"
if [[ "$(uname -s)" == "Darwin" ]]; then