Skip to content

Instantly share code, notes, and snippets.

@fuhry
Created May 21, 2024 18:13
Show Gist options
  • Save fuhry/688ed60f475e8fd0f8ec129a6c10eef1 to your computer and use it in GitHub Desktop.
Save fuhry/688ed60f475e8fd0f8ec129a6c10eef1 to your computer and use it in GitHub Desktop.
#!/bin/bash
set -eu
###############################################################################
# CONSTANTS
declare -r CUSER="build"
declare -r DOCKER="docker"
declare -r IMAGE="archlinux:latest"
###############################################################################
# FUNCTIONS
getpkg_local_fs() {
local src="$1"
local container_id="$2"
$DOCKER cp -a "${src}" "${container_id}:/home/${CUSER}/pkg"
$DOCKER exec -u root "${container_id}" chown -R ${CUSER}:${CUSER} /home/${CUSER}/pkg
}
getpkg_remote_git() {
local src="$1"
local container_id="$2"
$DOCKER exec -u "${CUSER}" "${container_id}" git clone "${repo}" "/home/${CUSER}/pkg"
}
###############################################################################
# PROGRAM
umask 022
repo="${1:-}"
if [[ "$repo" =~ ^/ ]] && test -d "$repo" && test -f "${repo}/PKGBUILD"; then
echo "Using local repository at ${repo}" >&2
repo_driver="getpkg_local_fs"
elif [[ "$repo" =~ ^aur: ]]; then
repo="https://aur.archlinux.org/${repo:4}.git"
repo_driver="getpkg_remote_git"
elif [[ "$repo" =~ ^(git|https?):// ]]; then
echo "Using Git repository at ${repo}" >&2
repo_driver="getpkg_remote_git"
else
echo "Usage: $0 local_directory_or_git_repository" >&2
exit 1
fi
CID="$(${DOCKER} run -dit "${IMAGE}" /bin/bash --login)"
trap "set +e ; (${DOCKER} stop -t1 ${CID} ; ${DOCKER} rm -f ${CID}) >/dev/null 2>&1" EXIT
${DOCKER} start "${CID}"
${DOCKER} exec -u root "${CID}" pacman -Sy
${DOCKER} exec -u root "${CID}" pacman -Su --noconfirm
${DOCKER} exec -u root "${CID}" pacman -S --needed --noconfirm base-devel git sudo
${DOCKER} exec -i -u root "${CID}" tee /etc/sudoers.d/10build <<< "build ALL=(ALL) NOPASSWD: ALL"
${DOCKER} exec -u root "${CID}" chmod 0400 /etc/sudoers.d/10build
${DOCKER} exec -u root "${CID}" bash -c 'getent passwd build || useradd -m -s /bin/bash build'
${DOCKER} exec -u root "${CID}" install -d -m0700 -o${CUSER} -g${CUSER} /home/${CUSER}
if test -f /etc/makepkg.conf; then
${DOCKER} cp /etc/makepkg.conf ${CID}:/etc/makepkg.conf
else
n_cpu="$(lscpu -y -p=CPU | grep -v '^#' | wc -l)"
${DOCKER} exec -u root "${CID}" bash -c "echo 'MAKEFLAGS=-j${n_cpu}' | tee -a /etc/makepkg.conf"
fi
"${repo_driver}" "${repo}" "${CID}"
${DOCKER} exec -u "${CUSER}" -w "/home/${CUSER}/pkg" "${CID}" bash -c "makepkg --printsrcinfo --nosign | grep -E '^\s*validpgpkeys = ' | grep -Eo '[A-F0-9]{40}' | xargs -i -n1 --no-run-if-empty gpg --recv-keys 0x{}"
${DOCKER} exec -it -u "${CUSER}" -w "/home/${CUSER}/pkg" "${CID}" makepkg -fc --syncdeps --noconfirm --nosign --nocheck
pkg_files=($(${DOCKER} exec -u "${CUSER}" -w "/home/${CUSER}/pkg" "${CID}" bash -c 'shopt -s nullglob; echo *.pkg.tar.*'))
if [ "${#pkg_files[@]}" = 0 ]; then
echo "ERROR: No package files were produced." >&2
exit 1
fi
for f in "${pkg_files[@]}"; do
echo "Saving artifact: $f"
$DOCKER cp "${CID}:/home/${CUSER}/pkg/${f}" ./
gpg --detach-sign "${f}"
chmod 0644 "${f}" "${f}.sig"
done
echo "Successfully produced the following package files:" >&2
for f in "${pkg_files[@]}"; do
echo "- ${f}"
done
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment