Optimize Alpine packaging workflow
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 2h16m43s

This commit is contained in:
Joachim Schlöffel
2026-07-12 10:24:15 +02:00
parent faf7d5e404
commit 89db986774
17 changed files with 125 additions and 166 deletions
+5
View File
@@ -0,0 +1,5 @@
.git
.cache
packages
packaging/**/pkg
packaging/**/src
+2 -1
View File
@@ -39,7 +39,7 @@ jobs:
steps: steps:
- name: Prepare Environment - name: Prepare Environment
run: | run: |
apk add --no-cache --update abuild-rootbld alpine-sdk atools-apkbuild-lint bash ca-certificates curl doas git nodejs sudo tar apk add --no-cache --update abuild-rootbld alpine-sdk atools-apkbuild-lint bash ca-certificates curl doas git nodejs rsync shellcheck sudo tar
mkdir -p "$ALPINE_APK_REPO_CACHE" "$CARGO_HOME" "$RUSTUP_HOME" "$CARGO_TARGET_DIR" mkdir -p "$ALPINE_APK_REPO_CACHE" "$CARGO_HOME" "$RUSTUP_HOME" "$CARGO_TARGET_DIR"
chown -R 1000:1000 /cache/public-alpine-packages/${{ matrix.alpine_registry_branch }} chown -R 1000:1000 /cache/public-alpine-packages/${{ matrix.alpine_registry_branch }}
@@ -50,6 +50,7 @@ jobs:
run: | run: |
scripts/apk/clean.sh scripts/apk/clean.sh
find packaging/alpine/local -mindepth 2 -maxdepth 2 -name APKBUILD -exec apkbuild-lint {} + find packaging/alpine/local -mindepth 2 -maxdepth 2 -name APKBUILD -exec apkbuild-lint {} +
scripts/apk/lint-shell.sh
scripts/apk/outdated.sh | tee update-check.txt scripts/apk/outdated.sh | tee update-check.txt
if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
{ {
+1
View File
@@ -88,6 +88,7 @@ apk:ci-build Build all configured Alpine packages directly in the curre
apk:ci-smoke Install-test built packages directly in the current Alpine environment apk:ci-smoke Install-test built packages directly in the current Alpine environment
apk:clean Remove generated Alpine package build outputs apk:clean Remove generated Alpine package build outputs
apk:lint Run Alpine APKBUILD lint in Docker apk:lint Run Alpine APKBUILD lint in Docker
apk:lint-shell Run ShellCheck for packaging automation
apk:packages List built Alpine packages and dependencies apk:packages List built Alpine packages and dependencies
apk:publish-check Run lint, multi-arch build, package listing, and smoke test apk:publish-check Run lint, multi-arch build, package listing, and smoke test
apk:publish-gitea Publish built packages to the Gitea Alpine package registry apk:publish-gitea Publish built packages to the Gitea Alpine package registry
+4
View File
@@ -35,6 +35,10 @@ run = "scripts/apk/update-generated-sources.sh"
description = "Run Alpine APKBUILD lint in Docker" description = "Run Alpine APKBUILD lint in Docker"
run = "scripts/apk/build.sh lint" run = "scripts/apk/build.sh lint"
[tasks."apk:lint-shell"]
description = "Run ShellCheck for packaging automation"
run = "scripts/apk/lint-shell.sh"
[tasks."apk:smoke"] [tasks."apk:smoke"]
description = "Install-test built packages from the local repository in Docker" description = "Install-test built packages from the local repository in Docker"
run = "scripts/apk/smoke.sh" run = "scripts/apk/smoke.sh"
@@ -2,45 +2,10 @@
set -euo pipefail set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}" repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_name="${PACKAGE_NAME:-gitea}" # shellcheck source=scripts/apk/test-install-lib.sh
package_version="${PACKAGE_VERSION:-1.26.4-r0}" . "${repo_root}/scripts/apk/test-install-lib.sh"
alpine_version="${ALPINE_VERSION:-3.24}"
arch="${ALPINE_ARCH:-x86_64}"
repository_url="${ALPINE_REPOSITORY_URL:-}"
repository_key_url="${ALPINE_REPOSITORY_KEY_URL:-}"
case "${arch}" in apk_test_install_run "${repo_root}" "${PACKAGE_NAME:-gitea}" "${PACKAGE_VERSION:-1.26.4-r0}" <<'SCRIPT'
x86_64)
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
;;
aarch64)
platform="${ALPINE_TEST_PLATFORM:-linux/arm64}"
;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
exit 2
;;
esac
if [[ -z "${repository_url}" && "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
if [[ -z "${repository_url}" && ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
printf 'run: ALPINE_PACKAGE=%s mise run apk:build\n' "${package_name}" >&2
exit 1
fi
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-e "PACKAGE_NAME=${package_name}" \
-e "PACKAGE_VERSION=${package_version}" \
-e "ALPINE_REPOSITORY_URL=${repository_url}" \
-e "ALPINE_REPOSITORY_KEY_URL=${repository_key_url}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc '
set -e set -e
if [ -n "${ALPINE_REPOSITORY_URL}" ]; then if [ -n "${ALPINE_REPOSITORY_URL}" ]; then
@@ -85,4 +50,4 @@ docker run --rm --platform "${platform}" \
rc-update add gitea default rc-update add gitea default
test -L /etc/runlevels/default/gitea test -L /etc/runlevels/default/gitea
' SCRIPT
@@ -2,43 +2,10 @@
set -euo pipefail set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}" repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_name="${PACKAGE_NAME:-greptimedb}" # shellcheck source=scripts/apk/test-install-lib.sh
alpine_version="${ALPINE_VERSION:-3.24}" . "${repo_root}/scripts/apk/test-install-lib.sh"
arch="${ALPINE_ARCH:-x86_64}"
repository_url="${ALPINE_REPOSITORY_URL:-}"
repository_key_url="${ALPINE_REPOSITORY_KEY_URL:-}"
case "${arch}" in apk_test_install_run "${repo_root}" "${PACKAGE_NAME:-greptimedb}" "${PACKAGE_VERSION:-}" <<'SCRIPT'
x86_64)
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
;;
aarch64)
platform="${ALPINE_TEST_PLATFORM:-linux/arm64}"
;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
exit 2
;;
esac
if [[ -z "${repository_url}" && "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
if [[ -z "${repository_url}" && ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
printf 'run: ALPINE_PACKAGE=%s mise run apk:build\n' "${package_name}" >&2
exit 1
fi
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-e "PACKAGE_NAME=${package_name}" \
-e "ALPINE_REPOSITORY_URL=${repository_url}" \
-e "ALPINE_REPOSITORY_KEY_URL=${repository_key_url}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc '
set -e set -e
if [ -n "${ALPINE_REPOSITORY_URL}" ]; then if [ -n "${ALPINE_REPOSITORY_URL}" ]; then
@@ -68,4 +35,4 @@ docker run --rm --platform "${platform}" \
test -f "/usr/share/doc/${PACKAGE_NAME}/config/config.md" test -f "/usr/share/doc/${PACKAGE_NAME}/config/config.md"
test -f "/usr/share/doc/${PACKAGE_NAME}/config/standalone.example.toml" test -f "/usr/share/doc/${PACKAGE_NAME}/config/standalone.example.toml"
find /etc/init.d -maxdepth 1 -name "greptimedb.*" -print | sort find /etc/init.d -maxdepth 1 -name "greptimedb.*" -print | sort
' SCRIPT
@@ -2,43 +2,10 @@
set -euo pipefail set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}" repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_name="${PACKAGE_NAME:-lavinmq}" # shellcheck source=scripts/apk/test-install-lib.sh
alpine_version="${ALPINE_VERSION:-3.24}" . "${repo_root}/scripts/apk/test-install-lib.sh"
arch="${ALPINE_ARCH:-x86_64}"
repository_url="${ALPINE_REPOSITORY_URL:-}"
repository_key_url="${ALPINE_REPOSITORY_KEY_URL:-}"
case "${arch}" in apk_test_install_run "${repo_root}" "${PACKAGE_NAME:-lavinmq}" "${PACKAGE_VERSION:-}" <<'SCRIPT'
x86_64)
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
;;
aarch64)
platform="${ALPINE_TEST_PLATFORM:-linux/arm64}"
;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
exit 2
;;
esac
if [[ -z "${repository_url}" && "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
if [[ -z "${repository_url}" && ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
printf 'run: ALPINE_PACKAGE=%s mise run apk:build\n' "${package_name}" >&2
exit 1
fi
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-e "PACKAGE_NAME=${package_name}" \
-e "ALPINE_REPOSITORY_URL=${repository_url}" \
-e "ALPINE_REPOSITORY_KEY_URL=${repository_key_url}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc '
set -e set -e
if [ -n "${ALPINE_REPOSITORY_URL}" ]; then if [ -n "${ALPINE_REPOSITORY_URL}" ]; then
@@ -72,4 +39,4 @@ docker run --rm --platform "${platform}" \
rc-update add lavinmq default rc-update add lavinmq default
test -L /etc/runlevels/default/lavinmq test -L /etc/runlevels/default/lavinmq
' SCRIPT
@@ -2,38 +2,10 @@
set -euo pipefail set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}" repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_name="${PACKAGE_NAME:-seaweedfs}" # shellcheck source=scripts/apk/test-install-lib.sh
alpine_version="${ALPINE_VERSION:-3.24}" . "${repo_root}/scripts/apk/test-install-lib.sh"
arch="${ALPINE_ARCH:-x86_64}"
case "${arch}" in apk_test_install_run "${repo_root}" "${PACKAGE_NAME:-seaweedfs}" "${PACKAGE_VERSION:-}" <<'SCRIPT'
x86_64)
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
;;
aarch64)
platform="${ALPINE_TEST_PLATFORM:-linux/arm64}"
;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
exit 2
;;
esac
if [[ "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
if [[ ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
printf 'run: ALPINE_PACKAGE=%s mise run apk:build\n' "${package_name}" >&2
exit 1
fi
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc '
set -e set -e
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/ cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
@@ -70,4 +42,4 @@ docker run --rm --platform "${platform}" \
test -d /usr/share/doc/seaweedfs/examples test -d /usr/share/doc/seaweedfs/examples
test -f /usr/share/doc/seaweedfs/examples/master.toml test -f /usr/share/doc/seaweedfs/examples/master.toml
test -f /usr/share/bash-completion/completions/weed test -f /usr/share/bash-completion/completions/weed
' SCRIPT
+24 -11
View File
@@ -19,6 +19,8 @@ if [[ "${builder_gid}" == "0" ]]; then
builder_gid=1000 builder_gid=1000
fi fi
image_name="${ALPINE_APK_BUILDER_IMAGE:-alpine-apk-builder:${alpine_version}-${builder_uid}-${builder_gid}}"
cache_scope_from_remote() { cache_scope_from_remote() {
local remote local remote
local path local path
@@ -63,7 +65,6 @@ run_for_arch() {
local arch="$1" local arch="$1"
local subcommand="$2" local subcommand="$2"
local package_dir="$3" local package_dir="$3"
local image_name
local container_package_dir local container_package_dir
local package_name local package_name
local cache_scope local cache_scope
@@ -73,19 +74,9 @@ run_for_arch() {
apk_validate_package_dir "${package_dir}" apk_validate_package_dir "${package_dir}"
package_name="$(apk_package_name "${package_dir}")" package_name="$(apk_package_name "${package_dir}")"
container_package_dir="$(apk_container_package_dir "${repo_root}" "${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_scope="${ALPINE_APK_CACHE_SCOPE:-$(cache_scope_from_remote)}"
cache_prefix="${ALPINE_APK_CACHE_PREFIX:-alpine-apk}-${cache_scope}-${package_name}-${arch}" 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}") docker_args=(--rm --platform "${build_platform}")
if [[ -t 0 && -t 1 ]]; then if [[ -t 0 && -t 1 ]]; then
docker_args+=(-it) docker_args+=(-it)
@@ -111,11 +102,33 @@ run_for_arch() {
"${subcommand}" "${subcommand}"
} }
build_builder_image() {
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}"
}
mkdir -p \ mkdir -p \
"${repo_root}/.cache/abuild" \ "${repo_root}/.cache/abuild" \
"${repo_root}/.cache/apk-distfiles" \ "${repo_root}/.cache/apk-distfiles" \
"${repo_root}/packages" "${repo_root}/packages"
case "${command_name}" in
build-all|build|checksum|lint|shell) ;;
*)
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
build_builder_image
case "${command_name}" in case "${command_name}" in
build-all) build-all)
while IFS= read -r package_dir; do while IFS= read -r package_dir; do
+1 -3
View File
@@ -72,10 +72,8 @@ while IFS= read -r package_dir; do
printf 'Building %s for %s\n' "$(basename "${package_dir}")" "${arch}" printf 'Building %s for %s\n' "$(basename "${package_dir}")" "${arch}"
( (
export ALPINE_ARCH="${arch}"
export CARCH="${arch}"
cd "${package_dir}" cd "${package_dir}"
abuild -r ALPINE_ARCH="${arch}" CARCH="${arch}" abuild -r
) )
mkdir -p "${REPODEST}/${repo_name}/${arch}" mkdir -p "${REPODEST}/${repo_name}/${arch}"
+2 -3
View File
@@ -70,7 +70,7 @@ changed_packages() {
mark_all_packages "shared build logic changed" mark_all_packages "shared build logic changed"
return return
;; ;;
packaging/alpine/local/*/APKBUILD) packaging/alpine/local/*)
package="${changed_path#packaging/alpine/local/}" package="${changed_path#packaging/alpine/local/}"
package="${package%%/*}" package="${package%%/*}"
selected["${package}"]=1 selected["${package}"]=1
@@ -231,8 +231,7 @@ sync_cache() {
prune_stale_apks prune_stale_apks
mkdir -p "${cache_root}" mkdir -p "${cache_root}"
find "${cache_root}" -mindepth 1 -maxdepth 1 -exec rm -rf {} + rsync -a --delete "${repo_dest}/" "${cache_root}/"
cp -a "${repo_dest}/." "${cache_root}/"
printf 'Updated Alpine package repository cache at %s\n' "${cache_root}" printf 'Updated Alpine package repository cache at %s\n' "${cache_root}"
} }
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
shellcheck \
"${repo_root}"/scripts/apk/*.sh \
"${repo_root}"/packaging/alpine/local/*/scripts/*.sh
+1 -1
View File
@@ -107,7 +107,7 @@ apk_package_apk_names() {
local subpackage local subpackage
local subpackages local subpackages
export CARCH="${arch}" export CARCH="${arch}"
cd "${package_dir}" cd "${package_dir}" || exit 1
# shellcheck source=/dev/null # shellcheck source=/dev/null
. ./APKBUILD . ./APKBUILD
+1
View File
@@ -6,6 +6,7 @@ repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
cd "${repo_root}" cd "${repo_root}"
mise run apk:outdated mise run apk:outdated
mise run apk:lint mise run apk:lint
mise run apk:lint-shell
mise run apk:build-all mise run apk:build-all
mise run apk:packages mise run apk:packages
mise run apk:smoke mise run apk:smoke
+4
View File
@@ -0,0 +1,4 @@
ARG ALPINE_VERSION=3.24
FROM alpine:${ALPINE_VERSION}
RUN apk add --no-cache bash openrc
+13 -2
View File
@@ -10,6 +10,7 @@ arch="${ALPINE_ARCH:-x86_64}"
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}" platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
repo_dir="${repo_root}/packages/${repo_name}/${arch}" repo_dir="${repo_root}/packages/${repo_name}/${arch}"
runtime_mode="${ALPINE_RUNTIME_TEST_MODE:-auto}" runtime_mode="${ALPINE_RUNTIME_TEST_MODE:-auto}"
runtime_image="${ALPINE_RUNTIME_TEST_IMAGE:-alpine-apk-runtime-test:${alpine_version}}"
validate_repo() { validate_repo() {
if [[ ! -d "${repo_dir}" ]]; then if [[ ! -d "${repo_dir}" ]]; then
@@ -66,10 +67,9 @@ run_hook_docker() {
-e "PACKAGE_NAME=${package_name}" \ -e "PACKAGE_NAME=${package_name}" \
-v "${repo_root}:/work:ro" \ -v "${repo_root}:/work:ro" \
-v "${repo_root}/packages/${repo_name}:/repo:ro" \ -v "${repo_root}/packages/${repo_name}:/repo:ro" \
"alpine:${alpine_version}" \ "${runtime_image}" \
sh -lc ' sh -lc '
set -e set -e
apk add --no-cache bash openrc >/dev/null
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/ cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
printf "%s\n" /repo >> /etc/apk/repositories printf "%s\n" /repo >> /etc/apk/repositories
apk update apk update
@@ -79,6 +79,15 @@ run_hook_docker() {
' '
} }
build_runtime_image() {
docker build \
--platform "${platform}" \
--build-arg "ALPINE_VERSION=${alpine_version}" \
-f "${repo_root}/scripts/apk/runtime-test.Dockerfile" \
-t "${runtime_image}" \
"${repo_root}"
}
validate_repo validate_repo
case "${runtime_mode}" in case "${runtime_mode}" in
@@ -99,6 +108,8 @@ esac
if [[ "${runtime_mode}" == "direct" ]]; then if [[ "${runtime_mode}" == "direct" ]]; then
prepare_direct_runtime prepare_direct_runtime
else
build_runtime_image
fi fi
while IFS= read -r package_dir; do while IFS= read -r package_dir; do
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
apk_test_install_run() {
local repo_root="$1"
local package_name="$2"
local package_version="$3"
local alpine_version="${ALPINE_VERSION:-3.24}"
local arch="${ALPINE_ARCH:-x86_64}"
local repository_url="${ALPINE_REPOSITORY_URL:-}"
local repository_key_url="${ALPINE_REPOSITORY_KEY_URL:-}"
local platform
local test_command
case "${arch}" in
x86_64) platform="${ALPINE_TEST_PLATFORM:-linux/amd64}" ;;
aarch64) platform="${ALPINE_TEST_PLATFORM:-linux/arm64}" ;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
return 2
;;
esac
if [[ -z "${repository_url}" && "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
if [[ -z "${repository_url}" && ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
printf 'run: ALPINE_PACKAGE=%s mise run apk:build\n' "${package_name}" >&2
return 1
fi
test_command="$(cat)"
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-e "PACKAGE_NAME=${package_name}" \
-e "PACKAGE_VERSION=${package_version}" \
-e "ALPINE_REPOSITORY_URL=${repository_url}" \
-e "ALPINE_REPOSITORY_KEY_URL=${repository_key_url}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc "${test_command}"
}