#!/usr/bin/env bash # Release the independently versioned native imgproxy runtime (vendor binary) to 103. set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" HOST="${STUDIO_HOST:-john@58.38.22.103}" REMOTE_ROOT="${STUDIO_REMOTE_ROOT:-/Users/john/Project}" RUNTIME_BASE="${REMOTE_ROOT}/imgproxy-runtime" INCOMING="${REMOTE_ROOT}/incoming/imgproxy-runtime" RELEASE_ID="$(date +%Y%m%d-%H%M%S)-$(git -C "$ROOT" rev-parse --short HEAD)" TMP="$(mktemp -d "${TMPDIR:-/tmp}/imgproxy-native-release.XXXXXX")" DRY_RUN=0 cleanup() { rm -rf "$TMP"; } trap cleanup EXIT while [[ $# -gt 0 ]]; do case "$1" in --dry-run) DRY_RUN=1 ;; -h|--help) cat <<'EOF' Usage: bash scripts/release-imgproxy-native-prod.sh [--dry-run] Builds and installs the vendor imgproxy runtime on 103. Portal runtime is unchanged. EOF exit 0 ;; *) echo "unknown argument: $1" >&2 exit 1 ;; esac shift done git -C "$ROOT" fetch origin main --quiet branch="$(git -C "$ROOT" branch --show-current)" [[ "$branch" == release/* ]] || { echo 'imgproxy native production release must run from a release/* branch' >&2; exit 1; } [[ -z "$(git -C "$ROOT" status --porcelain)" ]] || { echo 'worktree must be clean' >&2; exit 1; } [[ "$(git -C "$ROOT" rev-parse HEAD)" == "$(git -C "$ROOT" rev-parse origin/main)" ]] || { echo 'main must match origin/main' >&2 exit 1 } bash "$ROOT/scripts/check-release-ready.sh" bash "$ROOT/scripts/build-imgproxy-runtime-native.sh" RUNTIME_DIR="$ROOT/.runtime/imgproxy-native" for file in \ vendor/imgproxy-runtime/bin/imgproxy \ vendor/imgproxy-runtime/SHA256SUMS \ vendor/imgproxy-runtime/VERSION.txt \ scripts/install-imgproxy-native-prod.sh \ imgproxy-compat-proxy.mjs \ RUNBOOK.txt; do [[ -f "$RUNTIME_DIR/$file" ]] || { echo "missing runtime artifact: $file" >&2; exit 1; } done MANIFEST="$TMP/release-manifest.txt" { echo "release_id=${RELEASE_ID}" echo "git_head=$(git -C "$ROOT" rev-parse HEAD)" echo "imgproxy_version=$(cat "$RUNTIME_DIR/vendor/imgproxy-runtime/VERSION.txt")" echo "runtime_mode=native-vendor" } > "$MANIFEST" mkdir -p "$TMP/runtime" cp -R "$RUNTIME_DIR/." "$TMP/runtime/" cp "$MANIFEST" "$TMP/runtime/" tar -C "$TMP" -czf "$TMP/imgproxy-native-runtime-$RELEASE_ID.tar.gz" runtime (cd "$TMP" && shasum -a 256 "imgproxy-native-runtime-$RELEASE_ID.tar.gz" > "imgproxy-native-runtime-$RELEASE_ID.tar.gz.sha256") if [[ "$DRY_RUN" == 1 ]]; then shasum -a 256 -c "$TMP/imgproxy-native-runtime-$RELEASE_ID.tar.gz.sha256" echo "imgproxy native dry-run artifact verified: $TMP/imgproxy-native-runtime-$RELEASE_ID.tar.gz" exit 0 fi ssh -o BatchMode=yes "$HOST" "mkdir -p '$INCOMING' '$RUNTIME_BASE/releases' '$RUNTIME_BASE/backups'" scp -q "$TMP/imgproxy-native-runtime-$RELEASE_ID.tar.gz" "$TMP/imgproxy-native-runtime-$RELEASE_ID.tar.gz.sha256" "$HOST:$INCOMING/" ssh -o BatchMode=yes "$HOST" "RELEASE_ID='$RELEASE_ID' RUNTIME_BASE='$RUNTIME_BASE' INCOMING='$INCOMING' bash -s" <<'REMOTE' set -euo pipefail archive="$INCOMING/imgproxy-native-runtime-$RELEASE_ID.tar.gz" sha="$archive.sha256" release_dir="$RUNTIME_BASE/releases/$RELEASE_ID" backup_dir="$RUNTIME_BASE/backups/$RELEASE_ID" current_link="$RUNTIME_BASE/current" previous_target="$(readlink "$current_link" 2>/dev/null || true)" mkdir -p "$release_dir" "$backup_dir" cp "$HOME/Library/LaunchAgents/cn.tkmind.imgproxy.plist" "$backup_dir/imgproxy.plist" 2>/dev/null || true cp "$HOME/Library/LaunchAgents/cn.tkmind.imgproxy-compat.plist" "$backup_dir/imgproxy-compat.plist" 2>/dev/null || true cd "$INCOMING" shasum -a 256 -c "$sha" tar -xzf "$archive" -C "$release_dir" --strip-components=1 rollback() { launchctl bootout "gui/$(id -u)/cn.tkmind.imgproxy" >/dev/null 2>&1 || true launchctl bootout "gui/$(id -u)/cn.tkmind.imgproxy-compat" >/dev/null 2>&1 || true if [[ -n "$previous_target" && -d "$previous_target" ]]; then ln -sfn "$previous_target" "$current_link" else rm -f "$current_link" fi if [[ -f "$backup_dir/imgproxy.plist" ]]; then cp "$backup_dir/imgproxy.plist" "$HOME/Library/LaunchAgents/cn.tkmind.imgproxy.plist" launchctl bootstrap "gui/$(id -u)" "$HOME/Library/LaunchAgents/cn.tkmind.imgproxy.plist" >/dev/null 2>&1 || true fi if [[ -f "$backup_dir/imgproxy-compat.plist" ]]; then cp "$backup_dir/imgproxy-compat.plist" "$HOME/Library/LaunchAgents/cn.tkmind.imgproxy-compat.plist" launchctl bootstrap "gui/$(id -u)" "$HOME/Library/LaunchAgents/cn.tkmind.imgproxy-compat.plist" >/dev/null 2>&1 || true fi } trap rollback ERR IMGPROXY_RUNTIME_DIR="$release_dir" bash "$release_dir/scripts/install-imgproxy-native-prod.sh" ln -sfn "$release_dir" "$current_link" curl -fsS --max-time 5 http://127.0.0.1:20082/health >/dev/null curl -fsS --max-time 5 http://10.10.0.2:20081/health >/dev/null trap - ERR printf '%s\n' "$RELEASE_ID" > "$RUNTIME_BASE/current-release.txt" REMOTE curl -kfsS --max-time 15 https://img.tkmind.cn/health >/dev/null printf 'imgproxy native release verified: %s\n' "$RELEASE_ID"