161 lines
5.9 KiB
Bash
Executable File
161 lines
5.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
# shellcheck source=scripts/apk/package-lib.sh
|
|
. "${repo_root}/scripts/apk/package-lib.sh"
|
|
|
|
arches="${ALPINE_ARCHES:-x86_64 aarch64}"
|
|
branch="${ALPINE_REGISTRY_BRANCH:-v${ALPINE_VERSION:-3.24}}"
|
|
repository="${ALPINE_REGISTRY_REPOSITORY:-${PACKAGE_NAME:-main}}"
|
|
instance_url="${INSTANCE_URL:-}"
|
|
owner="${PACKAGE_OWNER:-}"
|
|
command_name="${1:-prepare}"
|
|
registry_cache="${CI_REGISTRY_CACHE_DIR:-${repo_root}/.cache/ci-registry}"
|
|
|
|
require_registry_config() {
|
|
local name="$1" value="$2"
|
|
[[ -n "${value}" ]] && return
|
|
printf 'missing required CI registry setting: %s\n' "${name}" >&2
|
|
exit 2
|
|
}
|
|
|
|
registry_url() {
|
|
printf '%s/api/packages/%s/alpine/%s/%s\n' \
|
|
"${instance_url%/}" "${owner}" "${branch}" "${repository}"
|
|
}
|
|
|
|
registry_key_url() {
|
|
printf '%s/api/packages/%s/alpine/key\n' "${instance_url%/}" "${owner}"
|
|
}
|
|
|
|
download_registry_metadata() {
|
|
local arch url key_dir
|
|
|
|
require_registry_config INSTANCE_URL "${instance_url}"
|
|
require_registry_config PACKAGE_OWNER "${owner}"
|
|
mkdir -p "${registry_cache}"
|
|
url="$(registry_url)"
|
|
for arch in ${arches}; do
|
|
curl --fail --silent --show-error --location \
|
|
--output "${registry_cache}/${arch}.APKINDEX.tar.gz" \
|
|
"${url}/${arch}/APKINDEX.tar.gz"
|
|
done
|
|
key_dir="${registry_cache}/keys"
|
|
mkdir -p "${key_dir}"
|
|
find "${key_dir}" -maxdepth 1 -type f -name '*.rsa.pub' -delete
|
|
curl --fail --silent --show-error --location \
|
|
--remote-name --remote-header-name --output-dir "${key_dir}" \
|
|
"$(registry_key_url)"
|
|
registry_key_path="$(find "${key_dir}" -maxdepth 1 -type f -name '*.rsa.pub' -print -quit)"
|
|
if [[ -z "${registry_key_path}" ]]; then
|
|
printf 'registry signing key was not downloaded: %s\n' "$(registry_key_url)" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
load_registry_index() {
|
|
local arch package_name package_version registry_key comparison
|
|
declare -gA registry_latest_versions=()
|
|
|
|
for arch in ${arches}; do
|
|
while IFS=$'\t' read -r package_name package_version; do
|
|
[[ -n "${package_name}" && -n "${package_version}" ]] || continue
|
|
registry_key="${arch}|${package_name}"
|
|
if [[ -z "${registry_latest_versions[${registry_key}]:-}" ]]; then
|
|
registry_latest_versions["${registry_key}"]="${package_version}"
|
|
continue
|
|
fi
|
|
comparison="$(apk version -t "${package_version}" "${registry_latest_versions[${registry_key}]}")"
|
|
if [[ "${comparison}" == ">" ]]; then
|
|
registry_latest_versions["${registry_key}"]="${package_version}"
|
|
fi
|
|
done < <(
|
|
tar -xOzf "${registry_cache}/${arch}.APKINDEX.tar.gz" APKINDEX | awk '
|
|
/^P:/ { package = substr($0, 3); next }
|
|
/^V:/ { if (package != "") print package "\t" substr($0, 3); package = "" }
|
|
'
|
|
)
|
|
done
|
|
}
|
|
|
|
registry_upgrade_packages() {
|
|
local package_dir package_name arch candidate_spec candidate_version published_version comparison selected
|
|
|
|
while IFS= read -r package_dir; do
|
|
apk_validate_package_dir "${package_dir}"
|
|
package_name="$(apk_package_name "${package_dir}")"
|
|
selected=0
|
|
for arch in ${arches}; do
|
|
apk_package_supports_arch "${package_dir}" "${arch}" || continue
|
|
IFS= read -r candidate_spec < <(apk_package_versioned_names "${package_dir}" "${arch}")
|
|
candidate_version="${candidate_spec#*=}"
|
|
published_version="${registry_latest_versions[${arch}|${package_name}]:-}"
|
|
if [[ -z "${published_version}" ]]; then
|
|
selected=1
|
|
printf 'Registry miss: %s (%s, %s)\n' "${package_name}" "${arch}" "${candidate_spec}" >&2
|
|
continue
|
|
fi
|
|
comparison="$(apk version -t "${candidate_version}" "${published_version}")"
|
|
if [[ "${comparison}" == ">" ]]; then
|
|
selected=1
|
|
printf 'Registry upgrade: %s (%s, %s -> %s)\n' \
|
|
"${package_name}" "${arch}" "${published_version}" "${candidate_version}" >&2
|
|
else
|
|
printf 'Registry current: %s (%s, source %s; published %s)\n' \
|
|
"${package_name}" "${arch}" "${candidate_version}" "${published_version}" >&2
|
|
fi
|
|
done
|
|
[[ "${selected}" == 1 ]] && printf '%s\n' "${package_name}"
|
|
done < <(apk_all_package_dirs "${repo_root}")
|
|
}
|
|
|
|
prepare() {
|
|
local build_matrix selected
|
|
declare -A selected_map=()
|
|
|
|
download_registry_metadata
|
|
load_registry_index
|
|
while IFS= read -r selected; do
|
|
[[ -n "${selected}" ]] && selected_map["${selected}"]=1
|
|
done < <(registry_upgrade_packages)
|
|
|
|
ALPINE_PACKAGES="$(for selected in "${!selected_map[@]}"; do printf '%s\n' "${selected}"; done | sort | xargs)"
|
|
if [[ -n "${ALPINE_PACKAGES}" ]]; then
|
|
ALPINE_SKIP_BUILD=0
|
|
printf 'Selected packages for rebuild: %s\n' "${ALPINE_PACKAGES}"
|
|
else
|
|
ALPINE_SKIP_BUILD=1
|
|
printf 'No packages selected for rebuild: registry has equal or newer package versions\n'
|
|
fi
|
|
|
|
if [[ -n "${GITHUB_ENV:-}" ]]; then
|
|
{
|
|
printf 'ALPINE_PACKAGES=%s\n' "${ALPINE_PACKAGES}"
|
|
printf 'ALPINE_SKIP_BUILD=%s\n' "${ALPINE_SKIP_BUILD}"
|
|
printf 'ALPINE_REGISTRY_URL=%s\n' "$(registry_url)"
|
|
printf 'ALPINE_REGISTRY_KEY=%s\n' "${registry_key_path}"
|
|
} >> "${GITHUB_ENV}"
|
|
fi
|
|
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
|
|
build_matrix="$({ printf '%s\n' "${ALPINE_PACKAGES}" | tr ' ' '\n' | jq -Rsc 'split("\n") | map(select(length > 0)) | {package: .}'; })"
|
|
printf 'selected_packages=%s\n' "${ALPINE_PACKAGES}" >> "${GITHUB_OUTPUT}"
|
|
printf 'build_matrix=%s\n' "${build_matrix}" >> "${GITHUB_OUTPUT}"
|
|
if [[ -n "${ALPINE_PACKAGES}" ]]; then
|
|
printf 'packages_selected=true\n' >> "${GITHUB_OUTPUT}"
|
|
else
|
|
printf 'packages_selected=false\n' >> "${GITHUB_OUTPUT}"
|
|
fi
|
|
if [[ " ${ALPINE_PACKAGES} " == *" greptimedb "* ]]; then
|
|
printf 'greptimedb_selected=true\n' >> "${GITHUB_OUTPUT}"
|
|
else
|
|
printf 'greptimedb_selected=false\n' >> "${GITHUB_OUTPUT}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
case "${command_name}" in
|
|
prepare) prepare ;;
|
|
*) printf 'usage: %s prepare\n' "$0" >&2; exit 2 ;;
|
|
esac
|