diff --git a/scripts/setup-auth-system.sh b/scripts/setup-auth-system.sh index 33bf2edd6b8..b1c480a78a2 100755 --- a/scripts/setup-auth-system.sh +++ b/scripts/setup-auth-system.sh @@ -60,21 +60,88 @@ echo " OpenClaw message: Send warning via OpenClaw itself" echo "Enter your phone number for alerts (or leave blank to skip):" read -r PHONE_NUMBER -# Update service file -SERVICE_FILE="$SCRIPT_DIR/systemd/openclaw-auth-monitor.service" -if [ -n "$NTFY_TOPIC" ]; then - sed -i "s|# Environment=NOTIFY_NTFY=.*|Environment=NOTIFY_NTFY=$NTFY_TOPIC|" "$SERVICE_FILE" -fi -if [ -n "$PHONE_NUMBER" ]; then - sed -i "s|# Environment=NOTIFY_PHONE=.*|Environment=NOTIFY_PHONE=$PHONE_NUMBER|" "$SERVICE_FILE" -fi - # Install systemd units +SERVICE_TEMPLATE="$SCRIPT_DIR/systemd/openclaw-auth-monitor.service" +SYSTEMD_USER_DIR="$HOME/.config/systemd/user" +SERVICE_TARGET="$SYSTEMD_USER_DIR/openclaw-auth-monitor.service" +TIMER_TARGET="$SYSTEMD_USER_DIR/openclaw-auth-monitor.timer" +AUTH_MONITOR_PATH="$SCRIPT_DIR/auth-monitor.sh" + echo "" echo "Installing systemd timer..." -mkdir -p ~/.config/systemd/user -cp "$SCRIPT_DIR/systemd/openclaw-auth-monitor.service" ~/.config/systemd/user/ -cp "$SCRIPT_DIR/systemd/openclaw-auth-monitor.timer" ~/.config/systemd/user/ +mkdir -p "$SYSTEMD_USER_DIR" + +SERVICE_TEMP="$(mktemp "$SYSTEMD_USER_DIR/openclaw-auth-monitor.service.XXXXXX")" +SERVICE_RENDERED="" +cleanup_service_temp() { + rm -f "$SERVICE_TEMP" "$SERVICE_RENDERED" +} +trap cleanup_service_temp EXIT +SERVICE_RENDERED="$(mktemp "$SYSTEMD_USER_DIR/openclaw-auth-monitor.service.rendered.XXXXXX")" + +cp "$SERVICE_TEMPLATE" "$SERVICE_TEMP" + +systemd_quote_arg() { + local value="$1" + value="${value//\\/\\\\}" + value="${value//%/%%}" + value="${value//\$/\$\$}" + value="${value//\"/\\\"}" + printf '"%s"' "$value" +} + +render_environment_line() { + local key="$1" + local placeholder="$2" + local value="$3" + + if [ -n "$value" ]; then + printf 'Environment=%s=%s' "$key" "$value" + else + printf '# Environment=%s=%s' "$key" "$placeholder" + fi +} + +RENDERED_EXEC_START="ExecStart=$(systemd_quote_arg "$AUTH_MONITOR_PATH")" +RENDERED_NTFY_LINE="$(render_environment_line "NOTIFY_NTFY" "openclaw-alerts" "$NTFY_TOPIC")" +RENDERED_PHONE_LINE="$(render_environment_line "NOTIFY_PHONE" "+1234567890" "$PHONE_NUMBER")" +FOUND_EXEC_START=0 +FOUND_NTFY=0 +FOUND_PHONE=0 + +while IFS= read -r line || [ -n "$line" ]; do + if [[ "$line" =~ ^[[:space:]]*ExecStart=.*$ ]]; then + printf '%s\n' "$RENDERED_EXEC_START" + FOUND_EXEC_START=1 + elif [[ "$line" =~ ^[[:space:]]*#?[[:space:]]*Environment=NOTIFY_NTFY=.*$ ]]; then + printf '%s\n' "$RENDERED_NTFY_LINE" + FOUND_NTFY=1 + elif [[ "$line" =~ ^[[:space:]]*#?[[:space:]]*Environment=NOTIFY_PHONE=.*$ ]]; then + printf '%s\n' "$RENDERED_PHONE_LINE" + FOUND_PHONE=1 + else + printf '%s\n' "$line" + fi +done < "$SERVICE_TEMP" > "$SERVICE_RENDERED" + +if [ "$FOUND_EXEC_START" -ne 1 ]; then + echo "ERROR: ExecStart line not found in $SERVICE_TEMPLATE" >&2 + exit 1 +fi +if [ "$FOUND_NTFY" -ne 1 ]; then + echo "ERROR: NOTIFY_NTFY placeholder not found in $SERVICE_TEMPLATE" >&2 + exit 1 +fi +if [ "$FOUND_PHONE" -ne 1 ]; then + echo "ERROR: NOTIFY_PHONE placeholder not found in $SERVICE_TEMPLATE" >&2 + exit 1 +fi + +mv "$SERVICE_RENDERED" "$SERVICE_TEMP" + +mv "$SERVICE_TEMP" "$SERVICE_TARGET" +trap - EXIT +cp "$SCRIPT_DIR/systemd/openclaw-auth-monitor.timer" "$TIMER_TARGET" systemctl --user daemon-reload systemctl --user enable --now openclaw-auth-monitor.timer diff --git a/scripts/test-projects.test-support.mjs b/scripts/test-projects.test-support.mjs index 812d77af963..9aac139de4d 100644 --- a/scripts/test-projects.test-support.mjs +++ b/scripts/test-projects.test-support.mjs @@ -723,6 +723,7 @@ const TOOLING_SOURCE_TEST_TARGETS = new Map([ ["scripts/run-oxlint-shards.mjs", ["test/scripts/run-oxlint.test.ts"]], ["scripts/run-with-env.mjs", ["test/scripts/run-with-env.test.ts"]], ["scripts/run-node.mjs", ["src/infra/run-node.test.ts"]], + ["scripts/setup-auth-system.sh", ["test/scripts/test-projects.test.ts"]], ["scripts/ci-run-timings.mjs", ["test/scripts/ci-run-timings.test.ts"]], ["scripts/docker-e2e.mjs", ["test/scripts/docker-e2e-helper-cli.test.ts"]], ["scripts/docker-e2e-rerun.mjs", ["test/scripts/docker-e2e-helper-cli.test.ts"]], diff --git a/src/scripts/test-projects.test.ts b/src/scripts/test-projects.test.ts index f616d797f65..2de417f174a 100644 --- a/src/scripts/test-projects.test.ts +++ b/src/scripts/test-projects.test.ts @@ -1011,6 +1011,25 @@ describe("test-projects args", () => { ).toStrictEqual([]); }); + it("routes auth setup script changes to the focused tooling planner test", () => { + const changedPaths = ["scripts/setup-auth-system.sh"]; + + expect(resolveChangedTestTargetPlan(changedPaths)).toEqual({ + mode: "targets", + targets: ["test/scripts/test-projects.test.ts"], + }); + expect( + buildVitestRunPlans(["--changed=origin/main"], process.cwd(), () => changedPaths), + ).toEqual([ + { + config: "test/vitest/vitest.tooling.config.ts", + forwardedArgs: [], + includePatterns: ["test/scripts/test-projects.test.ts"], + watchMode: false, + }, + ]); + }); + it("keeps core test-only changes on their owning test lane", () => { const changedPaths = ["src/auto-reply/reply/commands-approve.test.ts"];