From 3cc32708d94ad3b21851d29a5e356ef6421146cd Mon Sep 17 00:00:00 2001 From: inference-bot Date: Tue, 3 Nov 2026 19:47:06 +0000 Subject: [PATCH] docs site: deploy from a dedicated clean clone; poll against last deployed commit - docs-deploy-poll.service and the receiver now build from /home/ubuntu/.docs-publisher, so uncommitted edits in a working clone can never block a deploy - the poller compares origin/main against the last DEPLOYED commit (state file), so a push made from the deploy clone itself also triggers a deploy --- publishing/README.md | 5 +++++ publishing/docs-deploy-poll.service | 5 +++-- publishing/poll-watcher.sh | 14 +++++++++----- publishing/webhook-receiver.service | 5 +++-- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/publishing/README.md b/publishing/README.md index ac2b2bd..1b006d6 100644 --- a/publishing/README.md +++ b/publishing/README.md @@ -59,6 +59,11 @@ about a minute, with no human action. The Gitea webhook alone was not enough because the agent host's cloud firewall only admits inbound SSH — a webhook POST is silently dropped — while outbound access to Gitea works. +The service builds from a **dedicated clean clone** at +`/home/ubuntu/.docs-publisher`, not from anyone's working copy, so uncommitted +edits in a working clone can never block a deploy. Edit, commit, push — that +is the whole deployment story. + **Webhook (wired, waiting on one port).** A Gitea webhook is registered on `co-op/docs` (push events, branch `main`) pointing at the receiver below. The moment the Infomaniak panel allows inbound TCP to the agent host — port 8787 diff --git a/publishing/docs-deploy-poll.service b/publishing/docs-deploy-poll.service index 8740b4b..42ab8d6 100644 --- a/publishing/docs-deploy-poll.service +++ b/publishing/docs-deploy-poll.service @@ -26,8 +26,9 @@ Wants=network-online.target [Service] User=ubuntu -WorkingDirectory=/home/ubuntu/repos/docs -ExecStart=/bin/bash /home/ubuntu/repos/docs/publishing/poll-watcher.sh +WorkingDirectory=/home/ubuntu/.docs-publisher +Environment=DOCS_REPO_DIR=/home/ubuntu/.docs-publisher +ExecStart=/bin/bash /home/ubuntu/.docs-publisher/publishing/poll-watcher.sh Restart=on-failure RestartSec=10 diff --git a/publishing/poll-watcher.sh b/publishing/poll-watcher.sh index 81b2efc..81af52a 100755 --- a/publishing/poll-watcher.sh +++ b/publishing/poll-watcher.sh @@ -19,6 +19,7 @@ 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" @@ -43,11 +44,13 @@ while true; do continue fi - LOCAL="$(git rev-parse HEAD 2>/dev/null || echo none)" 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 [ "$LOCAL" != "$REMOTE" ]; then - log "main moved: $LOCAL -> $REMOTE; deploying" + 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 @@ -56,9 +59,10 @@ while true; do bash publishing/build.sh bash publishing/deploy.sh ' _ "$REPO_DIR" >>"$LOG_FILE" 2>&1; then - log "deploy finished for $REMOTE" + printf '%s\n' "$REMOTE" > "$STATE_FILE" + log "deploy finished for ${REMOTE:0:12}" else - log "deploy FAILED for $REMOTE (see log above)" + log "deploy FAILED for ${REMOTE:0:12} (see log above)" fi fi diff --git a/publishing/webhook-receiver.service b/publishing/webhook-receiver.service index 4ce08b4..a97a2c9 100644 --- a/publishing/webhook-receiver.service +++ b/publishing/webhook-receiver.service @@ -15,12 +15,13 @@ Wants=network-online.target [Service] User=ubuntu -WorkingDirectory=/home/ubuntu/repos/docs +WorkingDirectory=/home/ubuntu/.docs-publisher +Environment=DOCS_REPO_DIR=/home/ubuntu/.docs-publisher ExecStartPre=+/bin/sh -c '/usr/sbin/iptables -C INPUT -i lo -p tcp --dport 8787 -j ACCEPT 2>/dev/null || /usr/sbin/iptables -I INPUT 1 -i lo -p tcp --dport 8787 -j ACCEPT' ExecStartPre=+/bin/sh -c '/usr/sbin/iptables -C INPUT -p tcp --dport 8787 -s 179.237.86.116 -j ACCEPT 2>/dev/null || /usr/sbin/iptables -I INPUT 2 -p tcp --dport 8787 -s 179.237.86.116 -j ACCEPT' ExecStartPre=+/bin/sh -c '/usr/sbin/iptables -C INPUT -p tcp --dport 8787 ! -s 179.237.86.116 -j DROP 2>/dev/null || /usr/sbin/iptables -I INPUT 3 -p tcp --dport 8787 ! -s 179.237.86.116 -j DROP' ExecStartPre=+/bin/sh -c '/usr/sbin/ip6tables -C INPUT -p tcp --dport 8787 -j DROP 2>/dev/null || /usr/sbin/ip6tables -I INPUT -p tcp --dport 8787 -j DROP' -ExecStart=/home/ubuntu/repos/docs/.venv-docs/bin/python /home/ubuntu/repos/docs/publishing/webhook-receiver.py +ExecStart=/home/ubuntu/.docs-publisher/.venv-docs/bin/python /home/ubuntu/.docs-publisher/publishing/webhook-receiver.py Restart=on-failure RestartSec=5