Skip to content
117 changes: 97 additions & 20 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,11 @@ env:
REGISTRY: ghcr.io

jobs:
build-and-push:
prepare-tags-and-names:
runs-on: ubuntu-latest
strategy:
matrix:
service:
- name: frontend
image: librislog
dockerfile: ./frontend/Dockerfile
context: ./frontend
- name: backend
image: librislog-api
dockerfile: ./backend/Dockerfile
context: ./backend

permissions:
contents: read
packages: write

steps:
- name: Checkout repository
Expand Down Expand Up @@ -59,6 +48,54 @@ jobs:
SANITIZED="$(echo "$SANITIZED" | sed 's/^[^a-zA-Z0-9_]\+//')"
echo "sanitized_tag=${SANITIZED:0:128}" >> "$GITHUB_OUTPUT"

- name: Normalize repository name
id: repo
uses: actions/github-script@v7
with:
result-encoding: string
script: return `${context.repo.owner}/${context.repo.repo}`.toLowerCase()

outputs:
version: ${{ steps.version.outputs.version }}
sha_short: ${{ steps.version.outputs.sha_short }}
sanitized_tag: ${{ steps.sanitize.outputs.sanitized_tag }}
repository: ${{ steps.repo.outputs.result }}

build-and-push:
runs-on: ${{ matrix.runner }}
needs: prepare-tags-and-names
strategy:
fail-fast: false
matrix:
service:
- name: frontend
image: librislog
dockerfile: ./frontend/Dockerfile
context: ./frontend
- name: backend
image: librislog-api
dockerfile: ./backend/Dockerfile
context: ./backend

arch: [amd64, arm64]

include:
- arch: amd64
runner: ubuntu-latest
- arch: arm64
runner: ubuntu-24.04-arm

permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.event.inputs.branch || github.ref }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

Expand All @@ -72,14 +109,14 @@ jobs:
- name: Generate image tags
id: tags
run: |
IMAGE="${{ env.REGISTRY }}/${{ github.repository }}/${{ matrix.service.image }}"
SHA_SHORT="${{ steps.version.outputs.sha_short }}"
IMAGE="${{ env.REGISTRY }}/${{ needs.prepare-tags-and-names.outputs.repository }}/${{ matrix.service.image }}"
SHA_SHORT="${{ needs.prepare-tags-and-names.outputs.sha_short }}"

if [ "${{ github.event_name }}" = "release" ]; then
SANITIZED="${{ steps.sanitize.outputs.sanitized_tag }}"
TAGS="${IMAGE}:${SANITIZED},${IMAGE}:latest"
SANITIZED="${{ needs.prepare-tags-and-names.outputs.sanitized_tag }}"
TAGS="${IMAGE}:${SANITIZED}-${{ matrix.arch }},${IMAGE}:latest-${{ matrix.arch }}"
else
TAGS="${IMAGE}:develop,${IMAGE}:${SHA_SHORT}"
TAGS="${IMAGE}:develop-${{ matrix.arch }},${IMAGE}:${SHA_SHORT}-${{ matrix.arch }}"
fi

echo "tags=${TAGS}" >> "$GITHUB_OUTPUT"
Expand All @@ -90,11 +127,51 @@ jobs:
context: ${{ matrix.service.context }}
file: ${{ matrix.service.dockerfile }}
push: true
platforms: linux/amd64
platforms: linux/${{ matrix.arch }}
tags: ${{ steps.tags.outputs.tags }}
build-args: |
APP_VERSION=${{ steps.version.outputs.version }}
APP_VERSION=${{ needs.prepare-tags-and-names.outputs.version }}
GIT_SHA=${{ github.sha }}
${{ matrix.service.name == 'frontend' && 'PUBLIC_DEFAULT_LOCALE=en' || '' }}
cache-from: type=gha
cache-to: type=gha,mode=max

create-manifest:
needs: [prepare-tags-and-names, build-and-push]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
service:
- name: frontend
image: librislog
- name: backend
image: librislog-api

permissions:
packages: write

steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Log in to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Create multi-arch manifest
run: |
IMAGE="${{ env.REGISTRY }}/${{ needs.prepare-tags-and-names.outputs.repository }}/${{ matrix.service.image }}"
SHA_SHORT="${{ needs.prepare-tags-and-names.outputs.sha_short }}"

if [ "${{ github.event_name }}" = "release" ]; then
SANITIZED="${{ needs.prepare-tags-and-names.outputs.sanitized_tag }}"
docker buildx imagetools create -t "${IMAGE}:${SANITIZED}" "${IMAGE}:${SANITIZED}-amd64" "${IMAGE}:${SANITIZED}-arm64"
docker buildx imagetools create -t "${IMAGE}:latest" "${IMAGE}:latest-amd64" "${IMAGE}:latest-arm64"
else
docker buildx imagetools create -t "${IMAGE}:develop" "${IMAGE}:develop-amd64" "${IMAGE}:develop-arm64"
docker buildx imagetools create -t "${IMAGE}:${SHA_SHORT}" "${IMAGE}:${SHA_SHORT}-amd64" "${IMAGE}:${SHA_SHORT}-arm64"
fi