amd64 nodes (radio-box) got 'no matching manifest for linux/amd64' on pull and had to build locally. Every image workflow now builds linux/amd64,linux/arm64. Release images treats an existing src- tag as present only if it carries both platforms, so the arm64-only src- tags pushed before this get rebuilt on the next v1 push. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
92 lines
3.5 KiB
YAML
92 lines
3.5 KiB
YAML
name: Release images
|
|
|
|
# Make sure every node image a release ref needs exists in the registry
|
|
# (node-26#19). A node on `v1` pulls <image>:src-<tree hash of that image's
|
|
# directory at v1>. The per-image build workflows only run when their own
|
|
# directory changes on main, and anything built before #19 has no src- tag at
|
|
# all, so a release tag can point at trees nobody ever built. This fills the
|
|
# gaps: for each image, if src-<tree> is already in the registry it does
|
|
# nothing; otherwise it builds and pushes it (registry cache keeps op25 off a
|
|
# full recompile when only its app code changed).
|
|
#
|
|
# Runs on every v* tag push, including a re-cut `v1`. Also runnable by hand
|
|
# (workflow_dispatch) on any ref — run it once on the ref `v1` points at
|
|
# before re-cutting `v1` onto a commit that contains #19, so nodes never see
|
|
# a moment where their pinned images don't exist yet.
|
|
#
|
|
# Pushes ONLY src- tags. :latest / :stable keep tracking main, as before.
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
push:
|
|
tags:
|
|
- "v*"
|
|
|
|
jobs:
|
|
ensure:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- name: edge-node
|
|
context: drb-edge-node
|
|
- name: icecast
|
|
context: icecast
|
|
- name: op25-client
|
|
context: op25-container
|
|
- name: secondary-sdr
|
|
context: secondary-sdr-container
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: docker/setup-qemu-action@v3
|
|
|
|
- uses: docker/setup-buildx-action@v3
|
|
with:
|
|
config-inline: |
|
|
[registry."git.vpn.cusano.net"]
|
|
http = false
|
|
insecure = false
|
|
|
|
- uses: docker/login-action@v3
|
|
with:
|
|
registry: git.vpn.cusano.net
|
|
username: ${{ gitea.actor }}
|
|
password: ${{ secrets.BUILD_TOKEN }}
|
|
|
|
- name: Resolve source tag
|
|
id: meta
|
|
run: |
|
|
REPO_NAME="$(echo ${GITHUB_REPOSITORY} | awk -F'/' '{print $2}')"
|
|
# Must match scripts/image-tags.sh and the build-*.yml workflows.
|
|
IMAGE="git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${REPO_NAME}/${{ matrix.name }}"
|
|
TAG="src-$(git rev-parse HEAD:${{ matrix.context }})"
|
|
echo "IMAGE=$IMAGE" >> $GITHUB_OUTPUT
|
|
echo "TAG=$TAG" >> $GITHUB_OUTPUT
|
|
# Present only counts if BOTH platforms are in it: src- tags pushed
|
|
# before node-26#28 are arm64-only, and an amd64 node can't pull them.
|
|
RAW="$(docker buildx imagetools inspect --raw "$IMAGE:$TAG" 2>/dev/null | tr -d ' \n' || true)"
|
|
if printf '%s' "$RAW" | grep -q '"architecture":"amd64"' \
|
|
&& printf '%s' "$RAW" | grep -q '"architecture":"arm64"'; then
|
|
echo "EXISTS=true" >> $GITHUB_OUTPUT
|
|
echo "$IMAGE:$TAG already published for amd64 + arm64 — nothing to do"
|
|
else
|
|
echo "EXISTS=false" >> $GITHUB_OUTPUT
|
|
echo "$IMAGE:$TAG missing or not multi-arch — building it"
|
|
fi
|
|
|
|
- if: steps.meta.outputs.EXISTS != 'true'
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
context: ./${{ matrix.context }}
|
|
file: ./${{ matrix.context }}/Dockerfile
|
|
# amd64 + arm64, same as the build-*.yml workflows (node-26#28).
|
|
platforms: linux/amd64,linux/arm64
|
|
push: true
|
|
tags: ${{ steps.meta.outputs.IMAGE }}:${{ steps.meta.outputs.TAG }}
|
|
cache-from: type=registry,ref=${{ steps.meta.outputs.IMAGE }}:buildcache
|