name: Release Image # Primary release pipeline — pushes to registry.ginnoir.com (prod pulls this). # GitHub Actions .github/workflows/release.yml mirrors to GHCR as backup only. on: push: tags: - "v*" workflow_dispatch: concurrency: group: release-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: false jobs: build-and-push: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Derive image tags id: meta shell: bash run: | VERSION="${GITHUB_REF_NAME#v}" MAJOR_MINOR="$(printf '%s' "$VERSION" | awk -F. '{print $1"."$2}')" { echo "version=$VERSION" echo "major_minor=$MAJOR_MINOR" echo "image=registry.ginnoir.com/ginnoir/famapp" } >> "$GITHUB_OUTPUT" - name: Ensure docker CLI + buildx run: | # Debian's docker.io package ships no buildx plugin, which the # registry-cache build below requires. Install Docker's official # CLI + buildx plugin so the build works regardless of what the # runner image happens to provide. if docker buildx version >/dev/null 2>&1; then echo "docker + buildx already available" docker version docker buildx version exit 0 fi export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq ca-certificates curl gnupg install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc chmod a+r /etc/apt/keyrings/docker.asc echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \ > /etc/apt/sources.list.d/docker.list apt-get update -qq apt-get install -y -qq docker-ce-cli docker-buildx-plugin docker version docker buildx version - name: Login to registry run: | echo "${{ secrets.REGISTRY_PUSH_PASSWORD }}" | docker login registry.ginnoir.com \ --username "${{ secrets.REGISTRY_PUSH_USERNAME }}" \ --password-stdin - name: Set up buildx run: | docker buildx create --name famapp-builder --use 2>/dev/null || docker buildx use famapp-builder docker buildx inspect --bootstrap - name: Build and push image env: IMAGE: ${{ steps.meta.outputs.image }} VERSION: ${{ steps.meta.outputs.version }} MAJOR_MINOR: ${{ steps.meta.outputs.major_minor }} CACHE: registry.ginnoir.com/ginnoir/famapp:buildcache run: | docker buildx build \ --push \ --tag "${IMAGE}:${VERSION}" \ --tag "${IMAGE}:${MAJOR_MINOR}" \ --tag "${IMAGE}:latest" \ --cache-from "type=registry,ref=${CACHE}" \ --cache-to "type=registry,ref=${CACHE},mode=max" \ .