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>
25 lines
1.1 KiB
Bash
25 lines
1.1 KiB
Bash
# Shared by the bin/ helpers. The main checkout holds the venv and the
|
|
# (gitignored) vault files that every worktree uses.
|
|
repo=$(git rev-parse --show-toplevel)
|
|
main_checkout=$(git -C "$repo" worktree list --porcelain | awk '/^worktree /{print $2; exit}')
|
|
lock_dir=${XDG_RUNTIME_DIR:-/tmp}/ansible-selfhosting
|
|
mkdir -p "$lock_dir" && chmod 700 "$lock_dir"
|
|
|
|
# take_lock NAME: wait for, then hold, a lock shared by every agent on this machine.
|
|
take_lock() {
|
|
local name=$1
|
|
exec 9>"$lock_dir/$name.lock"
|
|
if ! flock -n 9; then
|
|
echo "Waiting for $name lock, held by: $(cat "$lock_dir/$name.owner" 2>/dev/null || echo unknown)" >&2
|
|
flock 9
|
|
fi
|
|
echo "$(basename "$repo") (pid $$, $(date '+%H:%M:%S'))" > "$lock_dir/$name.owner"
|
|
}
|
|
|
|
# Worktrees need the gitignored vault files from the main checkout.
|
|
link_vault() {
|
|
[ "$repo" = "$main_checkout" ] && return
|
|
[ -e "$repo/group_vars/all/vault.yml" ] || ln -s "$main_checkout/group_vars/all/vault.yml" "$repo/group_vars/all/vault.yml"
|
|
[ -e "$repo/vault_pass" ] || ln -s "$main_checkout/vault_pass" "$repo/vault_pass"
|
|
}
|