Files
omarchy-pkgs/helpers/lock-helpers.sh
T
Ryan Hughes 63f6156f25 Replace migrate with manifest-driven advance-channel and add the release lock
bin/repo advance --from/--to moves packages forward through the pipeline
(edge → rc → stable), driven by the source channel's database rather than the
raw directory, copying packages AND their detached signatures (fixing the old
migrate bug that left promoted packages unverifiable), refusing to rewrite any
published filename, and requiring a .sig for everything it moves. stable → rc
is allowed only as --fast-ring parity replication or the one-time
--bootstrap seed (bin/repo bootstrap-rc). 'migrate' stays as a deprecated
alias for the transition.

helpers/lock-helpers.sh adds a host-wide flock shared by bin/release,
advance-channel, and upload-prebuilt (reentrant via OMARCHY_RELEASE_LOCK_HELD)
so timers and operators serialize instead of interleaving partial publishes.

bin/release gains a stable-only step 7: replicate fast-ring artifacts to rc so
rc and stable stay in parity between release trains (skipped until rc is
bootstrapped).
2026-08-27 01:10:33 -04:00

45 lines
1.7 KiB
Bash

# Release lock: one channel mutation at a time on this host.
#
# Everything that changes a published channel (release runs, advance, promote,
# upload-prebuilt) takes this lock, so a timer firing mid-advance or two
# operators colliding serializes instead of interleaving partial publishes.
#
# The lock lives beside the published tree (REPO_ROOT), not the checkout, so
# the primary checkout and the rc branch worktree contend on the same file.
# Reentrant across child scripts: acquire_release_lock exports
# OMARCHY_RELEASE_LOCK_HELD, and children skip acquisition when they see it
# (the flock fd is inherited, so the lock stays held for the whole tree).
RELEASE_LOCK_FD=9
acquire_release_lock() {
local timeout="${1:-3600}"
if [[ -n "${OMARCHY_RELEASE_LOCK_HELD:-}" ]]; then
return 0
fi
local lock_file="${REPO_ROOT:-$BUILD_ROOT/pkgs.omarchy.org}/.release.lock"
mkdir -p "$(dirname "$lock_file")"
eval "exec $RELEASE_LOCK_FD>>\"\$lock_file\""
if ! flock -n "$RELEASE_LOCK_FD"; then
local holder
holder=$(cat "$lock_file" 2>/dev/null | tail -1)
echo "Waiting for release lock (up to ${timeout}s)${holder:+ — held by: $holder}" >&2
if ! flock -w "$timeout" "$RELEASE_LOCK_FD"; then
echo "Could not acquire release lock within ${timeout}s: $lock_file" >&2
echo "If no release is actually running, remove the file and retry." >&2
return 1
fi
fi
# Record the holder for the "waiting for" message above. Truncate first so a
# crashed holder's stale line does not linger once we own the lock.
: >"$lock_file"
echo "pid $$ ($0) since $(date '+%Y-%m-%d %H:%M:%S')" >>"$lock_file"
export OMARCHY_RELEASE_LOCK_HELD=1
}