`! docker buildx inspect | grep -q linux/arm64` under `set -o pipefail` fails when grep exits on its first match before buildx has finished writing: buildx dies of SIGPIPE, the pipeline reports 141, and the script tells the operator to register emulation that is already registered. It refused to publish twice in a row that way, with arm64 present each time — and the same race is why it ever worked. Matching against the captured output has no pipe to break. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
55 lines
2.3 KiB
Bash
Executable File
55 lines
2.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Builds the server image for the Pi (arm64) and x86 hosts (amd64) and pushes it
|
|
# to the registry, tagged `latest` and with the commit it was built from.
|
|
#
|
|
# The Pi never builds: deploy/docker-compose.pi.yml pulls what this pushes.
|
|
# Only a clean working tree is built, so a commit tag names exactly the code in
|
|
# that commit — a tag built from uncommitted edits would name nothing.
|
|
#
|
|
# npm run publish-image # registry.mc02.dev/schulcloud-mcp
|
|
# IMAGE=registry.example/other npm run publish-image
|
|
set -euo pipefail
|
|
|
|
IMAGE=${IMAGE:-registry.mc02.dev/schulcloud-mcp}
|
|
PLATFORMS=${PLATFORMS:-linux/amd64,linux/arm64}
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
if [ -n "$(git status --porcelain)" ]; then
|
|
echo "The working tree has uncommitted changes. Commit them first: the image's tag must name exactly one commit." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# An x86 machine builds arm64 under QEMU emulation, which has to be registered
|
|
# once per boot. Registering needs a privileged container, so say how rather
|
|
# than doing it unasked.
|
|
#
|
|
# The platform list is captured, not piped into grep: `grep -q` exits on the
|
|
# first match, buildx then dies of SIGPIPE, and under `pipefail` that reads as
|
|
# "no arm64" — which had this script refuse to publish while arm64 was
|
|
# available the whole time.
|
|
platforms=$(docker buildx inspect)
|
|
if [[ "$PLATFORMS" == *linux/arm64* ]] && [[ "$platforms" != *linux/arm64* ]]; then
|
|
echo "This builder cannot build linux/arm64. Register emulation (lasts until the next reboot) with:" >&2
|
|
echo " docker run --privileged --rm tonistiigi/binfmt --install arm64" >&2
|
|
exit 1
|
|
fi
|
|
|
|
revision=$(git rev-parse HEAD)
|
|
tag=$(git rev-parse --short HEAD)
|
|
|
|
# One multi-platform push needs either Docker's containerd image store or a
|
|
# docker-container builder (`docker buildx create --use`); buildx says which
|
|
# is missing if neither is there.
|
|
docker buildx build \
|
|
--platform "$PLATFORMS" \
|
|
--tag "$IMAGE:latest" \
|
|
--tag "$IMAGE:$tag" \
|
|
--label org.opencontainers.image.title=schulcloud-mcp \
|
|
--label org.opencontainers.image.source=https://git.mc02.dev/fabi/Schulcloud-MCP \
|
|
--label "org.opencontainers.image.revision=$revision" \
|
|
--label "org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
--push .
|
|
|
|
echo "Pushed $IMAGE:$tag and $IMAGE:latest for $PLATFORMS."
|