From f6cc3f3ea3a41b2a29029fa0c7b6e88c3cbc8b4d Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Wed, 29 Oct 2025 11:54:20 -0400 Subject: [PATCH 1/5] Initial working concept for aarch64 --- build/Dockerfile.aarch64 | 20 ++++++ build/bootstrap/Dockerfile.alarm-base | 7 ++ build/bootstrap/alarm-signing-key.asc | 51 ++++++++++++++ build/bootstrap/create-alarm-base.sh | 99 +++++++++++++++++++++++++++ 4 files changed, 177 insertions(+) create mode 100644 build/Dockerfile.aarch64 create mode 100644 build/bootstrap/Dockerfile.alarm-base create mode 100644 build/bootstrap/alarm-signing-key.asc create mode 100755 build/bootstrap/create-alarm-base.sh diff --git a/build/Dockerfile.aarch64 b/build/Dockerfile.aarch64 new file mode 100644 index 00000000..2dcbdb73 --- /dev/null +++ b/build/Dockerfile.aarch64 @@ -0,0 +1,20 @@ +FROM omarchy-alarm-base:latest + +RUN pacman-key --init && \ + pacman-key --populate archlinuxarm + +RUN pacman -Syu --noconfirm && \ + pacman -S --noconfirm base-devel git sudo wget jq gnupg + +RUN pacman-key --recv-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 --keyserver keys.openpgp.org && \ + pacman-key --lsign-key 40DFB630FF42BCFFB047046CF0134EE680CAC571 + +RUN useradd -m -G wheel builder && \ + echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers + +USER builder +WORKDIR /src + +RUN mkdir -p ~/.gnupg && chmod 700 ~/.gnupg + +CMD ["/build/build.sh"] diff --git a/build/bootstrap/Dockerfile.alarm-base b/build/bootstrap/Dockerfile.alarm-base new file mode 100644 index 00000000..2f9fd6eb --- /dev/null +++ b/build/bootstrap/Dockerfile.alarm-base @@ -0,0 +1,7 @@ +FROM scratch + +ADD ArchLinuxARM-aarch64-latest.tar.gz / + +ENV LANG=en_US.UTF-8 + +CMD ["/usr/bin/bash"] diff --git a/build/bootstrap/alarm-signing-key.asc b/build/bootstrap/alarm-signing-key.asc new file mode 100644 index 00000000..c043b82c --- /dev/null +++ b/build/bootstrap/alarm-signing-key.asc @@ -0,0 +1,51 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +fx6y8+A0kBiaAmcY01U/upYXeHs= +=AIgD +-----END PGP PUBLIC KEY BLOCK----- diff --git a/build/bootstrap/create-alarm-base.sh b/build/bootstrap/create-alarm-base.sh new file mode 100755 index 00000000..b5fccdc5 --- /dev/null +++ b/build/bootstrap/create-alarm-base.sh @@ -0,0 +1,99 @@ +#!/bin/bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BUILD_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" + +source "$BUILD_ROOT/helpers/message-helpers.sh" + +TARBALL_URL="http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz" +TARBALL_MD5_URL="http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz.md5" +TARBALL_SIG_URL="http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz.sig" +ALARM_KEY_ID="68B3537F39A313B3E574D06777193F152BDBE6A6" + +TARBALL_FILE="$SCRIPT_DIR/ArchLinuxARM-aarch64-latest.tar.gz" +MD5_FILE="$SCRIPT_DIR/ArchLinuxARM-aarch64-latest.tar.gz.md5" +SIG_FILE="$SCRIPT_DIR/ArchLinuxARM-aarch64-latest.tar.gz.sig" + +print_header "Arch Linux ARM Bootstrap" + +print_info "This will create the omarchy-alarm-base:latest Docker image" +print_info "Source: https://archlinuxarm.org/platforms/armv8/generic" +echo "" + +if docker images | grep -q "omarchy-alarm-base.*latest"; then + print_warning "Image omarchy-alarm-base:latest already exists" + read -p "Rebuild it? (y/N): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + print_info "Skipping bootstrap" + exit 0 + fi +fi + +cd "$SCRIPT_DIR" + +print_info "Downloading ALARM aarch64 tarball (~450MB)..." +if [[ -f "$TARBALL_FILE" ]]; then + print_info "Tarball already exists, skipping download" +else + wget -O "$TARBALL_FILE" "$TARBALL_URL" +fi + +print_info "Downloading checksum and signature..." +wget -O "$MD5_FILE" "$TARBALL_MD5_URL" || true +wget -O "$SIG_FILE" "$TARBALL_SIG_URL" || true + +if [[ -f "$MD5_FILE" ]]; then + print_info "Verifying MD5 checksum..." + if md5sum -c "$MD5_FILE"; then + print_success "✓ MD5 checksum verified" + else + print_error "MD5 checksum verification failed" + exit 1 + fi +fi + +if [[ -f "$SIG_FILE" ]]; then + print_info "Verifying GPG signature..." + + if ! gpg --list-keys "$ALARM_KEY_ID" &>/dev/null; then + print_info "Importing ALARM signing key..." + if [[ -f "$SCRIPT_DIR/alarm-signing-key.asc" ]]; then + gpg --import "$SCRIPT_DIR/alarm-signing-key.asc" + else + gpg --keyserver keyserver.ubuntu.com --recv-keys "$ALARM_KEY_ID" + fi + fi + + if gpg --verify "$SIG_FILE" "$TARBALL_FILE"; then + print_success "✓ GPG signature verified" + else + print_error "GPG signature verification failed" + exit 1 + fi +else + print_warning "No signature file found, skipping GPG verification" +fi + +print_info "Building Docker image from tarball..." + +docker build --platform linux/arm64 -t omarchy-alarm-base:latest -f "$SCRIPT_DIR/Dockerfile.alarm-base" "$SCRIPT_DIR" + +if [[ $? -eq 0 ]]; then + print_success "Successfully created omarchy-alarm-base:latest" + echo "" + print_info "Testing the image..." + docker run --rm --platform linux/arm64 omarchy-alarm-base:latest uname -a + echo "" + print_success "Bootstrap complete!" + print_info "You can now build the aarch64 builder: docker build -f build/Dockerfile.aarch64" +else + print_error "Failed to create Docker image" + exit 1 +fi + +print_info "Cleaning up downloaded files..." +rm -f "$TARBALL_FILE" "$MD5_FILE" "$SIG_FILE" + +print_success "Done!" From 78c1ef26581ea0133e41f3f1e5e753729ede7081 Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Wed, 29 Oct 2025 22:55:17 -0400 Subject: [PATCH 2/5] Unified aarch64 / amd64 image --- bin/build | 7 +- build/Dockerfile | 143 ++++++++++++++++++++++++++++++++++++++ build/Dockerfile.x86_64 | 23 ------ build/pacstrap-docker | 23 ++++++ helpers/docker-helpers.sh | 47 +++++-------- 5 files changed, 183 insertions(+), 60 deletions(-) create mode 100644 build/Dockerfile delete mode 100644 build/Dockerfile.x86_64 create mode 100755 build/pacstrap-docker diff --git a/bin/build b/bin/build index 7aba76af..de933333 100755 --- a/bin/build +++ b/bin/build @@ -110,12 +110,7 @@ fi # Run the builder with assembled args IMAGE_TAG="omarchy-pkg-builder:latest-$ARCH" -PLATFORM_ARG="" -if [[ "$ARCH" == "aarch64" ]]; then - PLATFORM_ARG="--platform linux/arm64" -elif [[ "$ARCH" == "x86_64" ]]; then - PLATFORM_ARG="--platform linux/amd64" -fi +PLATFORM_ARG=$(get_platform_arg "$ARCH") docker run $PLATFORM_ARG "${DOCKER_ARGS[@]}" "$IMAGE_TAG" /build/build.sh diff --git a/build/Dockerfile b/build/Dockerfile new file mode 100644 index 00000000..4121ce4b --- /dev/null +++ b/build/Dockerfile @@ -0,0 +1,143 @@ +# ============================================================================== +# Omarchy Package Builder - Multi-Architecture +# Supports: x86_64 (Arch Linux) and aarch64 (Arch Linux ARM) +# ============================================================================== + +# ------------------------------------------------------------------------------ +# Stage 1: Bootstrap - Create base Arch/ALARM system from scratch +# ------------------------------------------------------------------------------ +FROM docker.io/alpine:3.21 AS bootstrapper + +ARG TARGETARCH +ARG BUILDPLATFORM + +COPY pacstrap-docker /usr/local/bin/ + +RUN apk add --no-cache \ + pacman-makepkg \ + curl \ + bash \ + zstd \ + gnupg + +# Map Docker TARGETARCH (amd64/arm64) to Arch naming (x86_64/aarch64) +RUN case "${TARGETARCH}" in \ + amd64) \ + echo "x86_64" > /tmp/arch && \ + printf '[core]\nInclude = /etc/pacman.d/mirrorlist\n\n[extra]\nInclude = /etc/pacman.d/mirrorlist\n' > /tmp/repos.conf ;; \ + arm64) \ + echo "aarch64" > /tmp/arch && \ + printf '[core]\nInclude = /etc/pacman.d/mirrorlist\n\n[extra]\nInclude = /etc/pacman.d/mirrorlist\n\n[alarm]\nInclude = /etc/pacman.d/mirrorlist\n\n[aur]\nInclude = /etc/pacman.d/mirrorlist\n' > /tmp/repos.conf ;; \ + *) \ + echo "Unsupported architecture: ${TARGETARCH}" && exit 1 ;; \ + esac + +RUN mkdir -p /etc/pacman.d && \ + cat /tmp/repos.conf >> /etc/pacman.conf + +RUN if [ "${TARGETARCH}" = "amd64" ]; then \ + printf 'Server = https://mirror.omarchy.org/$repo/os/$arch\nServer = https://mirror.rackspace.com/archlinux/$repo/os/$arch\nServer = https://geo.mirror.pkgbuild.com/$repo/os/$arch\n' > /etc/pacman.d/mirrorlist; \ + else \ + curl -L "https://raw.githubusercontent.com/archlinuxarm/PKGBUILDs/master/core/pacman-mirrorlist/mirrorlist" 2>/dev/null | \ + sed -E 's/^\s*#\s*Server\s*=/Server =/g' > /etc/pacman.d/mirrorlist && \ + sed -i 's/\$arch/aarch64/g' /etc/pacman.d/mirrorlist; \ + fi + +# Bootstrap keyrings (required before pacstrap can verify packages) +RUN mkdir -p /usr/share/pacman/keyrings && \ + if [ "${TARGETARCH}" = "arm64" ]; then \ + KEYRING_URL="https://raw.githubusercontent.com/archlinuxarm/PKGBUILDs/master/core/archlinuxarm-keyring/" && \ + for file in archlinuxarm-revoked archlinuxarm-trusted archlinuxarm.gpg; do \ + curl -fsSL "${KEYRING_URL}${file}" -o /usr/share/pacman/keyrings/${file} || exit 1; \ + done && \ + BOOTSTRAP_EXTRA="archlinuxarm-keyring"; \ + else \ + mkdir /tmp/archlinux-keyring && \ + curl -fsSL https://archlinux.org/packages/core/any/archlinux-keyring/download | \ + unzstd | tar -C /tmp/archlinux-keyring -xv && \ + mv /tmp/archlinux-keyring/usr/share/pacman/keyrings/* /usr/share/pacman/keyrings/ && \ + BOOTSTRAP_EXTRA=""; \ + fi && \ + pacman-key --init && \ + pacman-key --populate + +RUN mkdir /rootfs && \ + if [ "${TARGETARCH}" = "arm64" ]; then \ + BOOTSTRAP_EXTRA="archlinuxarm-keyring"; \ + else \ + BOOTSTRAP_EXTRA=""; \ + fi && \ + pacstrap-docker /rootfs base ${BOOTSTRAP_EXTRA} && \ + cp /etc/pacman.conf /rootfs/etc/pacman.conf && \ + cp /etc/pacman.d/mirrorlist /rootfs/etc/pacman.d/mirrorlist && \ + echo "en_US.UTF-8 UTF-8" > /rootfs/etc/locale.gen && \ + echo "LANG=en_US.UTF-8" > /rootfs/etc/locale.conf && \ + rm -rf /rootfs/var/lib/pacman/sync/* \ + /rootfs/var/cache/pacman/pkg/* \ + /rootfs/tmp/* + +# ------------------------------------------------------------------------------ +# Stage 2: Build Environment +# ------------------------------------------------------------------------------ +FROM scratch AS builder + +ARG TARGETARCH + +COPY --from=bootstrapper /rootfs/ / + +ENV LANG=en_US.UTF-8 +ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +RUN ln -sf /usr/lib/os-release /etc/os-release && \ + locale-gen && \ + pacman-key --init && \ + if pacman -Q archlinuxarm-keyring >/dev/null 2>&1; then \ + pacman-key --populate archlinux archlinuxarm && \ + pacman-key --lsign-key 77193F152BDBE6A6; \ + else \ + pacman-key --populate archlinux; \ + fi + +# Setup Omarchy keyring manually before adding repo (avoids keyserver trust issues) +# Note: Repository is removed at the end since build scripts add it dynamically +RUN pacman-key --recv-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 --keyserver keys.openpgp.org && \ + pacman-key --lsign-key 40DFB630FF42BCFFB047046CF0134EE680CAC571 && \ + printf '\n[omarchy]\nSigLevel = Optional\nServer = https://pkgs.omarchy.org/$arch\n' >> /etc/pacman.conf && \ + pacman -Sy --noconfirm && \ + pacman -S --noconfirm omarchy-keyring && \ + pacman-key --populate omarchy && \ + sed -i '/^\[omarchy\]/,/^$/d' /etc/pacman.conf + +RUN pacman -Syu --noconfirm && \ + pacman -S --noconfirm \ + base-devel \ + git \ + sudo \ + wget \ + curl \ + jq \ + gnupg && \ + pacman -Scc --noconfirm && \ + rm -rf /var/cache/pacman/pkg/* + +# makepkg cannot run as root +RUN useradd -m -G wheel -s /bin/bash builder && \ + echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ + mkdir -p /home/builder/.gnupg && \ + chmod 700 /home/builder/.gnupg && \ + chown -R builder:builder /home/builder + +RUN sed -i 's/^#MAKEFLAGS=.*/MAKEFLAGS="-j$(nproc)"/' /etc/makepkg.conf && \ + sed -i 's/^COMPRESSZST=.*/COMPRESSZST=(zstd -c -z -q --threads=0 -)/' /etc/makepkg.conf + +RUN rm -rf /etc/pacman.d/gnupg/{openpgp-revocs.d/,private-keys-v1.d/,pubring.gpg~,gnupg.S.}* + +USER builder +WORKDIR /src + +CMD ["/bin/bash"] + +LABEL maintainer="Omarchy " +LABEL description="Multi-architecture Arch Linux package build environment" +LABEL version="2.0" +LABEL architectures="x86_64,aarch64" diff --git a/build/Dockerfile.x86_64 b/build/Dockerfile.x86_64 deleted file mode 100644 index bd6af102..00000000 --- a/build/Dockerfile.x86_64 +++ /dev/null @@ -1,23 +0,0 @@ -FROM archlinux:latest - -# Update system and install build tools -RUN pacman -Syu --noconfirm && \ - pacman -S --noconfirm base-devel git sudo wget jq gnupg - -# Import Omarchy signing key into pacman keyring -RUN pacman-key --init && \ - pacman-key --recv-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 --keyserver keys.openpgp.org && \ - pacman-key --lsign-key 40DFB630FF42BCFFB047046CF0134EE680CAC571 - -# Create build user (required for makepkg - cannot run as root) -RUN useradd -m -G wheel builder && \ - echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers - -USER builder -WORKDIR /src - -# Setup GPG directory -RUN mkdir -p ~/.gnupg && chmod 700 ~/.gnupg - -# Default command -CMD ["/build/build.sh"] diff --git a/build/pacstrap-docker b/build/pacstrap-docker new file mode 100755 index 00000000..0e3051fa --- /dev/null +++ b/build/pacstrap-docker @@ -0,0 +1,23 @@ +#!/bin/bash +# Simplified pacstrap for Docker (doesn't require mounts) + +set -e + +newroot=$1 +shift +pacman_args=("${@:-base}") + +[[ -d "$newroot" ]] || { echo "ERROR: $newroot is not a directory"; exit 1; } + +echo "==> Creating install root at $newroot" +mkdir -m 0755 -p "$newroot"/var/{cache/pacman/pkg,lib/pacman,log} "$newroot"/{dev,run,etc} +mkdir -m 1777 -p "$newroot"/tmp +mkdir -m 0555 -p "$newroot"/{sys,proc} + +echo "==> Installing packages to $newroot" +if ! pacman -r "$newroot" -Sy --noconfirm "${pacman_args[@]}"; then + echo "ERROR: Failed to install packages" + exit 1 +fi + +echo "==> Installation complete" diff --git a/helpers/docker-helpers.sh b/helpers/docker-helpers.sh index 0b053862..ac88873c 100644 --- a/helpers/docker-helpers.sh +++ b/helpers/docker-helpers.sh @@ -1,6 +1,5 @@ # Docker helper functions for Omarchy package build system -# Check Docker is available and running check_docker() { if ! command -v docker &>/dev/null; then print_error "Docker is not installed" @@ -14,26 +13,31 @@ check_docker() { fi } -# Build the Docker image if needed build_docker_image() { local build_dir="$1" local arch="${2:-x86_64}" - local dockerfile="$build_dir/Dockerfile.$arch" local platform="" local image_tag="omarchy-pkg-builder:latest-$arch" - # Set platform for Docker build - if [[ "$arch" == "aarch64" ]]; then - platform="--platform linux/arm64" - elif [[ "$arch" == "x86_64" ]]; then - platform="--platform linux/amd64" - fi + case "$arch" in + x86_64) platform="linux/amd64" ;; + aarch64) platform="linux/arm64" ;; + *) + print_error "Unsupported architecture: $arch" + exit 1 + ;; + esac - print_info "Building Docker image for $arch..." - docker build $platform -t "$image_tag" -f "$dockerfile" "$build_dir" + print_info "Building Docker image for $arch ($platform)..." + + docker buildx build \ + --platform "$platform" \ + --load \ + -t "$image_tag" \ + -f "$build_dir/Dockerfile" \ + "$build_dir" } -# Make directory writable by Docker container user make_dir_writable() { local dir="$1" if [ "$(id -u)" -eq 0 ]; then @@ -42,22 +46,3 @@ make_dir_writable() { sudo chown -R $(id -u):$(id -g) "$dir" 2>/dev/null || chmod -R 777 "$dir" fi } - -# Run a Docker container with standard setup -run_docker() { - local script="$1" - local arch="${2:-x86_64}" - shift 2 - local -a args=("$@") - local image_tag="omarchy-pkg-builder:latest-$arch" - local platform="" - - # Set platform for Docker run - if [[ "$arch" == "aarch64" ]]; then - platform="--platform linux/arm64" - elif [[ "$arch" == "x86_64" ]]; then - platform="--platform linux/amd64" - fi - - docker run --rm $platform "${args[@]}" "$image_tag" "$script" -} From 724e083a2839c8ebb37f65bd41b446ac309a70a0 Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Wed, 29 Oct 2025 22:57:53 -0400 Subject: [PATCH 3/5] Add missing function back --- helpers/docker-helpers.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/helpers/docker-helpers.sh b/helpers/docker-helpers.sh index ac88873c..6c515012 100644 --- a/helpers/docker-helpers.sh +++ b/helpers/docker-helpers.sh @@ -38,6 +38,15 @@ build_docker_image() { "$build_dir" } +get_platform_arg() { + local arch="$1" + case "$arch" in + x86_64) echo "--platform linux/amd64" ;; + aarch64) echo "--platform linux/arm64" ;; + *) echo "" ;; + esac +} + make_dir_writable() { local dir="$1" if [ "$(id -u)" -eq 0 ]; then From dacf0cd9a4f97b4343bfb1644dce5783286728de Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Thu, 30 Oct 2025 00:36:19 -0400 Subject: [PATCH 4/5] Simplify and solve cache issue --- bin/build | 5 ----- build/build.sh | 35 ++++++----------------------------- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/bin/build b/bin/build index de933333..e8013d15 100755 --- a/bin/build +++ b/bin/build @@ -103,11 +103,6 @@ DOCKER_ARGS=( -v "$BUILD_ROOT/pkgbuilds:/pkgbuilds:ro" ) -# Use local pacman cache if you already have one on host to speed up repeat runs -if [ -d "/var/cache/pacman/pkg" ]; then - DOCKER_ARGS+=(-v "/var/cache/pacman/pkg:/var/cache/pacman/pkg") -fi - # Run the builder with assembled args IMAGE_TAG="omarchy-pkg-builder:latest-$ARCH" PLATFORM_ARG=$(get_platform_arg "$ARCH") diff --git a/build/build.sh b/build/build.sh index 2dfa90cf..6ab250f3 100755 --- a/build/build.sh +++ b/build/build.sh @@ -16,13 +16,8 @@ echo "==> Configuring Omarchy repositories for dependency resolution..." # Always add omarchy-build repo (for incremental builds) # Packages in build-output are unsigned, so use SigLevel = Never -# Use the build-output dir as additional cache to avoid file copying issues sudo tee -a /etc/pacman.conf > /dev/null </dev/null | grep -v '\.sig$' | head -1) + # Find ALL package files (handles split packages) + local new_pkgs=($(ls -t ${pkg}-*.pkg.tar.* 2>/dev/null | grep -v '\.sig$' | grep -v 'omarchy-build\.db')) - if [[ -n "$new_pkg" ]]; then - echo " Adding $new_pkg to database..." - - # Add to omarchy-build database - repo-add omarchy-build.db.tar.zst "$new_pkg" 2>&1 | grep -E "==>|error" || true + if [[ ${#new_pkgs[@]} -gt 0 ]]; then + repo-add omarchy-build.db.tar.zst "${new_pkgs[@]}" >/dev/null 2>&1 ln -sf omarchy-build.db.tar.zst omarchy-build.db - - # Refresh pacman databases so it sees the new package - echo " Refreshing pacman database..." - sudo pacman -Sy 2>&1 | grep -E "omarchy-build|error" || true - - # Verify the package is in the database - if pacman -Sl omarchy-build 2>/dev/null | grep -q "^omarchy-build $pkg "; then - echo " ✓ Package available in omarchy-build repo" - else - echo " ⚠ Warning: Package not found in omarchy-build repo" - fi + sudo pacman -Sy >/dev/null 2>&1 fi cd /src/$pkg From 5b28e55d9138ba61ac81cd7dcf797660dfd997f7 Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Thu, 30 Oct 2025 00:56:48 -0400 Subject: [PATCH 5/5] Update docs --- README.md | 312 ++++++++++++++++++++------------------------------- bin/sync-aur | 24 +++- 2 files changed, 144 insertions(+), 192 deletions(-) diff --git a/README.md b/README.md index 5e7962c2..699879da 100644 --- a/README.md +++ b/README.md @@ -1,261 +1,195 @@ # Omarchy Package Repository -This repository manages the Omarchy Package Repository, building a host of PKGBUILDs and facilitating syncing from AUR where necessary. +Build system for the Omarchy Package Repository. Builds PKGBUILDs from local sources and AUR, signs them, and syncs to production. -## Overview +**Multi-Architecture**: Supports both x86_64 and aarch64 (ARM64). -The build system uses Docker to create a clean, reproducible build environment. Packages are built unsigned, then signed in a separate step, promoted to production, and synced to a remote server. +## Prerequisites +### aarch64 Builds (Optional) -**Multi-Architecture Support**: The build system supports both **x86_64** and **aarch64** (ARM64) architectures. See [docs/AARCH64_BUILDS.md](docs/AARCH64_BUILDS.md) for aarch64 setup and usage. +To build ARM64 packages on x86_64, enable QEMU emulation: -### Directory Structure +```bash +# Run after each reboot +docker run --privileged --rm tonistiigi/binfmt --install arm64 +# Verify +docker run --rm --platform linux/arm64 alpine:latest uname -m +# Should output: aarch64 ``` -omarchy-pkgs/ -├── pkgbuilds/ # Source PKGBUILDs (one directory per package) -├── build-output/ # Temporary build workspace -├── pkgs.omarchy.org/ # Final signed packages -├── build/ # Build scripts that run inside of the Docker container -├── bin/ # Command-line tools -└── logs/ # Build and operation logs -``` + +**Note**: aarch64 builds use QEMU and slower than native x86_64 builds. ## Quick Start -### Complete Release Workflow - -Build, sign, promote, clean, and sync in one command: +### Complete Workflow ```bash +# Build, sign, promote, clean, and sync bin/repo release + +# Single package +bin/repo release --package omarchy-nvim + +# ARM64 +bin/repo release --arch aarch64 --package omarchy-nvim ``` -With options: -```bash -bin/repo release --skip-prod-check # Skip production confirmation -bin/repo release --sync-remote dev-pkgs:/ # Sync to dev remote instead -bin/repo release --package omarchy-nvim # Build only one package -bin/repo release --package yay cursor-bin omarchy-nvim # Build multiple packages -``` - -### Step-by-Step Workflow +### Step-by-Step ```bash -# 1. Build packages (unsigned) -bin/repo build - -# 2. Sign all built packages (sitting in `build-output`) -bin/repo sign - -# 3. Promote to production directory (copy from `build-output` -> `pkgs.omarchy.org`) -bin/repo promote - -# 4. Clean old versions and update database -bin/repo clean - -# 5. Sync to remote server -bin/repo sync pkgs.omarchy.org/x86_64 +bin/repo build # Build (unsigned) +bin/repo sign # Sign packages +bin/repo promote # Copy to production +bin/repo clean # Remove old versions +bin/repo sync pkgs.omarchy.org/x86_64 # Sync to remote ``` ## Commands -### `bin/repo build` +### Build -Builds packages from `pkgbuilds/` directory in a Docker container. - -**Options:** -- `--package ` - Build only a specific package -- `--arch ` - Target architecture (default: x86_64) - -**What it does:** -- Clears `build-output/` directory -- Builds packages in dependency order -- Creates unsigned `.pkg.tar.zst` files in `build-output/x86_64/` -- Skips packages that are already up-to-date in `pkgs.omarchy.org/` - -**Examples:** ```bash -bin/repo build # Build all packages (x86_64) -bin/repo build --package omarchy-nvim # Build only one package -bin/repo build --package yay omarchy-nvim cursor-bin # Build multiple packages -bin/repo build --arch aarch64 # Build for ARM64/aarch64 +bin/repo build # All packages (x86_64) +bin/repo build --package yay cursor-bin # Specific packages +bin/repo build --arch aarch64 # ARM64 ``` -### `bin/repo sign` +**Output**: Unsigned `.pkg.tar.zst` in `build-output/` -Signs all unsigned packages in `build-output/`. +### Sign -**What it does:** -- Fetches GPG key and passphrase from env or 1Password -- Signs all `.pkg.tar.zst` files - -### `bin/repo promote` - -Copies signed packages from `build-output/` to `pkgs.omarchy.org/`. - -**Options:** -- `--arch ` - Target architecture (default: x86_64) -- `--dry-run` - Preview what would be copied - -**What it does:** -- Copies all packages and signatures to production directory -- Cleans up `build-output/` after successful promotion - -**Examples:** ```bash -bin/repo promote -bin/repo promote --dry-run +bin/repo sign ``` -### `bin/repo clean` +Fetches GPG key from 1Password or environment, signs all packages in `build-output/`. -Removes old package versions and updates the repository database. +### Promote -**Options:** -- `--keep N` - Keep N versions of each package (default: 2) -- `--dry-run` - Preview what would be removed -- `--usage` - Show disk usage statistics +```bash +bin/repo promote # Copy to production +bin/repo promote --arch aarch64 # ARM64 +bin/repo promote --dry-run # Preview +``` -**What it does:** -- Removes old package versions (keeps latest 2 by default) -- Updates `omarchy.db.tar.zst` repository database -- Shows disk usage and statistics +Copies signed packages from `build-output/` → `pkgs.omarchy.org/`. + +### Clean -**Examples:** ```bash bin/repo clean # Keep 2 versions bin/repo clean --keep 3 # Keep 3 versions -bin/repo clean --dry-run # Preview cleanup -bin/repo clean --usage # Show disk usage +bin/repo clean --dry-run # Preview ``` -### `bin/repo sync` +Removes old versions, updates database. -Syncs the repository to a remote server using rclone. +### Sync -**Arguments:** -- `` - Local directory to sync (e.g., `pkgs.omarchy.org/x86_64`) - -**Options:** -- `--remote ` - Rclone remote destination (default: `pkgs.omarchy.org:omarchy-pkgs`) -- `--skip-prod-check` - Skip production confirmation - -**What it does:** -- Syncs packages to remote (uses `--ignore-existing` to preserve versions) -- Syncs database files with checksums -- Prompts for confirmation when syncing to production - -**Examples:** ```bash -bin/repo sync pkgs.omarchy.org/x86_64 # Sync to production -bin/repo sync pkgs.omarchy.org/x86_64 --skip-prod-check # Skip confirmation -bin/repo sync pkgs.omarchy.org/x86_64 --remote dev-pkgs:/# Sync to dev +bin/repo sync pkgs.omarchy.org/x86_64 # Production +bin/repo sync pkgs.omarchy.org/aarch64 # ARM64 +bin/repo sync pkgs.omarchy.org/x86_64 --skip-prod-check # No confirmation ``` -### `bin/repo release` +Syncs to remote server using rclone. -Runs the complete release workflow in sequence. +### Other -**Options:** -- `--package ` - Build only specific package(s) (space-separated) -- `--arch ` - Target architecture (default: x86_64) -- `--sync-remote ` - Rclone remote for sync (default: production) -- `--skip-prod-check` - Skip production confirmation - -**What it does:** -1. Builds packages -2. Signs packages -3. Promotes to production -4. Cleans old versions -5. Syncs to remote - -**Examples:** ```bash -bin/repo release # Full workflow -bin/repo release --skip-prod-check # Skip prod confirmation -bin/repo release --sync-remote dev-pkgs:/ # Sync to dev -bin/repo release --package omarchy-nvim # Single package -bin/repo release --package yay cursor-bin omarchy-nvim # Multiple packages +bin/repo list # List packages +bin/repo remove # Remove package +bin/repo update # Update database ``` -### Other Commands +## Directory Structure -**`bin/repo list`** - List all packages in the repository -```bash -bin/repo list +``` +omarchy-pkgs/ +├── pkgbuilds/ # Source PKGBUILDs +├── build-output/ # Unsigned packages (temporary) +│ ├── x86_64/ +│ └── aarch64/ +├── pkgs.omarchy.org/ # Signed packages (production) +│ ├── x86_64/ +│ └── aarch64/ +├── build/ # Build scripts (in container) +└── bin/ # CLI tools (on host) ``` -**`bin/repo remove `** - Remove a package from the repository -```bash -bin/repo remove yay -``` - -**`bin/repo update`** - Update the repository database (usually done automatically by `clean`) -```bash -bin/repo update -``` - -## Adding New Packages +## Adding Packages ### From AUR -1. Add package name to `build/packages/omarchy-aur.packages` (for future syncing) -2. Sync PKGBUILD to local directory: - ```bash - bin/sync-aur package-name - ``` -3. Build and release: - ```bash - bin/repo release --package package-name - ``` +```bash +# Add to sync list +echo "package-name" >> build/packages/omarchy-aur.packages -#### Maintaining Local Patches for AUR Packages +# Sync PKGBUILD +bin/sync-aur package-name -If you need to maintain local modifications to AUR packages that persist through `aur-sync` updates: +# Build and release +bin/repo release --package package-name +``` -1. Create a `patches/` directory inside the package directory: - ```bash - mkdir pkgbuilds/package-name/patches - ``` +#### Local Patches for AUR Packages -2. Create patch files for your modifications: - ```bash - cd pkgbuilds/package-name - # Make your changes to PKGBUILD or other files - git diff > patches/my-fix.patch - ``` +Create `pkgbuilds/package-name/patches/*.patch` to maintain modifications across AUR syncs: -3. When `bin/sync-aur` runs, it will automatically apply all `.patch` files found in the `patches/` directory after syncing from AUR. - -**Example:** The `opencode` package has `patches/fix-parcel-watcher.patch` which adds platform-specific `@parcel/watcher` installation to the build process. +```bash +cd pkgbuilds/package-name +# Make changes +git diff > patches/my-fix.patch +# Next sync will auto-apply patches +``` ### Custom Package -1. Create directory in `pkgbuilds/`: - ```bash - mkdir pkgbuilds/my-package - ``` -2. Add PKGBUILD and any additional files -3. Build and release: - ```bash - bin/repo release --package my-package - ``` +```bash +mkdir pkgbuilds/my-package +# Add PKGBUILD and files +bin/repo release --package my-package +``` -## Package Dependencies +## Architecture-Specific Notes -The build system automatically handles dependencies between packages being built. For example, if `aether` depends on `hyprshade`, the build system will: +### x86_64 +- Native builds (fast) +- Mirrors: mirror.omarchy.org, rackspace, pkgbuild.com -1. Detect the dependency relationship -2. Build `hyprshade` first -3. Add it to the `omarchy-build` temporary repository -4. Build `aether` (which can now install `hyprshade` from `omarchy-build`) +### aarch64 +- QEMU emulation required on x86_64 hosts (slower) +- Uses Arch Linux ARM repositories +- Additional repos: `[alarm]`, `[aur]` +- Same workflow, just add `--arch aarch64` -This works through two internal repositories: -- **`omarchy-build`** - Temporary repo in `build-output/` (unsigned packages, used during build) -- **`omarchy`** - Production repo in `pkgs.omarchy.org/` (signed packages) +### Building for Both Architectures + +```bash +# Build x86_64 +bin/repo release --package myapp + +# Build aarch64 +bin/repo release --arch aarch64 --package myapp + +# Sync both +bin/repo sync pkgs.omarchy.org/x86_64 +bin/repo sync pkgs.omarchy.org/aarch64 +``` + +## Dependency Resolution + +The build system automatically handles inter-package dependencies: + +1. Parses `depends=()` and `makedepends=()` from PKGBUILDs +2. Builds in correct order +3. Makes newly-built packages available via temporary `[omarchy-build]` repo + +Example: If `aether` depends on `hyprshade`, `hyprshade` is built first. ## Version Management Packages are only rebuilt if: -- PKGBUILD version is newer than the version in the repository DB -- Package doesn't exist in production yet +- PKGBUILD version is newer than repository version +- Package doesn't exist in production diff --git a/bin/sync-aur b/bin/sync-aur index 5407cb8b..72a4cd81 100755 --- a/bin/sync-aur +++ b/bin/sync-aur @@ -11,9 +11,27 @@ trap "rm -rf $TEMP_DIR" EXIT # Parse arguments SPECIFIC_PACKAGES=() -if [[ $# -gt 0 ]]; then - SPECIFIC_PACKAGES=("$@") -fi +for arg in "$@"; do + case "$arg" in + -h|--help) + echo "Usage: $0 [PACKAGE...]" + echo "" + echo "Sync AUR packages to pkgbuilds/ directory" + echo "" + echo "Arguments:" + echo " PACKAGE One or more package names to sync (optional)" + echo "" + echo "Examples:" + echo " $0 # Sync all packages from omarchy-aur.packages" + echo " $0 yay # Sync only the yay package" + echo " $0 yay paru # Sync yay and paru packages" + exit 0 + ;; + *) + SPECIFIC_PACKAGES+=("$arg") + ;; + esac +done print_header "AUR Package Sync"