47 lines
2.2 KiB
Bash
Executable file
47 lines
2.2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# build-lock.sh — a first-wins BUILD MUTEX for `bun run build`.
|
|
#
|
|
# WHY: multiple agents (and RESUMED "idle" agents — a SendMessage revives one) can each run `bun run build`
|
|
# into the shared public/ output. Concurrent builds clobber each other (a neighbor's `bun run clean` wipes
|
|
# your in-progress output → false "bundle MISSING"). Nothing but coordinator-discipline prevented this — so
|
|
# this makes the collision STRUCTURALLY impossible: the FIRST build acquires the lock; a SECOND build that
|
|
# tries while it's held FAILS FAST with a clear message instead of corrupting the tree.
|
|
#
|
|
# This is the local-dev form of IDEA-FORGEJO-CICD-BUILD-LOCK-MULTIWRITER (the CI/CD concurrency mutex) — the
|
|
# swarm hit the hazard before that gate, so the primitive is built now. Same contract: first-wins, second
|
|
# fails clean, no race.
|
|
#
|
|
# USAGE: `bun run build` (package.json wires build -> this wrapper -> build:unlocked). Override the wait with
|
|
# BUILD_LOCK_WAIT=<seconds> (default 0 = fail-fast/nonblock; set e.g. 300 to QUEUE behind a running build).
|
|
set -euo pipefail
|
|
|
|
LOCK_FILE="${BUILD_LOCK_FILE:-public/.build.lock}"
|
|
WAIT="${BUILD_LOCK_WAIT:-0}"
|
|
mkdir -p "$(dirname "$LOCK_FILE")"
|
|
|
|
# fd 9 = the lock handle
|
|
exec 9>"$LOCK_FILE"
|
|
|
|
if [ "$WAIT" = "0" ]; then
|
|
# nonblocking: first-wins, second fails clean
|
|
if ! flock -n 9; then
|
|
echo "🚫 BUILD LOCK HELD — another build is running (holder: $(cat "$LOCK_FILE" 2>/dev/null || echo '?'))." >&2
|
|
echo " Rebuild refused to avoid a concurrent-build race (would clobber public/). Wait for it to finish" >&2
|
|
echo " and retry, or run with BUILD_LOCK_WAIT=300 to QUEUE behind it." >&2
|
|
exit 75 # EX_TEMPFAIL — 'try again later', distinct from a real build failure
|
|
fi
|
|
else
|
|
echo "⏳ waiting up to ${WAIT}s for the build lock…" >&2
|
|
if ! flock -w "$WAIT" 9; then
|
|
echo "🚫 BUILD LOCK still held after ${WAIT}s — giving up (no race caused)." >&2
|
|
exit 75
|
|
fi
|
|
fi
|
|
|
|
# we hold the lock — stamp who + when, then build
|
|
echo "pid=$$ started=$(date -u +%FT%TZ) by=${BUILD_LOCK_OWNER:-$(whoami)}" >&9
|
|
echo "🔒 build lock acquired — running the authoritative build." >&2
|
|
bun run build:unlocked
|
|
status=$?
|
|
echo "🔓 build done (exit $status) — releasing lock." >&2
|
|
exit $status
|