Files
200feet/scripts/build_and_push.sh

99 lines
3.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Build the static payload, cross-build the Docker image for linux/amd64
# (the typical Portainer host arch), push to the registry.
# Usage: scripts/build_and_push.sh [tag]
# Default tag = current date + short git sha (if git repo) else 'latest'.
#
# Env vars:
# PLATFORMS - default "linux/amd64". Set to "linux/amd64,linux/arm64" for
# multi-arch (registry must support OCI manifest lists; most do).
# PY - default ".venv/bin/python"
# SKIP_GEN - "1" to skip regeneration of analysis outputs.
set -euo pipefail
cd "$(dirname "$0")/.."
REGISTRY="registry.davidadams.rocks"
IMAGE="${REGISTRY}/200feet"
PLATFORMS="${PLATFORMS:-linux/amd64}"
PY="${PY:-.venv/bin/python}"
BUILDER_NAME="200feet-builder"
if [[ $# -ge 1 ]]; then
TAG="$1"
else
DATE_TAG="$(date +%Y%m%d-%H%M)"
if git rev-parse --short HEAD >/dev/null 2>&1; then
SHA="$(git rev-parse --short HEAD)"
TAG="${DATE_TAG}-${SHA}"
else
TAG="${DATE_TAG}"
fi
fi
if [[ "${SKIP_GEN:-0}" != "1" ]]; then
echo "==> Regenerating analysis"
"$PY" scripts/analyze.py
"$PY" scripts/compare_setbacks.py
"$PY" scripts/build_web.py
fi
# Ensure a buildx builder exists with multi-arch / QEMU support. Reuse any
# existing docker-container builder rather than always creating ours -- many
# M1 setups already have one (e.g. 'multiarch' under Colima).
PICKED_BUILDER=""
if docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then
PICKED_BUILDER="${BUILDER_NAME}"
else
# Try first existing docker-container builder, else create ours.
while IFS= read -r line; do
name=$(awk '{print $1}' <<<"$line" | sed 's/\*$//')
driver=$(awk '{print $2}' <<<"$line")
if [[ "$driver" == "docker-container" && -n "$name" && "$name" != "NAME/NODE" ]]; then
PICKED_BUILDER="$name"; break
fi
done < <(docker buildx ls 2>/dev/null | tail -n +2)
if [[ -z "${PICKED_BUILDER}" ]]; then
echo "==> Creating buildx builder '${BUILDER_NAME}'"
docker buildx create --name "${BUILDER_NAME}" --driver docker-container >/dev/null
docker buildx inspect "${BUILDER_NAME}" --bootstrap >/dev/null
PICKED_BUILDER="${BUILDER_NAME}"
fi
fi
docker buildx use "${PICKED_BUILDER}"
echo "==> Using buildx builder '${PICKED_BUILDER}'"
# Sanity-check the builder actually supports the requested platforms.
SUPPORTED=$(docker buildx inspect "${PICKED_BUILDER}" 2>/dev/null | awk -F: '/Platforms/ {print $2}' | tr -d ' ')
for plat in $(echo "${PLATFORMS}" | tr ',' ' '); do
if ! grep -q "${plat}" <<<"${SUPPORTED}"; then
echo "ERROR: builder '${PICKED_BUILDER}' does not support ${plat}." >&2
echo "Supported: ${SUPPORTED}" >&2
exit 1
fi
done
echo "==> Building & pushing ${IMAGE}:${TAG} for ${PLATFORMS}"
docker buildx build \
--builder "${PICKED_BUILDER}" \
--platform "${PLATFORMS}" \
--provenance=false \
--sbom=false \
--tag "${IMAGE}:${TAG}" \
--tag "${IMAGE}:latest" \
--push \
.
echo
echo "==> Verifying pushed manifest"
docker buildx imagetools inspect "${IMAGE}:latest"
echo
echo "Pushed:"
echo " ${IMAGE}:${TAG}"
echo " ${IMAGE}:latest"
echo "Platforms: ${PLATFORMS}"
echo
echo "In Portainer: Stacks -> 200feet -> Update -> 'Re-pull image and redeploy'."