Files
ansible/deploy-guard.yml
PhilandClaude Opus 5.5 0875389d02 Add guard rails for several agents working on the repo at once
Deploys from unpushed branches were being reverted by the next deploy
from main, and in-place vault edits could overwrite each other.

- deploy-guard.yml (imported by site.yml and dns.yml) refuses real runs
  unless the checkout is clean and exactly origin/main; --check is fine.
- bin/deploy holds a lock so only one deploy runs at a time.
- bin/vault-run edits the vault under a lock with an atomic swap.
- bin/worktree starts a task in a fresh worktree from origin/main.
- CLAUDE.md explains the workflow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:29:41 -06:00

41 lines
1.6 KiB
YAML

---
# Imported at the top of site.yml and dns.yml.
#
# Several agents work on this repo at once. If one deploys from an unpushed
# branch, the next deploy from main quietly puts the old config back. So a
# real run only goes ahead when this checkout is exactly origin/main:
# land your commit on main first, then deploy that commit.
#
# --check runs are always allowed. -e allow_unpushed=true skips the guard
# for emergencies; push the fix to main straight after.
- name: Only deploy what's on origin/main
hosts: localhost
gather_facts: false
tags: always
tasks:
- name: Check this checkout matches origin/main
ansible.builtin.shell: |
set -eu
git fetch -q origin main
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
echo "This checkout has uncommitted changes. Commit them, land them on main, then deploy."
exit 1
fi
head=$(git rev-parse HEAD); main=$(git rev-parse origin/main)
if [ "$head" != "$main" ]; then
echo "HEAD $(git rev-parse --short HEAD) isn't origin/main ($(git rev-parse --short origin/main))."
if git merge-base --is-ancestor "$main" "$head"; then
echo "Your commits aren't on main yet: rebase, push to main, then deploy."
else
echo "main has moved on: rebase onto origin/main first, or other agents' changes get reverted."
fi
exit 1
fi
args:
chdir: "{{ playbook_dir }}"
changed_when: false
check_mode: false
when:
- not ansible_check_mode
- not (allow_unpushed | default(false) | bool)