teleo-codex/ops/auto-deploy.sh
m3taversal 5c8c92602f Remove 3 dead cron scripts replaced by pipeline-v2 daemon
- extract-cron.sh: replaced by lib/extract.py (disabled on VPS since v2 cutover)
- evaluate-trigger.sh: replaced by lib/evaluate.py + merge.py
- batch-extract-50.sh: replaced by pipeline daemon extraction stage
- Updated deploy scripts to stop referencing batch-extract-50.sh
- Updated deploy-manifest.md and schema-change-protocol.md references
- Broadened .gitignore __pycache__/ to cover all directories

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 17:12:04 +01:00

140 lines
4.1 KiB
Bash
Executable file

#!/usr/bin/env bash
# auto-deploy.sh — Pull from Forgejo, sync to working dirs, restart if needed.
# Runs as systemd timer (teleo-auto-deploy.timer) every 2 minutes.
# Exits silently when nothing has changed.
set -euo pipefail
LOCK_FILE="/tmp/teleo-auto-deploy.lock"
exec 9>"$LOCK_FILE"
if ! flock -n 9; then
logger -t "auto-deploy" "Another deploy is already running. Skipping."
exit 0
fi
DEPLOY_CHECKOUT="/opt/teleo-eval/workspaces/deploy"
PIPELINE_DIR="/opt/teleo-eval/pipeline"
DIAGNOSTICS_DIR="/opt/teleo-eval/diagnostics"
AGENT_STATE_DIR="/opt/teleo-eval/ops/agent-state"
STAMP_FILE="/opt/teleo-eval/.last-deploy-sha"
LOG_TAG="auto-deploy"
log() { logger -t "$LOG_TAG" "$1"; echo "$(date '+%Y-%m-%d %H:%M:%S') $1"; }
if [ ! -d "$DEPLOY_CHECKOUT/.git" ]; then
log "ERROR: Deploy checkout not found at $DEPLOY_CHECKOUT. Run setup first."
exit 1
fi
cd "$DEPLOY_CHECKOUT"
if ! git fetch origin main --quiet 2>&1; then
log "ERROR: git fetch failed"
exit 1
fi
NEW_SHA=$(git rev-parse origin/main)
OLD_SHA=$(cat "$STAMP_FILE" 2>/dev/null || echo "none")
if [ "$NEW_SHA" = "$OLD_SHA" ]; then
exit 0
fi
log "New commits: ${OLD_SHA:0:8} -> ${NEW_SHA:0:8}"
if ! git checkout main --quiet 2>&1; then
log "ERROR: git checkout main failed — dirty tree or corrupted index"
exit 1
fi
if ! git pull --ff-only --quiet 2>&1; then
log "ERROR: git pull --ff-only failed. Manual intervention needed."
exit 1
fi
# Syntax check all Python files before copying
ERRORS=0
for f in ops/pipeline-v2/lib/*.py ops/pipeline-v2/*.py ops/diagnostics/*.py; do
[ -f "$f" ] || continue
if ! python3 -c "import ast, sys; ast.parse(open(sys.argv[1]).read())" "$f" 2>&1; then
log "SYNTAX ERROR: $f"
ERRORS=$((ERRORS + 1))
fi
done
if [ "$ERRORS" -gt 0 ]; then
log "ERROR: $ERRORS syntax errors. Deploy aborted. Fix and push again."
exit 1
fi
log "Syntax check passed"
# Sync to working directories (mirrors deploy.sh logic)
RSYNC_FLAGS="-az --exclude='__pycache__' --exclude='*.pyc' --exclude='*.bak*'"
rsync $RSYNC_FLAGS ops/pipeline-v2/lib/ "$PIPELINE_DIR/lib/"
for f in teleo-pipeline.py reweave.py; do
[ -f "ops/pipeline-v2/$f" ] && rsync $RSYNC_FLAGS "ops/pipeline-v2/$f" "$PIPELINE_DIR/$f"
done
rsync $RSYNC_FLAGS ops/pipeline-v2/telegram/ "$PIPELINE_DIR/telegram/"
rsync $RSYNC_FLAGS ops/diagnostics/ "$DIAGNOSTICS_DIR/"
rsync $RSYNC_FLAGS ops/agent-state/ "$AGENT_STATE_DIR/"
[ -f ops/research-session.sh ] && rsync $RSYNC_FLAGS ops/research-session.sh /opt/teleo-eval/research-session.sh
log "Files synced"
# Restart services only if Python files changed
RESTART=""
if [ "$OLD_SHA" != "none" ]; then
if git diff --name-only "$OLD_SHA" "$NEW_SHA" -- ops/pipeline-v2/ 2>/dev/null | grep -q '\.py$'; then
RESTART="$RESTART teleo-pipeline"
fi
if git diff --name-only "$OLD_SHA" "$NEW_SHA" -- ops/diagnostics/ 2>/dev/null | grep -q '\.py$'; then
RESTART="$RESTART teleo-diagnostics"
fi
else
RESTART="teleo-pipeline teleo-diagnostics"
fi
if [ -n "$RESTART" ]; then
log "Restarting:$RESTART"
sudo systemctl restart $RESTART
sleep 15
FAIL=0
for svc in $RESTART; do
if systemctl is-active --quiet "$svc"; then
log "$svc: active"
else
log "ERROR: $svc failed to start"
journalctl -u "$svc" -n 5 --no-pager 2>/dev/null || true
FAIL=1
fi
done
if echo "$RESTART" | grep -q "teleo-pipeline"; then
if curl -sf --connect-timeout 3 http://localhost:8080/health > /dev/null 2>&1; then
log "pipeline health: OK"
else
log "WARNING: pipeline health check failed"
FAIL=1
fi
fi
if echo "$RESTART" | grep -q "teleo-diagnostics"; then
if curl -sf --connect-timeout 3 http://localhost:8081/ops > /dev/null 2>&1; then
log "diagnostics health: OK"
else
log "WARNING: diagnostics health check failed"
FAIL=1
fi
fi
if [ "$FAIL" -gt 0 ]; then
# Code is already synced — push a fix, don't wait for next cycle
log "WARNING: Smoke test failures. NOT updating stamp. Will retry next cycle. Push a fix."
exit 1
fi
else
log "No Python changes — services not restarted"
fi
echo "$NEW_SHA" > "$STAMP_FILE"
log "Deploy complete: $(git log --oneline -1 "$NEW_SHA")"