#!/bin/bash # Meta command for Omarchy repository management # Usage: ./bin/repo [options] set -e # Get the directory of this script SCRIPT_DIR=$(realpath "${BASH_SOURCE[0]%/*}") 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 timers " 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="" for ((i=1; i<=$#; i++)); do if [[ "${!i}" == "--mirror" ]]; then next=$((i+1)) LOG_MIRROR="${!next}" break fi done # Setup logging with timestamps mkdir -p "$LOG_DIR" # Rotate logs first - keep only the 10 most recent if [[ -d "$LOG_DIR" ]]; then cd "$LOG_DIR" # List logs by modification time (newest first), skip first 9, delete the rest # This way after we create the new log, we'll have exactly 10 ls -t repo_*.log 2>/dev/null | tail -n +10 | xargs -r rm -f cd "$BUILD_ROOT" fi TIMESTAMP=$(date +%Y%m%d_%H%M%S) if [[ -n "$LOG_MIRROR" ]]; then LOG_FILE="$LOG_DIR/repo_${LOG_MIRROR}_${TIMESTAMP}.log" else LOG_FILE="$LOG_DIR/repo_${TIMESTAMP}.log" fi export LOG_FILE export OMARCHY_LOG_FILE="$LOG_FILE" # Show usage show_usage() { echo "Usage: $0 [options]" echo "" echo "Commands:" echo " release Run complete workflow: build → sign → promote → clean → update → sync" echo " build Build packages (unsigned)" echo " sign Sign all packages in build-output" echo " promote Promote build to production (build-output → pkgs.omarchy.org)" echo " update Update repository database" echo " clean Clean old package versions" echo " advance Move packages forward through the pipeline (edge → rc → stable)" echo " bootstrap-rc One-time seed of the rc channel from stable" echo " migrate DEPRECATED alias for 'advance --from edge --to stable'" echo " list List source package metadata (use --repo for published repo)" echo " remove Remove a specific package" echo " sync Sync repository to remote" echo " push Upload local builds to the repository host and publish them there" echo " deploy Build locally, then push: one command from a build machine" echo " setup Install everything the repository host needs" echo " timers Show release timer schedule, last runs, and queued builds" echo "" echo "Typical workflows:" echo " $0 release # Complete release workflow" echo "" echo " $0 build # Manual step-by-step:" echo " $0 sign" echo " $0 promote" echo " $0 clean" 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 } # Check if no command provided if [[ $# -eq 0 ]]; then show_usage fi # Get command and shift arguments COMMAND="$1" shift # Route to appropriate script with logging case $COMMAND in release) "$SCRIPT_DIR/release" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; build) "$SCRIPT_DIR/build" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; sign) "$SCRIPT_DIR/sign" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; promote) "$SCRIPT_DIR/promote-build" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; update) "$SCRIPT_DIR/update-repo" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; clean) "$SCRIPT_DIR/clean-repo" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; advance) "$SCRIPT_DIR/advance-channel" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; bootstrap-rc) "$SCRIPT_DIR/advance-channel" --from stable --to rc --bootstrap "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; migrate) print_warning "'migrate' is deprecated; releases now flow edge → rc → stable (bin/repo advance)" "$SCRIPT_DIR/advance-channel" --from edge --to stable "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; list) "$SCRIPT_DIR/list-packages" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; remove) "$SCRIPT_DIR/remove-package" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; sync) "$SCRIPT_DIR/sync-repo" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; push) "$SCRIPT_DIR/push-build" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; deploy) "$SCRIPT_DIR/deploy" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; setup) "$SCRIPT_DIR/setup" "$@" 2>&1 | tee "$LOG_FILE" exit ${PIPESTATUS[0]} ;; timers) # Status output, not a build step: show it, do not log it. "$SCRIPT_DIR/timers" "$@" exit $? ;; -h | --help | help) show_usage ;; *) print_error "Unknown command: $COMMAND" echo "" show_usage ;; esac