Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 65 additions & 19 deletions .github/workflows/publish-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,71 @@ permissions:
contents: read
packages: write

# Native multi-arch: each (image, arch) builds on a native runner (no QEMU),
# pushes by digest, then a merge job stitches the per-arch digests into one
# multi-arch manifest per image. amd64 on ubuntu-latest, arm64 on the native
# ubuntu-24.04-arm runner.
jobs:
publish:
runs-on: ubuntu-latest
build:
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- image: tidebase
dockerfile: apps/server/Dockerfile
- image: tidebase-mcp
dockerfile: apps/mcp/Dockerfile
- { image: tidebase, dockerfile: apps/server/Dockerfile, platform: linux/amd64, arch: amd64, runner: ubuntu-latest }
- { image: tidebase, dockerfile: apps/server/Dockerfile, platform: linux/arm64, arch: arm64, runner: ubuntu-24.04-arm }
- { image: tidebase-mcp, dockerfile: apps/mcp/Dockerfile, platform: linux/amd64, arch: amd64, runner: ubuntu-latest }
- { image: tidebase-mcp, dockerfile: apps/mcp/Dockerfile, platform: linux/arm64, arch: arm64, runner: ubuntu-24.04-arm }
steps:
- uses: actions/checkout@v4

- uses: docker/setup-buildx-action@v3

- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- id: build
uses: docker/build-push-action@v6
with:
context: .
file: ${{ matrix.dockerfile }}
platforms: ${{ matrix.platform }}
outputs: type=image,name=ghcr.io/blueprintlabio/${{ matrix.image }},push-by-digest=true,name-canonical=true,push=true
cache-from: type=gha,scope=${{ matrix.image }}-${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=${{ matrix.image }}-${{ matrix.arch }}

- name: Export digest
run: |
mkdir -p "${{ runner.temp }}/digests"
digest="${{ steps.build.outputs.digest }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"

- uses: actions/upload-artifact@v4
with:
# `--` delimiter so `tidebase` does not prefix-match `tidebase-mcp`.
name: digests-${{ matrix.image }}--${{ matrix.arch }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1

merge:
needs: build
runs-on: ubuntu-latest
strategy:
matrix:
image: [tidebase, tidebase-mcp]
steps:
- uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-${{ matrix.image }}--*
merge-multiple: true

- uses: docker/setup-buildx-action@v3

- uses: docker/login-action@v3
with:
registry: ghcr.io
Expand All @@ -37,19 +86,16 @@ jobs:
with:
images: ghcr.io/blueprintlabio/${{ matrix.image }}
tags: |
type=ref,event=tag
type=raw,value=latest,enable={{is_default_branch}}
type=sha
type=ref,event=tag

- uses: docker/build-push-action@v6
with:
context: .
file: ${{ matrix.dockerfile }}
# amd64 only: matches the deploy target (Coolify host) and builds
# natively on the GitHub runner. Native arm64 is added separately.
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=${{ matrix.image }}
cache-to: type=gha,mode=max,scope=${{ matrix.image }}
- name: Create multi-arch manifest
working-directory: ${{ runner.temp }}/digests
run: |
docker buildx imagetools create \
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf 'ghcr.io/blueprintlabio/${{ matrix.image }}@sha256:%s ' *)

- name: Inspect
run: docker buildx imagetools inspect ghcr.io/blueprintlabio/${{ matrix.image }}:${{ steps.meta.outputs.version }}
Loading