fix: paginate Cua Driver release discovery

Build on #306 without replacing its package or updater workaround. Exhaust the component feed before selecting a release and cover quarantine, version ordering, invalid input, and transport failures with offline fixtures.
This commit is contained in:
Francesco Bonacci committed 2026-09-07 17:57:46 -05:00
1 parent 8ac12ec7d6
commit 2b2e880eed
3 files changed
+174 -3

No files matched your search

+4
View File
@@ -834,6 +834,10 @@ EOF
check "malformed upstream fails the sync instead of skipping" "1" "$((FAILED - prev_failed))"
FAILED=0
if ! bash "$BUILD_ROOT/pkgbuilds/cua-driver-bin/.omarchy/upstream-test.sh"; then
failures=$((failures + 1))
fi
echo ""
if [[ "$failures" -eq 0 ]]; then
print_success "Self-test passed"
@@ -0,0 +1,146 @@
#!/bin/bash
# Offline hook fixtures, also run by bin/sync-upstream self-test. Requires
# GNU date, jq, and pacman's vercmp, like the repository's other self-tests.
set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")/.."
failures=0
check() {
if [[ "$2" == "$3" ]]; then
echo " ok: $1"
else
echo " FAIL: $1 (expected '$2', got '$3')"
failures=$((failures + 1))
fi
}
# Freeze time at the exact 24-hour boundary of the fixture's 0.24.0.
date() {
if [[ "$*" == '+%s' ]]; then
jq -nr '"2026-09-08T16:51:50Z" | fromdateiso8601'
else
command date "$@"
fi
}
curl() {
local url="${!#}"
case "$url" in
'https://api.github.com/repos/trycua/cua/releases?per_page=100&page='*)
local page="${url##*=}"
[[ "$page" != "${FAIL_PAGE:-}" ]] || { echo 'fixture API failure' >&2; return 22; }
if [[ "${ENDLESS:-}" == 1 || "$page" == 1 ]]; then
printf '%s\n' "$PAGE1"
elif [[ "$page" == 2 ]]; then
printf '%s\n' "$PAGE2"
else
echo '[]'
fi
;;
'https://github.com/trycua/cua/releases/download/'*'/checksums.txt')
[[ "${FAIL_CHECKSUMS:-}" != 1 ]] || { echo 'fixture download failure' >&2; return 22; }
printf '%s\n' "$CHECKSUMS"
;;
*) echo "unexpected fixture URL: $url" >&2; return 1 ;;
esac
}
export -f curl date
export PAGE1 PAGE2 CHECKSUMS FAIL_PAGE FAIL_CHECKSUMS ENDLESS
export MIN_RELEASE_AGE_SECONDS=86400
export BYPASS_MIN_RELEASE_AGE=''
FAIL_PAGE='' FAIL_CHECKSUMS='' ENDLESS=''
PAGE2='[]'
release() {
jq -cn --arg tag "$1" --arg published "${2:-2026-09-06T16:51:50Z}" \
'{tag_name: $tag, published_at: $published, draft: false, prerelease: true}'
}
run_hook() {
status=0
out=$(bash .omarchy/upstream.sh 2>&1) || status=$?
}
expect_failure() {
run_hook
check "$1 fails" yes "$([[ "$status" != 0 ]] && echo yes || echo no)"
check "$1 reports the reason" yes "$([[ "$out" == *"$2"* ]] && echo yes || echo no)"
}
sum_x=$(printf 'a%.0s' {1..64})
sum_a=$(printf 'b%.0s' {1..64})
CHECKSUMS=$(printf '%s\n' \
"$sum_x cua-driver-rs-0.24.0-linux-x86_64.tar.gz" \
"$sum_a cua-driver-rs-0.24.0-linux-arm64.tar.gz")
foreign_page=$(jq -cn '[range(100) | {tag_name: "fleet-v9.0.0", draft: false}]')
stable=$(release cua-driver-rs-v0.24.0 2026-09-07T16:51:50Z)
echo 'Cua Driver release hook:'
PAGE1="$foreign_page"
PAGE2="[$stable]"
run_hook
check 'component found beyond the first 100 releases' 0 "$status"
check 'stable-shaped prerelease accepted at exactly 24h' 0.24.0 "$(jq -r '.pkgver' <<<"$out")"
check 'x86_64 checksum' "$sum_x" "$(jq -r '.sha256sums.x86_64[0]' <<<"$out")"
check 'ARM checksum' "$sum_a" "$(jq -r '.sha256sums.aarch64[0]' <<<"$out")"
check 'publication date preserved' 2026-09-07T16:51:50Z "$(jq -r '.published_at' <<<"$out")"
# An eligible lower version on page one must not terminate the scan.
rebuilt=$(release cua-driver-rs-v0.23.3 2026-09-07T16:51:50Z)
PAGE1=$(jq -c --argjson rebuilt "$rebuilt" '.[0] = $rebuilt' <<<"$foreign_page")
PAGE2="[$(release cua-driver-rs-v0.24.0)]"
run_hook
check 'older page outranks recently rebuilt lower version' 0.24.0 "$(jq -r '.pkgver' <<<"$out")"
draft=$(release cua-driver-rs-v99.0.0 | jq -c '.draft = true')
nightly=$(release nightly-cua-driver-rs-v99.0.0)
suffix=$(release cua-driver-rs-v99.0.0-nightly.1)
young=$(release cua-driver-rs-v0.25.0 2026-09-07T16:51:51Z)
PAGE1="[$draft,$nightly,$suffix,$young,$stable,$rebuilt]"
PAGE2='[]'
run_hook
check 'drafts/nightlies rejected and young release quarantined' 0.24.0 "$(jq -r '.pkgver' <<<"$out")"
PAGE1="[$young]"
run_hook
check 'all candidates too young is a successful skip' 0 "$status"
check 'all young candidates emit empty JSON' '{}' "${out##*$'\n'}"
check 'quarantine reason is reported' yes "$([[ "$out" == *release-age* ]] && echo yes || echo no)"
PAGE1="[$(release cua-driver-rs-v0.23.2)]"
run_hook
check 'current package version is unchanged' '{}' "$out"
PAGE1="[$draft,$nightly,$suffix]"
expect_failure 'no stable component candidate' 'no stable cua-driver-rs-v'
PAGE1='[]'
expect_failure 'empty feed' 'no stable cua-driver-rs-v'
PAGE1="[$(release cua-driver-rs-v0.24.0 yesterday)]"
expect_failure 'relative publication date' 'invalid published_at'
PAGE1="[$(release cua-driver-rs-v0.24.0 2026-02-30T00:00:00Z)]"
expect_failure 'impossible publication date' 'invalid published_at'
PAGE1='[{"tag_name":"cua-driver-rs-v0.24.0","draft":false}]'
expect_failure 'missing publication date' 'invalid published_at'
PAGE1="$foreign_page"
PAGE2='{"message":"API rate limit exceeded"}'
expect_failure 'API error object on later page' 'invalid release feed'
PAGE2='not json'
expect_failure 'malformed JSON on later page' 'invalid release feed'
PAGE2='[42]'
expect_failure 'malformed release entry' 'Cannot index'
PAGE2="[$stable]"
FAIL_PAGE=2
expect_failure 'network failure after first page' 'fixture API failure'
FAIL_PAGE=''
ENDLESS=1
expect_failure 'feed exceeds pagination bound' 'refusing incomplete selection'
ENDLESS=''
PAGE1="[$stable]"
PAGE2='[]'
FAIL_CHECKSUMS=1
expect_failure 'checksum download failure' 'fixture download failure'
FAIL_CHECKSUMS=''
CHECKSUMS="$sum_x cua-driver-rs-0.24.0-linux-x86_64.tar.gz"
expect_failure 'missing ARM checksum' 'no valid checksum'
CHECKSUMS='invalid cua-driver-rs-0.24.0-linux-x86_64.tar.gz'
expect_failure 'invalid checksum' 'no valid checksum'
[[ "$failures" == 0 ]]
+24 -3
View File
@@ -9,7 +9,28 @@ set -euo pipefail
REPO="trycua/cua"
TAG_PREFIX="cua-driver-rs-v"
releases=$(curl -fsSL "https://api.github.com/repos/$REPO/releases?per_page=100")
# Publication order is not version order: older pages can contain a newer
# driver version than a recently rebuilt release. Exhaust the feed before
# selecting, and fail closed if the bounded scan cannot reach its end.
releases='[]'
max_pages=100
for ((page = 1; page <= max_pages; page++)); do
release_page=$(curl --connect-timeout 10 --max-time 30 -fsSL \
"https://api.github.com/repos/$REPO/releases?per_page=100&page=$page")
if ! page_size=$(jq -er 'if type == "array" and length <= 100 then length else error("expected release page of at most 100 entries") end' <<<"$release_page"); then
echo "invalid release feed for $REPO on page $page" >&2
exit 1
fi
releases=$(jq -c --argjson page "$release_page" '. + $page' <<<"$releases")
(( page_size == 100 )) || break
done
if (( page > max_pages )); then
echo "release feed for $REPO exceeds $max_pages pages; refusing incomplete selection" >&2
exit 1
fi
# Keep jq failures in the main shell, where errexit can reject malformed data.
release_rows=$(jq -r '.[] | select(.draft | not) | [.tag_name // "", .published_at // ""] | @tsv' <<<"$releases")
min_age="${MIN_RELEASE_AGE_SECONDS:-0}"
now=$(date +%s)
@@ -48,9 +69,9 @@ while IFS=$'\t' read -r tag published_at; do
best_tag=$tag
best_published=$published_at
fi
done < <(jq -r '.[] | select(.draft | not) | [.tag_name // "", .published_at // ""] | @tsv' <<<"$releases")
done <<<"$release_rows"
# A feed page with no stable driver release at all is an anomaly worth a loud
# A feed with no stable driver release at all is an anomaly worth a loud
# error; every candidate merely being inside the quarantine window is not.
if (( candidates == 0 )); then
echo "no stable $TAG_PREFIX releases in the feed for $REPO" >&2