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 run: | if command -v docker >/dev/null 2>&1; then echo "docker already available" docker version exit 0 fi apt-get update -qq && apt-get install -y -qq docker.io docker 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" \ .