117 lines
4.2 KiB
Bash
117 lines
4.2 KiB
Bash
#!/usr/bin/env bash
|
|
# Manually build and push selected linux/amd64 OCI images from main.
|
|
set -euo pipefail
|
|
|
|
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
registry="${ZOT_REGISTRY:-registry.oeo.one}"
|
|
work="$root/.release/main-fastlane"
|
|
buildah_home="/home/justme/woodpecker/buildah-home/main-fastlane"
|
|
mkdir -p "$work" "$buildah_home"
|
|
export HOME="$buildah_home"
|
|
export BUILDAH_HOME="$buildah_home"
|
|
export REGISTRY_AUTH_FILE="$work/zot-auth.json"
|
|
|
|
[[ "${CI_PIPELINE_EVENT:-}" == manual && "${CI_COMMIT_BRANCH:-}" == main ]] || {
|
|
echo "fast-lane images can only be published by a manual run on main" >&2
|
|
exit 2
|
|
}
|
|
|
|
manual_targets=""
|
|
if [[ -n "${FASTLANE_COMPONENTS:-}" && -n "${FASTLANE_BASE_SHA:-}" ]]; then
|
|
echo "set only one of FASTLANE_COMPONENTS or FASTLANE_BASE_SHA" >&2
|
|
exit 2
|
|
elif [[ -n "${FASTLANE_COMPONENTS:-}" ]]; then
|
|
manual_targets="$(python3 -c '
|
|
import sys
|
|
allowed = {"backend", "agent", "probe"}
|
|
requested = {part.strip() for part in sys.argv[1].split(",") if part.strip()}
|
|
unknown = requested - allowed
|
|
if not requested or unknown:
|
|
raise SystemExit("invalid FASTLANE_COMPONENTS: " + ", ".join(sorted(unknown or {"empty list"})))
|
|
print("\n".join(name for name in ("backend", "agent", "probe") if name in requested))
|
|
' "$FASTLANE_COMPONENTS")"
|
|
elif [[ -n "${FASTLANE_BASE_SHA:-}" ]]; then
|
|
[[ "$FASTLANE_BASE_SHA" =~ ^[0-9a-fA-F]{7,40}$ ]] || {
|
|
echo "FASTLANE_BASE_SHA must be a commit SHA" >&2
|
|
exit 2
|
|
}
|
|
if ! git cat-file -e "${FASTLANE_BASE_SHA}^{commit}" 2>/dev/null; then
|
|
git fetch --no-tags origin "$FASTLANE_BASE_SHA"
|
|
fi
|
|
base_sha="$(git rev-parse "${FASTLANE_BASE_SHA}^{commit}")"
|
|
git merge-base --is-ancestor "$base_sha" "${CI_COMMIT_SHA:-HEAD}" || {
|
|
echo "FASTLANE_BASE_SHA must be an ancestor of the selected main commit" >&2
|
|
exit 2
|
|
}
|
|
export CI_PIPELINE_FILES="$(git diff --name-only "$base_sha" "${CI_COMMIT_SHA:-HEAD}" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read().splitlines()))')"
|
|
export FASTLANE_FILES_ARE_JSON=true
|
|
else
|
|
# A manual run may follow several pushes; rebuild all images unless the caller
|
|
# explicitly chooses components or supplies a base SHA for change detection.
|
|
manual_targets=$'backend\nagent\nprobe'
|
|
fi
|
|
|
|
[[ -n "${ZOT_USERNAME:-}" && -n "${ZOT_SECRET:-}" ]] || {
|
|
echo "Zot credentials are required" >&2
|
|
exit 2
|
|
}
|
|
|
|
if [[ -n "$manual_targets" ]]; then
|
|
targets="$manual_targets"
|
|
else
|
|
targets="$(python3 "$root/ci/main-fastlane.py")"
|
|
fi
|
|
if [[ -z "$targets" ]]; then
|
|
echo "no runtime image changes detected; skipping container builds"
|
|
exit 0
|
|
fi
|
|
echo "affected linux/amd64 images: ${targets//$'\n'/, }"
|
|
|
|
logged_in=false
|
|
for attempt in 1 2 3 4; do
|
|
if buildah login --tls-verify=true --username "$ZOT_USERNAME" --password-stdin "$registry" <<< "$ZOT_SECRET" >/dev/null; then
|
|
logged_in=true
|
|
break
|
|
fi
|
|
if [[ "$attempt" -lt 4 ]]; then
|
|
echo "Zot login attempt $attempt failed; retrying in 3 seconds" >&2
|
|
sleep 3
|
|
fi
|
|
done
|
|
[[ "$logged_in" == true ]] || { echo "could not authenticate to Zot after 4 attempts" >&2; exit 1; }
|
|
|
|
publish_node_image() {
|
|
local component="$1" context="$work/$1" image="$registry/monitor/monitor-$1"
|
|
local local_image="localhost/monitor-$component:main-amd64"
|
|
|
|
python3 "$root/ci/main-fastlane.py" --stage "$component" --destination "$context"
|
|
buildah bud --layers --network host --tls-verify=true --arch amd64 \
|
|
--build-arg APP_VERSION=main \
|
|
-f "$context/Containerfile" -t "$local_image" "$context"
|
|
|
|
for tag in main-amd64 main; do
|
|
local pushed=false
|
|
for attempt in 1 2 3; do
|
|
if buildah push --tls-verify=true "$local_image" "docker://$image:$tag"; then
|
|
pushed=true
|
|
break
|
|
fi
|
|
if [[ "$attempt" -lt 3 ]]; then
|
|
echo "Zot push for $component:$tag attempt $attempt failed; retrying in 5 seconds" >&2
|
|
sleep 5
|
|
fi
|
|
done
|
|
[[ "$pushed" == true ]] || { echo "could not push $component:$tag after 3 attempts" >&2; return 1; }
|
|
echo "pushed Zot image $image:$tag"
|
|
done
|
|
}
|
|
|
|
while IFS= read -r component; do
|
|
[[ -n "$component" ]] || continue
|
|
case "$component" in
|
|
backend) bash "$root/ci/release-linux.sh" amd64 backend ;;
|
|
agent|probe) publish_node_image "$component" ;;
|
|
*) echo "unknown affected image: $component" >&2; exit 2 ;;
|
|
esac
|
|
done <<< "$targets"
|