diff --git a/README.md b/README.md index cc2b17e..238c748 100644 --- a/README.md +++ b/README.md @@ -469,12 +469,19 @@ stable — promotion is always this explicit step. ### Build trigger and the build host -Release commands run from anywhere. When the machine you are on **is** the -build host (detected by the published database living in this checkout), host -operations — build triggers, `advance`, promotion — execute locally. From any -other machine they go over ssh to the configured host; without a configured -host, the exact commands to run are printed and the 6-hourly auto-release -timer serves as the backstop. +Release commands run from anywhere. `bin/repo` is a **remote control**: with a +repository host configured, every command that operates on the published tree +(`release`, `build`, `sign`, `promote`, `update`, `clean`, `advance`, +`bootstrap-rc`, `remove`, `sync`, `migrate`) executes ON the host over ssh — +the exact same code, run where the tree lives, so ssh'ing in and running the +same commands by hand behaves identically. Pass `--local` to force execution +on the current machine. `list`, `push`, `deploy`, and `setup` never forward +(`push`/`deploy` exist precisely to move local builds *to* the host). + +Without a configured host, commands run locally — which on the build host +itself (no `.repo-host` there) is exactly right, and elsewhere the exact +commands to run are printed by the orchestrator, with the 6-hourly +auto-release timer as the backstop. The host setting is any destination `ssh` accepts, resolved in this order: diff --git a/bin/omarchy-release b/bin/omarchy-release index 3fe7357..eb9df6f 100755 --- a/bin/omarchy-release +++ b/bin/omarchy-release @@ -261,20 +261,16 @@ trigger_rc_build() { host_advance() { # host_advance [extra args...] local from="$1" to="$2" shift 2 - local host - if host=$(repo_host); then - print_info "Advancing $from -> $to on $host..." - ssh "$host" "cd /root/omarchy-pkgs && git pull --ff-only && bin/repo advance --from $from --to $to --skip-prod-check $*" - elif on_repo_host; then - # This checkout holds the published tree — advance right here, from this - # checkout's tooling (no pull: the operator controls their working copy). - print_info "Advancing $from -> $to locally (this is the build host)..." - "$BUILD_ROOT/bin/repo" advance --from "$from" --to "$to" --skip-prod-check "$@" - else + # bin/repo is the remote control: with a host configured it forwards this + # over ssh itself; on the host it runs locally. Only the "neither" case — + # a workstation with no host — must be refused here, because running it + # against this machine's (likely stale) local tree would be wrong. + if ! resolve_repo_host "$REPO_HOST_OVERRIDE" >/dev/null && ! on_repo_host; then print_no_host_help "advance $from -> $to" \ " cd /root/omarchy-pkgs && bin/repo advance --from $from --to $to --skip-prod-check $*" return 1 fi + "$BUILD_ROOT/bin/repo" advance --from "$from" --to "$to" --skip-prod-check "$@" } wait_for_published() { # wait_for_published [timeout-seconds] @@ -1026,7 +1022,11 @@ ARGS=() while [[ $# -gt 0 ]]; do case $1 in --yes) ASSUME_YES=true; shift ;; - --host) REPO_HOST_OVERRIDE="$2"; shift 2 ;; + --host) + REPO_HOST_OVERRIDE="$2" + export OMARCHY_REPO_HOST="$2" # child bin/repo invocations forward to it too + shift 2 + ;; --iso) ISO_MODE="yes"; shift ;; --no-iso) ISO_MODE="no"; shift ;; --no-wait) WAIT=false; shift ;; diff --git a/bin/repo b/bin/repo index b195447..c9d4b49 100755 --- a/bin/repo +++ b/bin/repo @@ -11,6 +11,52 @@ BUILD_ROOT=$(realpath "$SCRIPT_DIR/..") # Source common functions source "$BUILD_ROOT/helpers/message-helpers.sh" source "$BUILD_ROOT/helpers/paths.sh" +source "$BUILD_ROOT/helpers/host-helpers.sh" + +# --- remote control ---------------------------------------------------------- +# +# With a repository host configured (OMARCHY_REPO_HOST or .repo-host), commands +# that operate on the published tree run ON the host over ssh — the exact same +# code, executed where the tree lives. This checkout is the remote control. +# Pass --local to force local execution. The host itself configures no +# .repo-host, so on it every command runs locally, ssh'd in or not. +# +# Local-machine workflows (list, push, deploy, setup) never forward: push and +# deploy exist precisely to move local builds TO the host. +FORWARDABLE=" release build sign promote update clean migrate advance bootstrap-rc remove sync " + +LOCAL_OVERRIDE=false +STRIPPED_ARGS=() +for arg in "$@"; do + if [[ "$arg" == "--local" ]]; then + LOCAL_OVERRIDE=true + else + STRIPPED_ARGS+=("$arg") + fi +done +set -- "${STRIPPED_ARGS[@]}" + +maybe_forward_to_host() { + local cmd="${1:-}" + shift || true + [[ "$LOCAL_OVERRIDE" == true ]] && return 0 + [[ "$FORWARDABLE" == *" $cmd "* ]] || return 0 + local host + host=$(resolve_repo_host "") || return 0 + + local quoted="" a + for a in "$@"; do quoted+=" $(printf '%q' "$a")"; done + + # A tty makes the remote confirmation prompts (production sync, etc.) work; + # without one locally, run non-interactively. + local tty_flag="" + [[ -t 0 && -t 1 ]] && tty_flag="-t" + + print_info "Repository host configured — running on $host (pass --local to run here)" + exec ssh $tty_flag "$host" "source /root/.omarchy/build-credentials 2>/dev/null; cd /root/omarchy-pkgs && git pull --ff-only && exec bin/repo $cmd$quoted" +} + +maybe_forward_to_host "$@" # Extract mirror from arguments for log naming (before args are shifted) LOG_MIRROR="" @@ -74,6 +120,11 @@ show_usage() { echo " $0 update" echo " $0 sync pkgs.omarchy.org/x86_64" echo "" + echo "Remote control: when a repository host is configured (OMARCHY_REPO_HOST" + echo "or .repo-host — any ssh destination), the commands above except list," + echo "push, deploy, and setup run ON the host over ssh. Pass --local to force" + echo "execution on this machine instead." + echo "" echo "For command-specific help, use:" echo " $0 --help" exit 0