#!/usr/bin/env bash # Marks a cache directory as held open by a running job, so ANY job's prune # pass (including this run's own) skips it. # # Usage: cache-lock.sh acquire|release # # Without this, a directory's only protection from a concurrently running # job's eviction pass is "it happens to also be that job's own target dir", # which is true for the job that owns it and false for everyone else. The # marker is per-job (not just per-run) so two jobs sharing one cache key each # hold an independent lock rather than one clobbering the other's. # # A lock is a timestamp file, not a real mutex: prune-cache.sh honours it only # until STALE_LOCK_SECONDS, after which it is treated as abandoned by a job # the runner killed before it reached its own release step. Honouring a lock # forever would let one crashed job pin a directory permanently. # # `.ci-lock-` IS A CROSS-REPO CONTRACT NAME with daniel/gitdan's # `scripts/ci-cache-reclaim.sh`: that host-level arbiter reads this same # marker (its `leftover_is_locked()`) to decide whether a leftover it is about # to reclaim is still held open by a live job. `cache-lib.sh`'s # `write_cache_lock()` writes the identical shape independently of this # script. Rename or reshape this marker here without a matching change on # gitdan's side and the arbiter's lock check silently stops matching — a live # job's staging tree loses its liveness guard and becomes an ordinary reclaim # candidate while still in use. See the "Scratch names in a cache root" section # in README.md, and daniel/gitdan's `DEPENDED-UPON NAMES CONTRACT` block in # `scripts/ci-cache-reclaim.sh`, for the full arrangement — this repo's half # is: don't rename `.ci-lock-` without telling that script. set -euo pipefail MODE="${1:?usage: cache-lock.sh acquire|release }" DIR="${2:?}"; ID="${3:?}" case "$MODE" in acquire) mkdir -p "$DIR" date +%s > "$DIR/.ci-lock-${ID}" echo "lock: acquired .ci-lock-${ID} on $(basename "$DIR")" ;; release) rm -f "$DIR/.ci-lock-${ID}" 2>/dev/null || true echo "lock: released .ci-lock-${ID} on $(basename "$DIR")" ;; *) echo "::error::cache-lock.sh: unknown mode '$MODE' (expected acquire or release)" >&2 exit 1 ;; esac