185 lines
6.8 KiB
Bash
Executable File
185 lines
6.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Verify that every quickshell pin we build against is current enough to
|
||
# survive the next Arch Qt update.
|
||
#
|
||
# Why this exists: CI run 137 (2026-10-08) failed because end-4 pinned
|
||
# quickshell to 41651d7 (Sep 25), which predates quickshell's Qt 6.12 fix
|
||
# (5d5d498, Oct 3: "use MOC includes instead of opaque pointer definitions
|
||
# - Fixes linking issues and Qt 6.12 compatibility"). Arch shipped
|
||
# qt6 6.12.0 the next day and the pinned commit stopped compiling
|
||
# ("Meta Types must be fully defined"). customize_airootfs.sh papers over
|
||
# end-4's stale pin at build time; this script is the tripwire that tells
|
||
# us when pins - ours OR end-4's - fall behind again BEFORE a build does.
|
||
#
|
||
# Checked pins:
|
||
# 1. localrepo/end4-pkgbuilds/quickshell-git/PKGBUILD (our own pin)
|
||
# 2. end-4/dots-hyprland sdata/dist-arch PKGBUILD (live from GitHub)
|
||
#
|
||
# Checks per pin:
|
||
# - commit exists upstream
|
||
# - includes the Qt 6.12 fix (5d5d498)
|
||
# - not older than QUICKSHELL_PIN_MAX_AGE_DAYS (default 45)
|
||
#
|
||
# Exit 1 on any failure so CI (pin-check.yaml) goes red.
|
||
#
|
||
# Usage: ./localrepo/check-quickshell-pin.sh
|
||
set -euo pipefail
|
||
|
||
QT612_FIX='5d5d49873fe8cf1f99ddfd5006ceb2057c5c9b13'
|
||
QS_REPO='https://git.outfoxxed.me/quickshell/quickshell.git'
|
||
END4_STALE_PIN='41651d7' # the pin customize_airootfs.sh overrides
|
||
END4_PKGBUILD_URL='https://raw.githubusercontent.com/end-4/dots-hyprland/main/sdata/dist-arch/illogical-impulse-quickshell-git/PKGBUILD'
|
||
MAX_AGE_DAYS="${QUICKSHELL_PIN_MAX_AGE_DAYS:-45}"
|
||
|
||
profile_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
LOCAL_PKGBUILD="${profile_dir}/localrepo/end4-pkgbuilds/quickshell-git/PKGBUILD"
|
||
|
||
FAILED=0
|
||
|
||
fail() {
|
||
echo "❌ $1" >&2
|
||
FAILED=1
|
||
}
|
||
|
||
# ── collect pins ────────────────────────────────────────────────────────────
|
||
|
||
pin_of() { # <file-contents-stdin> -> first _commit='...' value
|
||
sed -n "s/^_commit='\([0-9a-f]\{7,40\}\)'.*/\1/p" | head -n1
|
||
}
|
||
|
||
if [[ ! -f "$LOCAL_PKGBUILD" ]]; then
|
||
echo "❌ missing ${LOCAL_PKGBUILD}" >&2
|
||
exit 1
|
||
fi
|
||
local_pin=$(pin_of < "$LOCAL_PKGBUILD")
|
||
if [[ -z "$local_pin" ]]; then
|
||
echo "❌ no _commit= found in ${LOCAL_PKGBUILD}" >&2
|
||
exit 1
|
||
fi
|
||
|
||
end4_pin=''
|
||
end4_pkgbuild=''
|
||
for try in 1 2 3 4 5; do
|
||
if end4_pkgbuild=$(curl -fsSL --max-time 30 "$END4_PKGBUILD_URL"); then
|
||
end4_pin=$(printf '%s\n' "$end4_pkgbuild" | pin_of)
|
||
break
|
||
fi
|
||
echo " ⏳ fetch of end-4 PKGBUILD failed (try $try/5), retrying in $(( try * 3 ))s..." >&2
|
||
sleep $(( try * 3 ))
|
||
done
|
||
if [[ -z "$end4_pin" ]]; then
|
||
fail "could not fetch end-4's quickshell PKGBUILD from GitHub — network or path change?"
|
||
echo ""
|
||
echo "Result: FAILED"
|
||
exit 1
|
||
fi
|
||
|
||
# ── clone quickshell (blobless: commits+trees only, fast) ───────────────────
|
||
|
||
tmp=$(mktemp -d)
|
||
trap 'rm -rf "$tmp"' EXIT
|
||
|
||
cloned=0
|
||
for try in 1 2 3; do
|
||
if git clone --filter=blob:none --quiet "$QS_REPO" "$tmp/qs" 2>/dev/null; then
|
||
cloned=1
|
||
break
|
||
fi
|
||
rm -rf "$tmp/qs"
|
||
echo " ⏳ clone of quickshell failed (try $try/3), retrying in $(( try * 5 ))s..." >&2
|
||
sleep $(( try * 5 ))
|
||
done
|
||
if [[ "$cloned" -ne 1 ]]; then
|
||
fail "could not clone ${QS_REPO} — network or repo moved?"
|
||
echo ""
|
||
echo "Result: FAILED"
|
||
exit 1
|
||
fi
|
||
QS="$tmp/qs"
|
||
qs_head=$(git -C "$QS" rev-parse HEAD)
|
||
qs_head_date=$(git -C "$QS" show -s --format=%cs HEAD)
|
||
echo "quickshell upstream master: ${qs_head:0:12} (${qs_head_date})"
|
||
echo ""
|
||
|
||
now=$(date +%s)
|
||
|
||
# <label> <pin> <mode>: mode "hard" fails on any problem; mode "soft" only
|
||
# warns, for pins we don't control (end-4's) — UNLESS the problem is one the
|
||
# customize_airootfs.sh override does not cover, which always fails hard
|
||
# because it would break the next ISO build.
|
||
check_pin() {
|
||
local label=$1 pin=$2 mode=$3
|
||
local ts age behind bad=0
|
||
|
||
if ! git -C "$QS" cat-file -e "${pin}^{commit}" 2>/dev/null; then
|
||
fail "$label: pin '$pin' does not exist in quickshell upstream"
|
||
return
|
||
fi
|
||
|
||
local has_fix=0
|
||
if git -C "$QS" merge-base --is-ancestor "$QT612_FIX" "$pin"; then
|
||
has_fix=1
|
||
fi
|
||
|
||
ts=$(git -C "$QS" show -s --format=%ct "$pin")
|
||
age=$(( (now - ts) / 86400 ))
|
||
behind=$(git -C "$QS" rev-list --count "$pin..HEAD")
|
||
|
||
if [[ "$mode" == "hard" ]]; then
|
||
if [[ "$has_fix" -eq 0 ]]; then
|
||
fail "$label: pin '$pin' PREDATES the Qt 6.12 fix (${QT612_FIX:0:12}) — will not compile against Qt >= 6.12"
|
||
bad=1
|
||
fi
|
||
if (( age > MAX_AGE_DAYS )); then
|
||
fail "$label: pin is $age days old (> ${MAX_AGE_DAYS}d), $behind commit(s) behind upstream master — bump it"
|
||
bad=1
|
||
fi
|
||
if [[ "$bad" -eq 0 ]]; then
|
||
echo " ✅ $label: pin ${pin:0:12} includes the Qt 6.12 fix, age ${age}d (${behind} commit(s) behind master)"
|
||
fi
|
||
return
|
||
fi
|
||
|
||
# soft mode: our build-time override compensates for this pin, so drift is
|
||
# a heads-up — it cannot break the ISO build on its own.
|
||
if [[ "$has_fix" -eq 0 ]]; then
|
||
echo " ⚠️ $label: pin ${pin:0:12} predates the Qt 6.12 fix — covered by the customize_airootfs.sh override, but end-4 should bump it"
|
||
else
|
||
echo " ✅ $label: pin ${pin:0:12} includes the Qt 6.12 fix"
|
||
fi
|
||
if (( age > MAX_AGE_DAYS )); then
|
||
echo " ⚠️ $label: pin is $age days old (> ${MAX_AGE_DAYS}d), $behind commit(s) behind master — consider bumping (not enforced, we don't own this pin)"
|
||
else
|
||
echo " ✅ $label: pin age ${age}d (${behind} commit(s) behind master), limit ${MAX_AGE_DAYS}d"
|
||
fi
|
||
}
|
||
|
||
# ── our pin ─────────────────────────────────────────────────────────────────
|
||
|
||
echo "our pin (localrepo/end4-pkgbuilds):"
|
||
check_pin "ours" "$local_pin" hard
|
||
|
||
# ── end-4's pin ─────────────────────────────────────────────────────────────
|
||
|
||
echo ""
|
||
echo "end-4's pin (dots-hyprland sdata/dist-arch):"
|
||
# end-4's pin is only safe if OUR override covers it: customize_airootfs.sh
|
||
# rewrites exactly the 41651d7 pin. Any other Qt-unsafe end-4 pin sails
|
||
# straight into the ISO build unpatched → hard failure.
|
||
if [[ "$end4_pin" == "$END4_STALE_PIN"* ]]; then
|
||
echo " ℹ️ end-4 still pins ${end4_pin:0:12} — customize_airootfs.sh override is active"
|
||
check_pin "end-4" "$end4_pin" soft
|
||
else
|
||
check_pin "end-4" "$end4_pin" hard
|
||
echo " ℹ️ end-4 has moved off ${END4_STALE_PIN} to ${end4_pin:0:12}"
|
||
echo " → if it now passes, consider retiring the override guard in"
|
||
echo " customize_airootfs.sh and syncing our own pin to match."
|
||
fi
|
||
|
||
echo ""
|
||
if [[ "$FAILED" -ne 0 ]]; then
|
||
echo "Result: FAILED"
|
||
exit 1
|
||
fi
|
||
echo "Result: OK — all quickshell pins are Qt 6.12-safe and within ${MAX_AGE_DAYS}d of upstream"
|