#!/usr/bin/env bash # Poll Gitea for new commits on main and deploy the docs site when it moves. # # Why polling: the agent host's cloud firewall only admits inbound SSH, so a # Gitea webhook cannot reach the receiver (publishing/webhook-receiver.py) — # every port is silently dropped. Outbound to git.inference.coop works, so the # agent host polls instead: a push to main is picked up within ~a minute and # deployed with no human action. When the operator opens a TCP port to the # agent host in the Infomaniak panel, the webhook takes over (its unit is # already installed); until then this watcher is the automation. # # Runs on the agent host as a systemd service (docs-deploy-poll.service). # Deploy steps are serialised with the same lock the webhook receiver uses, so # the two mechanisms can never deploy concurrently. set -uo pipefail REPO_DIR="${DOCS_REPO_DIR:-/home/ubuntu/repos/docs}" ENV_FILE="${DOCS_ENV_FILE:-/home/ubuntu/.hermes/.env}" LOG_FILE="${DOCS_DEPLOY_LOG:-/home/ubuntu/docs-deploy.log}" LOCK_FILE="${DOCS_DEPLOY_LOCK:-/home/ubuntu/.docs-deploy.lock}" STATE_FILE="${DOCS_DEPLOY_STATE:-/home/ubuntu/.docs-deploy.state}" INTERVAL="${DOCS_POLL_INTERVAL:-60}" cd "$REPO_DIR" log() { echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) [poll] $*" | tee -a "$LOG_FILE" >&2; } # The Cloudron token travels by environment only; it is read from the env file # and never echoed. CLOUDRON_TOKEN="$(sed -n 's/^CLOUDRON_TOKEN=//p' "$ENV_FILE" | head -1 | tr -d '"' | tr -d "'")" export CLOUDRON_TOKEN if [ -z "$CLOUDRON_TOKEN" ]; then log "FATAL: CLOUDRON_TOKEN not found in $ENV_FILE" exit 1 fi log "watcher started: polling $REPO_DIR every ${INTERVAL}s" while true; do if ! git fetch --quiet origin main 2>>"$LOG_FILE"; then log "git fetch failed; will retry" sleep "$INTERVAL" continue fi REMOTE="$(git rev-parse origin/main 2>/dev/null || echo none)" # Compare against the commit last DEPLOYED (not the clone's HEAD): a push # made from this very clone would otherwise look like "no change". LAST_DEPLOYED="$(cat "$STATE_FILE" 2>/dev/null || echo none)" if [ "$LAST_DEPLOYED" != "$REMOTE" ]; then log "main moved: ${LAST_DEPLOYED:0:12} -> ${REMOTE:0:12}; deploying" # flock -n shares the receiver's lock: one deploy at a time, ever. if flock -n "$LOCK_FILE" bash -c ' set -e cd "$1" git pull --ff-only origin main bash publishing/build.sh bash publishing/deploy.sh ' _ "$REPO_DIR" >>"$LOG_FILE" 2>&1; then printf '%s\n' "$REMOTE" > "$STATE_FILE" log "deploy finished for ${REMOTE:0:12}" else log "deploy FAILED for ${REMOTE:0:12} (see log above)" fi fi sleep "$INTERVAL" done