#!/usr/bin/env bash set -euo pipefail # Multi-arch buildx helper for DEVOPS-CONTAINERS-44-001 # Requirements: docker CLI with buildx, optional syft (for SBOM) and cosign (for signing). usage() { echo "Usage: $0 [--platform linux/amd64,linux/arm64] [--push] [--sbom syft|none] [--sign ]" >&2 exit 64 } if [[ $# -lt 2 ]]; then usage fi IMAGE_TAG=$1; shift CONTEXT_DIR=$1; shift PLATFORMS="linux/amd64,linux/arm64" PUSH=false SBOM_TOOL="syft" COSIGN_KEY="" while [[ $# -gt 0 ]]; do case "$1" in --platform) PLATFORMS="$2"; shift 2;; --push) PUSH=true; shift;; --sbom) SBOM_TOOL="$2"; shift 2;; --sign) COSIGN_KEY="$2"; shift 2;; *) echo "Unknown option: $1" >&2; usage;; esac done if ! command -v docker >/dev/null 2>&1; then echo "[buildx] docker CLI not found" >&2 exit 69 fi OUT_ROOT="out/buildx/$(echo "$IMAGE_TAG" | tr '/:' '__')" mkdir -p "$OUT_ROOT" BUILDER_NAME="stellaops-multiarch" if ! docker buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then docker buildx create --name "$BUILDER_NAME" --driver docker-container --use >/dev/null else docker buildx use "$BUILDER_NAME" >/dev/null fi BUILD_OPTS=( --platform "$PLATFORMS" -t "$IMAGE_TAG" --provenance=false --sbom=false --output "type=oci,dest=${OUT_ROOT}/image.oci" ) if $PUSH; then BUILD_OPTS+=("--push") fi echo "[buildx] building $IMAGE_TAG for $PLATFORMS" docker buildx build "${BUILD_OPTS[@]}" "$CONTEXT_DIR" echo "[buildx] computing digest" IMAGE_DIGEST=$(sha256sum "${OUT_ROOT}/image.oci" | awk '{print $1}') echo "$IMAGE_DIGEST image.oci" > "${OUT_ROOT}/image.sha256" if [[ "$SBOM_TOOL" == "syft" ]] && command -v syft >/dev/null 2>&1; then echo "[buildx] generating SBOM via syft" syft "oci-archive:${OUT_ROOT}/image.oci" -o json > "${OUT_ROOT}/sbom.syft.json" else echo "[buildx] skipping SBOM (tool=$SBOM_TOOL, syft available? $(command -v syft >/dev/null && echo yes || echo no))" fi if [[ -n "$COSIGN_KEY" ]] && command -v cosign >/dev/null 2>&1; then echo "[buildx] signing digest with cosign key" COSIGN_EXPERIMENTAL=1 cosign sign-blob --key "$COSIGN_KEY" --output-signature "${OUT_ROOT}/image.sig" --output-certificate "${OUT_ROOT}/image.cert" "${OUT_ROOT}/image.oci" else echo "[buildx] signature skipped (no key provided or cosign missing)" fi cat > "${OUT_ROOT}/build-metadata.json" <