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:
1 parent
8ac12ec7d6
commit
2b2e880eed
3 files changed
+174
-3
No files matched your search
@@ -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 ]]
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user