#!/bin/bash # Integration regression: uses real containers, makepkg, repo-add and pacman. # Requires the normal builder image (or TEST_BUILDER_IMAGE) for this platform. set -euo pipefail BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..") source "$BUILD_ROOT/helpers/message-helpers.sh" source "$BUILD_ROOT/helpers/docker-helpers.sh" check_engine TEST_ARCH=$(docker_native_arch) TEST_BUILDER_IMAGE=${TEST_BUILDER_IMAGE:-omarchy-pkg-builder:latest-$TEST_ARCH-edge} TEST_ROOT=$(mktemp -d) trap 'rm -rf "$TEST_ROOT"' EXIT mkdir -p "$TEST_ROOT/bin" "$TEST_ROOT/pkgbuilds" "$TEST_ROOT/build-output/edge/$TEST_ARCH" cp "$BUILD_ROOT/bin/build" "$TEST_ROOT/bin/" cp -r "$BUILD_ROOT/build" "$BUILD_ROOT/helpers" "$TEST_ROOT/" # No external verification keys are needed for source-free fixtures. : > "$TEST_ROOT/build/gpg-keys.txt" # The runner expects the normal image tag. Use an engine wrapper to select # the supplied test image without overwriting an operator's builder image. TEST_ENGINE=$(command -v "$CONTAINER_ENGINE") mkdir "$TEST_ROOT/engine" cat > "$TEST_ROOT/engine/$CONTAINER_ENGINE" <<'ENGINE' #!/bin/bash args=("$@") for index in "${!args[@]}"; do if [[ "${args[$index]}" == omarchy-pkg-builder:latest-* ]]; then args[$index]="$TEST_BUILDER_IMAGE" fi done exec "$TEST_ENGINE" "${args[@]}" ENGINE chmod +x "$TEST_ROOT/engine/$CONTAINER_ENGINE" export TEST_ENGINE TEST_BUILDER_IMAGE export PATH="$TEST_ROOT/engine:$PATH" export OMARCHY_SKIP_BUILDER_IMAGE=1 unset OMARCHY_REPO_ROOT OMARCHY_RC_PINS OMARCHY_DEFER_RUNTIME_DEPS OMARCHY_KEEP_BUILD_WORKSPACE fixture() { local name=$1 metadata=$2 mkdir -p "$TEST_ROOT/pkgbuilds/$name/.omarchy" printf '{"source":"local"}\n' > "$TEST_ROOT/pkgbuilds/$name/.omarchy/package.json" cat > "$TEST_ROOT/pkgbuilds/$name/PKGBUILD" < "$TEST_ROOT/pairs.log" 2>&1 || { cat "$TEST_ROOT/pairs.log" exit 1 } for package in flea omarchy omarchy-dev omarchy-settings omarchy-settings-dev; do compgen -G "$TEST_ROOT/build-output/edge/$TEST_ARCH/$package-1-1-*.pkg.tar.zst" >/dev/null done printf 'PASS: release/dev pairs and Flea build together in isolated roots\n' # Test-only and architecture-specific dependencies must precede consumers. # Failure must block both direct and transitive consumers, while an # unrelated package still builds in a clean container. fixture broken '' cat >> "$TEST_ROOT/pkgbuilds/broken/PKGBUILD" <<'EOF' prepare() { touch /tmp/omarchy-build-contamination; return 1; } EOF fixture consumer "checkdepends_${TEST_ARCH}=('broken')" fixture transitive "makedepends=('consumer')" fixture independent '' failure_status=0 OMARCHY_BUILD_RESULT_DIR="$TEST_ROOT/results" run_build transitive consumer broken independent > "$TEST_ROOT/failure.log" 2>&1 || failure_status=$? if [[ "$failure_status" != 2 ]]; then cat "$TEST_ROOT/failure.log" echo "FAIL: expected completed package failure (2), got $failure_status" >&2 exit 1 fi [[ -f "$TEST_ROOT/results/complete" ]] [[ $(cat "$TEST_ROOT/results/failed") == broken ]] [[ $(cat "$TEST_ROOT/results/blocked") == $'transitive\nconsumer' || $(cat "$TEST_ROOT/results/blocked") == $'consumer\ntransitive' ]] [[ $(cat "$TEST_ROOT/results/artifacts") == "independent-1-1-$TEST_ARCH.pkg.tar.zst" ]] grep -q 'consumer blocked by unsuccessful dependency: broken' "$TEST_ROOT/failure.log" grep -q 'transitive blocked by unsuccessful dependency: consumer' "$TEST_ROOT/failure.log" compgen -G "$TEST_ROOT/build-output/edge/$TEST_ARCH/independent-1-1-*.pkg.tar.zst" >/dev/null if compgen -G "$TEST_ROOT/build-output/edge/$TEST_ARCH/consumer-*.pkg.tar.zst" >/dev/null; then echo 'FAIL: consumer of a failed prerequisite was built' >&2 exit 1 fi printf 'PASS: failed prerequisite blocks consumers; independent build remains clean\n' # A later job can resolve dependencies from artifacts kept by the caller. # Make consumer depend on the already staged fixture without selecting it. sed -i "s/^checkdepends_.*/depends=('independent')/" "$TEST_ROOT/pkgbuilds/consumer/PKGBUILD" OMARCHY_KEEP_BUILD_WORKSPACE=1 run_build consumer > "$TEST_ROOT/seeded.log" 2>&1 || { cat "$TEST_ROOT/seeded.log" exit 1 } compgen -G "$TEST_ROOT/build-output/edge/$TEST_ARCH/consumer-1-1-*.pkg.tar.zst" >/dev/null printf 'PASS: kept workspace supplies dependencies to a later isolated build\n' # A rebuild may keep its filename while changing its bytes. Pacman's shared # cache must not hide the replacement artifact from the next consumer. cat >> "$TEST_ROOT/pkgbuilds/independent/PKGBUILD" <<'EOF' package() { install -Dm644 /dev/null "$pkgdir/usr/share/build-isolation/independent" echo replacement > "$pkgdir/usr/share/build-isolation/independent" } EOF cat >> "$TEST_ROOT/pkgbuilds/consumer/PKGBUILD" <<'EOF' check() { [[ $(cat /usr/share/build-isolation/independent) == replacement ]]; } EOF OMARCHY_KEEP_BUILD_WORKSPACE=1 run_build independent consumer > "$TEST_ROOT/rebuilt.log" 2>&1 || { cat "$TEST_ROOT/rebuilt.log" exit 1 } printf 'PASS: rebuilt artifacts supersede cached packages with the same filename\n' # CI's deferred pair mode still accepts the complete request although each # half now builds in its own container. An unavailable runtime dependency # proves it was deferred; build/test dependencies still use pacman normally. sed -i "s/^depends=.*/depends=('omarchy-settings-dev' 'unavailable-runtime-fixture')/" "$TEST_ROOT/pkgbuilds/omarchy-dev/PKGBUILD" OMARCHY_DEFER_RUNTIME_DEPS=true run_build omarchy-dev omarchy-settings-dev > "$TEST_ROOT/deferred.log" 2>&1 || { cat "$TEST_ROOT/deferred.log" exit 1 } compgen -G "$TEST_ROOT/build-output/edge/$TEST_ARCH/omarchy-dev-1-1-*.pkg.tar.zst" >/dev/null printf 'PASS: deferred pair mode works across isolated containers\n' fixture excluded '' printf '{"source":"local","channels":["stable"]}\n' > "$TEST_ROOT/pkgbuilds/excluded/.omarchy/package.json" run_build excluded > "$TEST_ROOT/empty.log" 2>&1 || { cat "$TEST_ROOT/empty.log"; exit 1; } grep -q 'Total packages: 0' "$TEST_ROOT/empty.log" if grep -q 'in a fresh container' "$TEST_ROOT/empty.log"; then echo 'FAIL: an excluded package started a build container' >&2 exit 1 fi printf 'PASS: empty plans finish without starting a package build\n'