Files
wz-phone/scripts/build-linux.sh
Siavash Sameni 59268f0391 fix: add libssl-dev to Linux build deps (openssl-sys needs it)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:00:20 +04:00

244 lines
7.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Build WarzonePhone Linux x86_64 release binaries using a Hetzner Cloud VPS.
# Prerequisites: hcloud CLI authenticated, SSH key "wz" registered.
#
# Usage:
# ./scripts/build-linux.sh --prepare Create VM, install deps, upload source
# ./scripts/build-linux.sh --build Build release binaries on the VM
# ./scripts/build-linux.sh --transfer Download binaries from VM to local
# ./scripts/build-linux.sh --destroy Delete the VM
# ./scripts/build-linux.sh --all Run prepare + build + transfer (no destroy)
#
# The VM persists between steps so you can iterate on build errors.
SSH_KEY_NAME="wz"
SSH_KEY_PATH="/Users/manwe/CascadeProjects/wzp"
SERVER_TYPE="cx33"
IMAGE="debian-12"
REMOTE_USER="root"
OUTPUT_DIR="target/linux-x86_64"
PROJECT_DIR="/Users/manwe/CascadeProjects/warzonePhone"
SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=10"
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
get_vm_ip() {
local ip
ip=$(hcloud server list -o columns=ipv4 -o noheader 2>/dev/null | tail -1 | tr -d ' ')
if [ -z "$ip" ]; then
echo "ERROR: No Hetzner VM found. Run --prepare first." >&2
exit 1
fi
echo "$ip"
}
ssh_cmd() {
local ip
ip=$(get_vm_ip)
ssh $SSH_OPTS -i "$SSH_KEY_PATH" "$REMOTE_USER@$ip" "$@"
}
scp_cmd() {
local ip
ip=$(get_vm_ip)
scp $SSH_OPTS -i "$SSH_KEY_PATH" "$@"
}
get_vm_name() {
hcloud server list -o columns=name -o noheader 2>/dev/null | tail -1 | tr -d ' '
}
# ---------------------------------------------------------------------------
# --prepare: Create VM, install deps, upload source
# ---------------------------------------------------------------------------
do_prepare() {
local server_name="wzp-builder"
# Check if VM already exists
local existing
existing=$(hcloud server list -o columns=name -o noheader 2>/dev/null | grep wzp-builder || true)
if [ -n "$existing" ]; then
echo "VM already exists: $existing"
echo "Reusing it. Uploading fresh source..."
do_upload
return
fi
echo "[1/5] Creating Hetzner VM..."
hcloud server create \
--name "$server_name" \
--type "$SERVER_TYPE" \
--image "$IMAGE" \
--ssh-key "$SSH_KEY_NAME" \
--location fsn1 \
--quiet
local ip
ip=$(get_vm_ip)
echo " VM: $server_name @ $ip"
# Wait for SSH
echo "[2/5] Waiting for SSH..."
for i in $(seq 1 30); do
if ssh $SSH_OPTS -i "$SSH_KEY_PATH" "$REMOTE_USER@$ip" "echo ok" &>/dev/null; then
break
fi
sleep 2
done
# Install build dependencies
echo "[3/5] Installing build dependencies..."
ssh_cmd "apt-get update -qq && apt-get install -y -qq build-essential cmake pkg-config libasound2-dev libssl-dev curl git libstdc++-12-dev > /dev/null 2>&1"
# Install Rust
echo "[4/5] Installing Rust..."
ssh_cmd "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable > /dev/null 2>&1"
# Upload source
echo "[5/5] Uploading source code..."
do_upload
echo ""
echo "=== VM Ready ==="
echo "IP: $ip"
echo "SSH: ssh -i $SSH_KEY_PATH root@$ip"
echo ""
echo "Next: ./scripts/build-linux.sh --build"
}
do_upload() {
echo " Creating source tarball..."
tar czf /tmp/wzp-src.tar.gz \
--exclude='target' \
--exclude='.git' \
--exclude='.claude' \
--exclude='notes' \
-C "$PROJECT_DIR" . 2>/dev/null
local ip
ip=$(get_vm_ip)
echo " Uploading to VM..."
scp $SSH_OPTS -i "$SSH_KEY_PATH" /tmp/wzp-src.tar.gz "$REMOTE_USER@$ip:/root/wzp-src.tar.gz" 2>/dev/null
ssh_cmd "rm -rf /root/warzonePhone && mkdir -p /root/warzonePhone && tar xzf /root/wzp-src.tar.gz -C /root/warzonePhone" 2>/dev/null
rm -f /tmp/wzp-src.tar.gz
echo " Source uploaded."
}
# ---------------------------------------------------------------------------
# --build: Build release binaries on the VM
# ---------------------------------------------------------------------------
do_build() {
local ip
ip=$(get_vm_ip)
echo "=== Building on $ip ==="
echo "[1/3] Building relay + client + web..."
ssh_cmd "source ~/.cargo/env && cd /root/warzonePhone && cargo build --release --bin wzp-relay --bin wzp-client --bin wzp-bench --bin wzp-web 2>&1"
echo ""
echo "[2/3] Building audio-enabled client..."
ssh_cmd "source ~/.cargo/env && cd /root/warzonePhone && cargo build --release --bin wzp-client --features audio 2>&1" | tail -5
ssh_cmd "cp /root/warzonePhone/target/release/wzp-client /root/warzonePhone/target/release/wzp-client-audio"
ssh_cmd "source ~/.cargo/env && cd /root/warzonePhone && cargo build --release --bin wzp-client 2>&1" | tail -3
echo ""
echo "[3/3] Verifying binaries..."
ssh_cmd "ls -lh /root/warzonePhone/target/release/wzp-relay /root/warzonePhone/target/release/wzp-client /root/warzonePhone/target/release/wzp-web /root/warzonePhone/target/release/wzp-bench /root/warzonePhone/target/release/wzp-client-audio"
echo ""
echo "=== Build Complete ==="
echo "Next: ./scripts/build-linux.sh --transfer"
}
# ---------------------------------------------------------------------------
# --transfer: Download binaries from VM to local
# ---------------------------------------------------------------------------
do_transfer() {
local ip
ip=$(get_vm_ip)
echo "=== Downloading binaries from $ip ==="
mkdir -p "$OUTPUT_DIR/static"
for bin in wzp-relay wzp-client wzp-client-audio wzp-bench wzp-web; do
echo " $bin..."
scp $SSH_OPTS -i "$SSH_KEY_PATH" "$REMOTE_USER@$ip:/root/warzonePhone/target/release/$bin" "$OUTPUT_DIR/$bin" 2>/dev/null
done
# Static files for web bridge
scp $SSH_OPTS -i "$SSH_KEY_PATH" "$REMOTE_USER@$ip:/root/warzonePhone/crates/wzp-web/static/index.html" "$OUTPUT_DIR/static/index.html" 2>/dev/null
scp $SSH_OPTS -i "$SSH_KEY_PATH" "$REMOTE_USER@$ip:/root/warzonePhone/crates/wzp-web/static/audio-processor.js" "$OUTPUT_DIR/static/audio-processor.js" 2>/dev/null
echo ""
echo "=== Transfer Complete ==="
ls -lh "$OUTPUT_DIR"/wzp-*
echo ""
echo "Deploy with:"
echo " scp $OUTPUT_DIR/wzp-relay $OUTPUT_DIR/wzp-client user@server:~/wzp/"
}
# ---------------------------------------------------------------------------
# --destroy: Delete the VM
# ---------------------------------------------------------------------------
do_destroy() {
local name
name=$(get_vm_name)
if [ -z "$name" ]; then
echo "No VM to destroy."
return
fi
echo "Deleting VM: $name"
hcloud server delete "$name"
echo "Done."
}
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
case "${1:-}" in
--prepare)
do_prepare
;;
--build)
do_build
;;
--transfer)
do_transfer
;;
--destroy)
do_destroy
;;
--all)
do_prepare
do_build
do_transfer
echo ""
echo "VM is still running. Destroy with: ./scripts/build-linux.sh --destroy"
;;
--upload)
do_upload
;;
*)
echo "Usage: $0 {--prepare|--build|--transfer|--destroy|--all|--upload}"
echo ""
echo "Steps:"
echo " --prepare Create VM, install deps, upload source"
echo " --build Build release binaries (shows full output)"
echo " --transfer Download binaries to target/linux-x86_64/"
echo " --destroy Delete the VM"
echo " --all prepare + build + transfer (VM persists)"
echo " --upload Re-upload source to existing VM"
exit 1
;;
esac