From d57a9955d5c872e77100a6102c8c43e2fa6c800c Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Sat, 5 Sep 2026 16:59:22 -0400 Subject: [PATCH 1/2] 1password: map the tarball architecture inside package() so the PKGBUILD's version can be read without CARCH The file-scope case on CARCH ended in 'return 1', which aborted any 'source PKGBUILD' that did not export CARCH before pkgver and pkgrel were assigned. check-versions reads PKGBUILDs that way, saw an empty version, queued 8.12.34-35 on every tick, and promotion then refused to overwrite the already-published artifact. Every channel has been in backoff since 06:41 UTC today because of it. --- pkgbuilds/1password/PKGBUILD | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/pkgbuilds/1password/PKGBUILD b/pkgbuilds/1password/PKGBUILD index 4e91196..bfb2dae 100644 --- a/pkgbuilds/1password/PKGBUILD +++ b/pkgbuilds/1password/PKGBUILD @@ -1,11 +1,4 @@ pkgname=1password - -case "$CARCH" in - x86_64) _tararch=x64 ;; - aarch64) _tararch=arm64 ;; - *) return 1 ;; -esac - pkgver=8.12.34 pkgrel=35 conflicts=('1password-beta' '1password-beta-bin') @@ -34,6 +27,17 @@ validpgpkeys=('3FEF9748469ADBE15DA7CA80AC2D62742012EA22') package() { depends=('hicolor-icon-theme' 'libgtk-3.so=0' 'nss' 'xdg-utils') + # 1Password names its tarballs by a vendor architecture suffix. arch=() + # above already limits which architectures makepkg builds, so no fallback + # branch is needed here; keeping this inside package() means sourcing the + # PKGBUILD without CARCH (as the version check does) still reads the + # version correctly. + local _tararch + case "$CARCH" in + x86_64) _tararch=x64 ;; + aarch64) _tararch=arm64 ;; + esac + # Go to source directory cd "1password-${pkgver}.${_tararch}" From d673d67a1cf240e9f2b26f4fe35c3382f5c8005c Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Sat, 5 Sep 2026 16:59:22 -0400 Subject: [PATCH 2/2] 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. --- bin/check-versions | 31 +++++++++++++++++++++++-------- bin/omarchy-pkgs | 3 ++- bin/sync-rebuilds | 22 +++++++++++++++++++++- helpers/package-metadata.sh | 24 ++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/bin/check-versions b/bin/check-versions index 9849701..925570f 100755 --- a/bin/check-versions +++ b/bin/check-versions @@ -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 diff --git a/bin/omarchy-pkgs b/bin/omarchy-pkgs index 0ca607b..b35016f 100755 --- a/bin/omarchy-pkgs +++ b/bin/omarchy-pkgs @@ -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 diff --git a/bin/sync-rebuilds b/bin/sync-rebuilds index b9aa81d..3009b89 100755 --- a/bin/sync-rebuilds +++ b/bin/sync-rebuilds @@ -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" diff --git a/helpers/package-metadata.sh b/helpers/package-metadata.sh index 043e2fc..564cd2d 100644 --- a/helpers/package-metadata.sh +++ b/helpers/package-metadata.sh @@ -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.