#!/usr/bin/env bash # Test, build, and swap the Go MCP binary on ns1. # Does not restart verae-timestamping-svc or forgejo-runner, and does not read secret files. set -euo pipefail LOCK="${LOCK:-/tmp/verae-mcp-go-deploy.lock}" DEST="${DEST:-/opt/verae/verae-mcp-timestamping-server-go/bin/verae-mcp-timestamping-server}" SERVICE="${SERVICE:-verae-mcp-timestamping.service}" PROBE="${PROBE:-http://127.0.0.1:8000/mcp}" GO_ROOT="${GO_ROOT:-/usr/local/lib/go1.26.9}" GO_TARBALL="${GO_TARBALL:-go1.26.9.linux-amd64.tar.gz}" GO_SHA256="${GO_SHA256:-42d158b4d8f7b61ac0a830567c940a86098fb7aac52e467a5ebec03ef5cc2f8d}" ROOT="$(cd "$(dirname "$0")/.." && pwd)" mkdir -p "$(dirname "$LOCK")" exec 9>"$LOCK" if ! flock -n 9; then echo "another mcp deploy holds the lock" >&2 exit 1 fi ensure_go() { if [[ -x "$GO_ROOT/bin/go" ]] && "$GO_ROOT/bin/go" version | grep -q 'go1.26.9 '; then export PATH="$GO_ROOT/bin:$PATH" return fi local tmp tmp="$(mktemp -d)" curl -fsSL -o "$tmp/go.tgz" "https://go.dev/dl/${GO_TARBALL}" echo "${GO_SHA256} ${tmp}/go.tgz" | sha256sum -c - tar -C "$tmp" -xzf "$tmp/go.tgz" sudo rm -rf "$GO_ROOT" sudo mv "$tmp/go" "$GO_ROOT" rm -rf "$tmp" export PATH="$GO_ROOT/bin:$PATH" } probe_ok() { local code code="$(curl -s -o /dev/null -w '%{http_code}' --max-time 5 "$PROBE" || true)" [[ -n "$code" && "$code" != "000" ]] } wait_probe() { local i for i in 1 2 3 4 5 6 7 8; do if probe_ok; then return 0 fi sleep 1 done return 1 } swap_binary() { local src="$1" sudo systemctl stop "$SERVICE" || true local n=0 while (( n < 5 )); do if sudo cp "$src" "$DEST"; then sudo chown verae-mcp:verae-mcp "$DEST" sudo chmod 755 "$DEST" sudo systemctl start "$SERVICE" return 0 fi n=$((n + 1)) sleep 1 sudo systemctl stop "$SERVICE" || true done echo "could not replace $DEST" >&2 sudo systemctl start "$SERVICE" || true return 1 } rollback() { local latest latest="$(ls -1t "${DEST}.bak-"* 2>/dev/null | head -1 || true)" if [[ -z "$latest" ]]; then echo "no backup to roll back to" >&2 sudo systemctl start "$SERVICE" || true exit 1 fi swap_binary "$latest" if wait_probe; then echo "rolled back to $latest (probe ok)" return 0 fi echo "rollback probe still failing" >&2 return 1 } if [[ "${1:-}" == "--rollback" ]]; then rollback exit $? fi ensure_go cd "$ROOT" go test ./... -count=1 go build -o /tmp/verae-mcp-timestamping-server-new ./cmd/verae-mcp-timestamping-server if ! grep -a -q 'verae-meta-git/1' /tmp/verae-mcp-timestamping-server-new; then echo "built binary is missing verae-meta-git/1" >&2 exit 1 fi if [[ "${1:-}" == "--test-only" ]]; then echo "tests ok" exit 0 fi ts="$(date -u +%Y%m%dT%H%M%SZ)" sudo cp -a "$DEST" "${DEST}.bak-${ts}" if ! swap_binary /tmp/verae-mcp-timestamping-server-new; then rollback || true exit 1 fi if ! wait_probe; then echo "new binary failed probe; rolling back" >&2 rollback || true exit 1 fi echo "deployed ${ts} probe ok"