Files
Joachim Schlöffel 50e8eaa62a
Some checks failed
Build Alpine Packages / build-and-publish (push) Has been cancelled
Cache Rust build artifacts for Alpine packages
2026-06-09 10:47:17 +02:00

160 lines
4.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
command_name="${1:-build}"
requested_arch="${2:-${ALPINE_ARCH:-x86_64}}"
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
. "${repo_root}/scripts/apk/package-lib.sh"
alpine_version="${ALPINE_VERSION:-3.23}"
repo_name="${ALPINE_REPO_NAME:-local}"
build_platform="${ALPINE_BUILD_PLATFORM:-linux/amd64}"
builder_uid="$(id -u)"
builder_gid="$(id -g)"
if [[ "${builder_uid}" == "0" ]]; then
builder_uid=1000
fi
if [[ "${builder_gid}" == "0" ]]; then
builder_gid=1000
fi
cache_scope_from_remote() {
local remote
local path
local owner
local repo
remote="$(git -C "${repo_root}" remote get-url origin 2>/dev/null || true)"
remote="${remote%.git}"
case "${remote}" in
ssh://*/*/*)
path="${remote#ssh://*/}"
;;
http://*/*/*|https://*/*/*)
path="${remote#*://*/}"
;;
*:*)
path="${remote#*:}"
;;
*)
path="$(basename "${repo_root}")"
;;
esac
owner="$(basename "$(dirname "${path}")")"
repo="$(basename "${path}")"
if [[ -n "${owner}" && "${owner}" != "." && -n "${repo}" ]]; then
printf '%s-%s\n' "${owner}" "${repo}" | sed 's/[^A-Za-z0-9_.-]/-/g'
else
printf '%s\n' "$(basename "${repo_root}")" | sed 's/[^A-Za-z0-9_.-]/-/g'
fi
}
validate_arch() {
case "$1" in
x86_64|aarch64) ;;
*) printf 'unsupported Alpine architecture: %s\n' "$1" >&2; return 2 ;;
esac
}
run_for_arch() {
local arch="$1"
local subcommand="$2"
local package_dir="$3"
local image_name
local container_package_dir
local package_name
local cache_scope
local cache_prefix
validate_arch "${arch}"
apk_validate_package_dir "${package_dir}"
package_name="$(apk_package_name "${package_dir}")"
container_package_dir="$(apk_container_package_dir "${repo_root}" "${package_dir}")"
image_name="${ALPINE_APK_BUILDER_IMAGE:-alpine-apk-builder:${arch}}"
cache_scope="${ALPINE_APK_CACHE_SCOPE:-$(cache_scope_from_remote)}"
cache_prefix="${ALPINE_APK_CACHE_PREFIX:-alpine-apk}-${cache_scope}-${package_name}-${arch}"
docker build \
--platform "${build_platform}" \
--build-arg "ALPINE_VERSION=${alpine_version}" \
--build-arg "BUILDER_UID=${builder_uid}" \
--build-arg "BUILDER_GID=${builder_gid}" \
-f "${repo_root}/scripts/apk/Dockerfile" \
-t "${image_name}" \
"${repo_root}"
docker_args=(--rm --platform "${build_platform}")
if [[ -t 0 && -t 1 ]]; then
docker_args+=(-it)
fi
docker run "${docker_args[@]}" \
-e "ALPINE_ARCH=${arch}" \
-e "CARCH=${arch}" \
-e "ALPINE_REPO_NAME=${repo_name}" \
-e "APKBUILD_DIR=${container_package_dir}" \
-e "CARGO_HOME=/home/builder/.cache/cargo" \
-e "CARGO_TARGET_DIR=/home/builder/.cache/cargo-target" \
-e "PACKAGER=${PACKAGER:-Joachim Schlöffel <me@joachim-schloeffel.com>}" \
-e "RUSTUP_HOME=/home/builder/.cache/rustup" \
-v "${cache_prefix}-cargo:/home/builder/.cache/cargo" \
-v "${cache_prefix}-cargo-target:/home/builder/.cache/cargo-target" \
-v "${cache_prefix}-rustup:/home/builder/.cache/rustup" \
-v "${repo_root}:/work" \
-v "${repo_root}/.cache/abuild:/home/builder/.abuild" \
-v "${repo_root}/.cache/apk-distfiles:/var/cache/distfiles" \
-v "${repo_root}/packages:/home/builder/packages" \
"${image_name}" \
"${subcommand}"
}
mkdir -p \
"${repo_root}/.cache/abuild" \
"${repo_root}/.cache/apk-distfiles" \
"${repo_root}/packages"
case "${command_name}" in
build-all)
while IFS= read -r package_dir; do
for arch in ${ALPINE_ARCHES:-x86_64 aarch64}; do
if ! apk_package_supports_arch "${package_dir}" "${arch}"; then
printf 'Skipping %s for unsupported arch %s\n' "$(apk_package_name "${package_dir}")" "${arch}"
continue
fi
run_for_arch "${arch}" build "${package_dir}"
done
done < <(apk_package_dirs "${repo_root}")
;;
build|checksum|lint)
while IFS= read -r package_dir; do
if [[ "${command_name}" == "build" ]] && ! apk_package_supports_arch "${package_dir}" "${requested_arch}"; then
printf 'Skipping %s for unsupported arch %s\n' "$(apk_package_name "${package_dir}")" "${requested_arch}"
continue
fi
run_for_arch "${requested_arch}" "${command_name}" "${package_dir}"
done < <(apk_package_dirs "${repo_root}")
;;
shell)
package_count=0
selected_package_dir=""
while IFS= read -r package_dir; do
package_count=$((package_count + 1))
selected_package_dir="${package_dir}"
done < <(apk_package_dirs "${repo_root}")
if [[ "${package_count}" -ne 1 ]]; then
printf 'apk:shell needs exactly one package; set ALPINE_PACKAGE=<name>\n' >&2
exit 2
fi
run_for_arch "${requested_arch}" "${command_name}" "${selected_package_dir}"
;;
*)
printf 'unknown command: %s\n' "${command_name}" >&2
printf 'usage: %s [build|build-all|checksum|lint|shell] [x86_64|aarch64]\n' "$0" >&2
exit 2
;;
esac