#!/usr/bin/env bash # ============================================================================= # Gitea Webhook Handler — Trigger Ansible Deploy on Merge # ============================================================================= # This script is called by the Gitea webhook when a PR is merged # to the main branch of timmy-config. # # Setup: # 1. Add webhook in Gitea: Settings → Webhooks → Add Webhook # 2. URL: http://localhost:9000/hooks/deploy-timmy-config # 3. Events: Pull Request (merged only) # 4. Secret: # # This script runs ansible-pull to update the local machine. # For fleet-wide deploys, each machine runs ansible-pull independently. # ============================================================================= set -euo pipefail REPO="https://forge.alexanderwhitestone.com/Timmy_Foundation/timmy-config.git" BRANCH="main" ANSIBLE_DIR="ansible" LOG_FILE="/var/log/ansible/webhook-deploy.log" LOCK_FILE="/tmp/ansible-deploy.lock" log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] [webhook] $*" | tee -a "${LOG_FILE}" } # Prevent concurrent deploys if [ -f "${LOCK_FILE}" ]; then LOCK_AGE=$(( $(date +%s) - $(stat -c %Y "${LOCK_FILE}" 2>/dev/null || echo 0) )) if [ "${LOCK_AGE}" -lt 300 ]; then log "Deploy already in progress (lock age: ${LOCK_AGE}s). Skipping." exit 0 else log "Stale lock file (${LOCK_AGE}s old). Removing." rm -f "${LOCK_FILE}" fi fi trap 'rm -f "${LOCK_FILE}"' EXIT touch "${LOCK_FILE}" log "Webhook triggered. Starting ansible-pull..." # Pull latest config cd /tmp rm -rf timmy-config-deploy git clone --depth 1 --branch "${BRANCH}" "${REPO}" timmy-config-deploy 2>&1 | tee -a "${LOG_FILE}" cd timmy-config-deploy/${ANSIBLE_DIR} # Run Ansible against localhost log "Running Ansible playbook..." ansible-playbook \ -i inventory/hosts.yml \ playbooks/site.yml \ --limit "$(hostname)" \ --diff \ 2>&1 | tee -a "${LOG_FILE}" RESULT=$? if [ ${RESULT} -eq 0 ]; then log "Deploy successful." else log "ERROR: Deploy failed with exit code ${RESULT}." fi # Cleanup rm -rf /tmp/timmy-config-deploy log "Webhook handler complete." exit ${RESULT}