Add GHCR build/publish workflow

This commit is contained in:
2025-11-01 00:34:51 +01:00
parent 18352caabe
commit 2fba3236ad
+197
View File
@@ -0,0 +1,197 @@
name: Build & Publish Images
on:
push:
branches: [ main, dev ]
tags:
- '*'
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_BACKEND: papercrate-dms/papercrate-backend
IMAGE_FRONTEND: papercrate-dms/papercrate-frontend
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
component: [backend, frontend]
platform: [linux/amd64, linux/arm64]
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Set component metadata
run: |
if [ "${{ matrix.component }}" = "backend" ]; then
echo "COMPONENT_CONTEXT=./backend" >> "$GITHUB_ENV"
echo "COMPONENT_IMAGE=${{ env.IMAGE_BACKEND }}" >> "$GITHUB_ENV"
else
echo "COMPONENT_CONTEXT=./frontend" >> "$GITHUB_ENV"
echo "COMPONENT_IMAGE=${{ env.IMAGE_FRONTEND }}" >> "$GITHUB_ENV"
fi
echo "COMPONENT_NAME=${{ matrix.component }}" >> "$GITHUB_ENV"
- name: Compute tags
env:
GITHUB_SHA: ${{ github.sha }}
GITHUB_REF: ${{ github.ref }}
REGISTRY: ${{ env.REGISTRY }}
PLATFORM: ${{ matrix.platform }}
run: |
ARCH=${PLATFORM#*/}
TAGS=("${GITHUB_SHA::7}")
BRANCH=${GITHUB_REF##*/}
if [ "$BRANCH" = "dev" ]; then
TAGS+=("${GITHUB_SHA::7}-dev")
fi
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
TAGS+=("${GITHUB_REF#refs/tags/}")
fi
UNIQUE=()
for tag in "${TAGS[@]}"; do
[[ -z "$tag" ]] && continue
skip=false
for seen in "${UNIQUE[@]}"; do
if [ "$tag" = "$seen" ]; then
skip=true
break
fi
done
if [ "$skip" = false ]; then
UNIQUE+=("$tag")
fi
done
{
echo "BASE_TAGS<<EOF"
for tag in "${UNIQUE[@]}"; do
printf '%s\n' "$tag"
done
echo "EOF"
echo "IMAGE_TAGS<<EOF"
for tag in "${UNIQUE[@]}"; do
printf '%s\n' "$REGISTRY/$COMPONENT_IMAGE:${tag}-${ARCH}"
done
echo "EOF"
echo "ARCH=$ARCH"
} >> "$GITHUB_ENV"
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build & push ${{ env.COMPONENT_NAME }} (${{ matrix.platform }})
uses: docker/build-push-action@v5
with:
context: ${{ env.COMPONENT_CONTEXT }}
push: true
platforms: ${{ matrix.platform }}
tags: ${{ env.IMAGE_TAGS }}
manifest:
runs-on: ubuntu-latest
needs: build
strategy:
matrix:
component: [backend, frontend]
permissions:
contents: read
packages: write
env:
REGISTRY: ghcr.io
ARCHES: amd64 arm64
steps:
- name: Set component metadata
run: |
if [ "${{ matrix.component }}" = "backend" ]; then
echo "COMPONENT_IMAGE=${{ env.IMAGE_BACKEND }}" >> "$GITHUB_ENV"
else
echo "COMPONENT_IMAGE=${{ env.IMAGE_FRONTEND }}" >> "$GITHUB_ENV"
fi
echo "COMPONENT_NAME=${{ matrix.component }}" >> "$GITHUB_ENV"
- name: Compute base tags
env:
GITHUB_SHA: ${{ github.sha }}
GITHUB_REF: ${{ github.ref }}
run: |
TAGS=("${GITHUB_SHA::7}")
BRANCH=${GITHUB_REF##*/}
if [ "$BRANCH" = "dev" ]; then
TAGS+=("${GITHUB_SHA::7}-dev")
fi
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
TAGS+=("${GITHUB_REF#refs/tags/}")
fi
UNIQUE=()
for tag in "${TAGS[@]}"; do
[[ -z "$tag" ]] && continue
skip=false
for seen in "${UNIQUE[@]}"; do
if [ "$tag" = "$seen" ]; then
skip=true
break
fi
done
if [ "$skip" = false ]; then
UNIQUE+=("$tag")
fi
done
{
echo "BASE_TAGS<<EOF"
for tag in "${UNIQUE[@]}"; do
printf '%s\n' "$tag"
done
echo "EOF"
} >> "$GITHUB_ENV"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create manifests for ${{ env.COMPONENT_NAME }}
run: |
while IFS= read -r tag; do
[ -n "$tag" ] || continue
args=()
for arch in $ARCHES; do
args+=("$REGISTRY/$COMPONENT_IMAGE:${tag}-${arch}")
done
docker buildx imagetools create \
--tag "$REGISTRY/$COMPONENT_IMAGE:$tag" \
"${args[@]}"
done <<< "$BASE_TAGS"