Read PKGBUILD variables with CARCH set and refuse to queue a package whose version cannot be read

makepkg always exports CARCH, so PKGBUILDs may branch on it at file
scope. Every place the tooling sourced a PKGBUILD did so without CARCH,
taking the wrong branch or aborting partway, and check-versions turned
the resulting empty pkgver/pkgrel into the version '-', which never
matches a published version and queues an endless rebuild.

package_pkgbuild_var reads one variable the way makepkg would see it,
for the architecture being checked, and reports whether the source
succeeded. check-versions, sync-rebuilds and omarchy-pkgs use it.
check-versions now warns and skips a package whose pkgver or pkgrel is
empty instead of comparing a partial version. A self-test covers a
PKGBUILD that branches on CARCH before assigning its version.
This commit is contained in:
Ryan Hughes committed 2026-09-05 16:59:22 -04:00
1 parent d57a9955d5
commit d673d67a1c
4 files changed
+70 -10

No files matched your search

+23 -8
View File
@@ -79,10 +79,26 @@ get_repo_version() {
'
}
# The PKGBUILD's full version (epoch:pkgver-pkgrel) for the architecture being
# checked. Prints nothing when pkgver or pkgrel cannot be read: a partial
# version like "-" would compare unequal to everything published and queue a
# rebuild on every tick, so an unreadable PKGBUILD must not queue at all.
get_pkgbuild_version() {
local pkgdir="$1"
if [[ -f "$pkgdir/PKGBUILD" ]]; then
(cd "$pkgdir" && bash -c 'source PKGBUILD 2>/dev/null; if [[ -n "$epoch" ]]; then echo "${epoch}:${pkgver}-${pkgrel}"; else echo "${pkgver}-${pkgrel}"; fi')
local epoch pkgver pkgrel
[[ -f "$pkgdir/PKGBUILD" ]] || return 1
epoch=$(package_pkgbuild_var "$pkgdir" epoch "$ARCH")
pkgver=$(package_pkgbuild_var "$pkgdir" pkgver "$ARCH")
pkgrel=$(package_pkgbuild_var "$pkgdir" pkgrel "$ARCH")
[[ -n "$pkgver" && -n "$pkgrel" ]] || return 1
if [[ -n "$epoch" ]]; then
echo "${epoch}:${pkgver}-${pkgrel}"
else
echo "${pkgver}-${pkgrel}"
fi
}
@@ -97,8 +113,8 @@ check_vcs_unchanged() {
# If epoch or pkgrel changed in PKGBUILD, release even if upstream is unchanged.
local pkgbuild_epoch pkgbuild_pkgrel
pkgbuild_epoch=$(cd "$pkgdir" && bash -c 'source PKGBUILD 2>/dev/null; echo "${epoch:-}"')
pkgbuild_pkgrel=$(cd "$pkgdir" && bash -c 'source PKGBUILD 2>/dev/null; echo "${pkgrel}"')
pkgbuild_epoch=$(package_pkgbuild_var "$pkgdir" epoch "$ARCH")
pkgbuild_pkgrel=$(package_pkgbuild_var "$pkgdir" pkgrel "$ARCH")
local repo_pkgrel="${repo_version##*-}"
local repo_no_pkgrel="${repo_version%-*}"
@@ -126,12 +142,11 @@ check_package() {
local mirror="$3"
local pkgbuild_version repo_version
pkgbuild_version=$(get_pkgbuild_version "$pkgdir")
repo_version=$(get_repo_version "$pkg" "$mirror")
if [[ -z "$pkgbuild_version" ]]; then
if ! pkgbuild_version=$(get_pkgbuild_version "$pkgdir") || [[ -z "$pkgbuild_version" ]]; then
print_warning "$pkg: could not read pkgver/pkgrel from its PKGBUILD for $ARCH — not queueing"
return 1
fi
repo_version=$(get_repo_version "$pkg" "$mirror")
if grep -qE '^pkgver[[:space:]]*\(\)' "$pkgdir/PKGBUILD"; then
if [[ -n "$repo_version" && -n "$(package_extract_vcs_hash_from_version "$repo_version")" ]]; then
+2 -1
View File
@@ -21,6 +21,7 @@ BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..")
source "$BUILD_ROOT/helpers/message-helpers.sh"
source "$BUILD_ROOT/helpers/paths.sh"
source "$BUILD_ROOT/helpers/host-helpers.sh"
source "$BUILD_ROOT/helpers/package-metadata.sh"
UPSTREAM_URL="${OMARCHY_UPSTREAM_URL:-https://github.com/basecamp/omarchy.git}"
EDGE_DB_URL="${OMARCHY_EDGE_DB_URL:-https://pkgs.omarchy.org/edge/$(reference_arch)/omarchy.db.tar.zst}"
@@ -92,7 +93,7 @@ version_is_rc() { version_is_prerelease "$1"; }
pkgbuild_var() {
local pkg="$1" var="$2"
(cd "$BUILD_ROOT/pkgbuilds/$pkg" && bash -c "source PKGBUILD 2>/dev/null; echo \"\${$var}\"")
package_pkgbuild_var "$BUILD_ROOT/pkgbuilds/$pkg" "$var"
}
# Prints the published version of $pkg from the edge DB. Distinguishes
+21 -1
View File
@@ -237,7 +237,7 @@ pkgbuild_field() {
local package_dir="$1"
local field="$2"
(cd "$package_dir" && env -u OMARCHY_SRC bash -c "source PKGBUILD 2>/dev/null; echo \"\${$field:-}\"")
package_pkgbuild_var "$package_dir" "$field"
}
# 2 -> 3, and 1.1 -> 1.2. Anything else is a pkgrel this command has no business
@@ -781,6 +781,26 @@ cmd_self_test() {
unset SELFTEST_ARCHES
check "pkgrel untouched" 1 "$(pkgrel_of "$root/pkgbuilds/t-x86")"
echo "A PKGBUILD that branches on CARCH at file scope still reads its version:"
root=$(selftest_root carch-branch)
mkdir -p "$root/pkgbuilds/t-carch/.omarchy"
cat > "$root/pkgbuilds/t-carch/PKGBUILD" <<'PKG'
pkgname=t-carch
case "$CARCH" in
x86_64) _suffix=x64 ;;
aarch64) _suffix=arm64 ;;
*) return 1 ;;
esac
pkgver=1.0
pkgrel=3
arch=(x86_64 aarch64)
PKG
echo '{"source":"local"}' > "$root/pkgbuilds/t-carch/.omarchy/package.json"
check "pkgver read for x86_64" "1.0" "$(package_pkgbuild_var "$root/pkgbuilds/t-carch" pkgver x86_64)"
check "pkgrel read for x86_64" "3" "$(package_pkgbuild_var "$root/pkgbuilds/t-carch" pkgrel x86_64)"
check "arch-specific value follows CARCH" "arm64" "$(package_pkgbuild_var "$root/pkgbuilds/t-carch" _suffix aarch64)"
check "unsupported arch reports failure" 1 "$(package_pkgbuild_var "$root/pkgbuilds/t-carch" pkgver armv7h >/dev/null; echo $?)"
echo ""
if [[ "$failures" -eq 0 ]]; then
print_success "Self-test passed"
+24
View File
@@ -144,6 +144,30 @@ package_has_pkgbuild() {
[[ -f "$pkgdir/PKGBUILD" ]]
}
# Read one variable from a PKGBUILD the way makepkg would see it.
#
# makepkg always exports CARCH, so PKGBUILDs may branch on it at file scope
# (per-architecture sources, tarball suffixes, even `return` for an
# unsupported architecture). Sourcing without CARCH takes the wrong branch or
# aborts partway, which leaves pkgver and pkgrel empty — and an empty version
# never equals the published one, so the package is queued for a rebuild that
# promotion then refuses. Every read of a PKGBUILD goes through here.
#
# Prints the value; exit status is that of `source PKGBUILD` itself, so a
# caller can tell "variable empty" from "PKGBUILD could not be read".
package_pkgbuild_var() {
local pkgdir="$1"
local var="$2"
local arch="${3:-${ARCH:-x86_64}}"
(cd "$pkgdir" && env -u OMARCHY_SRC CARCH="$arch" bash -c '
source PKGBUILD >/dev/null 2>&1
rc=$?
printf "%s\n" "${!1:-}"
exit "$rc"
' _ "$var")
}
# The architectures declared by a PKGBUILD. Set CARCH while reading it so a
# conditional arch=() assignment is evaluated for the architecture we are
# actually checking, even when the repository host is a different one.