fix: fail safely when AUR synchronization fails
All checks were successful
Update AUR Packages / update (nethlink-appimage) (push) Successful in 13s
Update AUR Packages / update (open-video-downloader-appimage) (push) Successful in 13s
Update AUR Packages / update (open-video-downloader-bin) (push) Successful in 14s
Update AUR Packages / update (pman-helper) (push) Successful in 13s
Update AUR Packages / update (reflex-appimage) (push) Successful in 13s
Update AUR Packages / update (tsparams) (push) Successful in 12s

This commit is contained in:
2026-07-27 00:17:01 +02:00
parent 4defd478dc
commit 2565c193e6
5 changed files with 174 additions and 19 deletions

99
test.sh
View File

@@ -59,6 +59,21 @@ EOS
done
[ -n "${PORT:-}" ] || { echo "could not start test http server" >&2; exit 1; }
# A git shim used by one test to simulate an SSH auth rejection on push.
# Everything else passes straight through to the real git.
REAL_GIT="$(command -v git)"
mkdir -p "$SANDBOX/bin"
cat > "$SANDBOX/bin/git" <<EOS
#!/usr/bin/env bash
if [ "\${FAKE_PUSH_AUTH_FAIL:-}" = "1" ] && [ "\$1" = "push" ] && [ "\$2" = "aur" ]; then
echo "aur@aur.archlinux.org: Permission denied (publickey)." >&2
echo "fatal: Could not read from remote repository." >&2
exit 128
fi
exec "$REAL_GIT" "\$@"
EOS
chmod +x "$SANDBOX/bin/git"
export PKG_REPO_BASE="file://$SANDBOX/origin"
export AUR_HTTPS_BASE="file://$SANDBOX/aur"
export AUR_SSH_BASE="file://$SANDBOX/aur"
@@ -333,8 +348,18 @@ test_lookup_failure_is_loud() {
make_pkg p9
local before; before="$(aur_head p9)"
FAKE_VERSION_FAIL=1 run_update p9
assert_eq "1" "$?" "broken upstream lookup: exits 1, not mistaken for 'no new version'"
local rc=$?
assert_eq "1" "$rc" "broken upstream lookup: exits 1, not mistaken for 'no new version'"
assert_eq "$before" "$(aur_head p9)" "broken upstream lookup: nothing pushed"
# Assert the REASON, not just the exit code. This previously passed even with
# the lookup failure being swallowed: the run carried on with an empty version
# and exited 1 several steps later when .SRCINFO generation rejected it, which
# is the pman-helper pkgver="" bug wearing a different hat.
grep -q "upstream version lookup failed" "$SANDBOX/last.log" \
&& pass "broken upstream lookup: fails AT the lookup, not later" \
|| fail "broken upstream lookup: fails AT the lookup, not later" \
"expected the lookup-failure message; got: $(tail -3 "$SANDBOX/last.log")"
}
test_empty_version_aborts_before_commit() {
@@ -397,6 +422,78 @@ test_multiarch_colliding_downloads() {
assert_ne "$x" "$a" "colliding downloads: sums differ despite the shared :: target"
}
# The ordering guarantee: if the AUR push fails, origin must NOT be pushed.
#
# This regressed in production. `( update_one ) || ...` disables set -e for the
# whole subshell body, so a failed sync-aur.sh did not stop the run and origin
# ended up ahead of the AUR -- the exact state the tool exists to prevent.
test_aur_failure_leaves_origin_unpushed() {
make_pkg p16
local clone="$SANDBOX/manual-p16"
git clone --quiet "file://$SANDBOX/origin/p16" "$clone"
( cd "$clone" && sed -i 's/^pkgdesc=.*/pkgdesc="needs publishing"/' PKGBUILD \
&& makepkg --printsrcinfo > .SRCINFO \
&& git commit --quiet -am "change to publish" && git push --quiet origin main )
local origin_before aur_before
origin_before="$(git -C "$SANDBOX/origin/p16" rev-parse main)"
aur_before="$(aur_head p16)"
# Push target does not exist -> the AUR push fails, the fetch still works.
AUR_SSH_BASE="file://$SANDBOX/nonexistent" FAKE_VERSION=1.0.0 run_update p16
local rc=$?
assert_eq "1" "$rc" "aur failure: run exits 1"
assert_eq "$aur_before" "$(aur_head p16)" "aur failure: AUR unchanged"
assert_eq "$origin_before" "$(git -C "$SANDBOX/origin/p16" rev-parse main)" \
"aur failure: origin NOT pushed (the ordering guarantee)"
# It must not blame divergence for what is a plain push failure.
grep -q "has commits origin does not" "$SANDBOX/last.log" \
&& fail "aur failure: not misreported as divergence" "blamed divergence for a non-divergence failure" \
|| pass "aur failure: not misreported as divergence"
}
# A real non-fast-forward must be named as such -- and must NOT suggest forcing,
# since the AUR refuses force pushes from non-administrators.
test_genuine_divergence_is_reported() {
make_pkg p17
local clone="$SANDBOX/manual-p17"
git clone --quiet "file://$SANDBOX/aur/p17.git" "$clone"
( cd "$clone" && echo "edited directly on the AUR" >> README.md \
&& git commit --quiet -am "out-of-band AUR commit" \
&& git push --quiet origin HEAD:master )
FAKE_VERSION=1.0.0 run_update p17
local rc=$?
assert_eq "1" "$rc" "divergence: exits 1"
grep -q "has commits origin does not" "$SANDBOX/last.log" \
&& pass "divergence: reported as divergence" \
|| fail "divergence: reported as divergence" "$(tail -4 "$SANDBOX/last.log")"
grep -qi "AUR_FORCE" "$SANDBOX/last.log" \
&& fail "divergence: does not suggest forcing" "AUR_FORCE is gone; nothing should mention it" \
|| pass "divergence: does not suggest forcing"
}
test_auth_failure_is_reported_as_auth() {
make_pkg p18
local clone="$SANDBOX/manual-p18"
git clone --quiet "file://$SANDBOX/origin/p18" "$clone"
( cd "$clone" && sed -i 's/^pkgdesc=.*/pkgdesc="publish me"/' PKGBUILD \
&& makepkg --printsrcinfo > .SRCINFO \
&& git commit --quiet -am "change" && git push --quiet origin main )
PATH="$SANDBOX/bin:$PATH" FAKE_PUSH_AUTH_FAIL=1 FAKE_VERSION=1.0.0 run_update p18
local rc=$?
assert_eq "1" "$rc" "auth failure: exits 1"
grep -q "rejected the SSH key" "$SANDBOX/last.log" \
&& pass "auth failure: reported as an SSH key problem" \
|| fail "auth failure: reported as an SSH key problem" "$(tail -4 "$SANDBOX/last.log")"
grep -q "has commits origin does not" "$SANDBOX/last.log" \
&& fail "auth failure: not misreported as divergence" "this is the production bug" \
|| pass "auth failure: not misreported as divergence"
}
test_srcinfo_guard() {
make_pkg p13
local clone="$SANDBOX/manual-p13"