Skip to content

docker-compose-ci

docker-compose-ci #16

name: docker-compose-ci
on:
workflow_dispatch:
push:
branches: ["**"]
tags: ["v*.*.*"]
pull_request:
branches: ["**"]
permissions:
contents: read
packages: write
id-token: write
concurrency:
group: docker-compose-ci-${{ github.ref }}
cancel-in-progress: true
env:
REPO_SLUG: centralized-logging
DOCKERHUB_NAMESPACE: "" # set to mirror to Docker Hub or leave empty
PLATFORMS: linux/amd64,linux/arm64
jobs:
tests:
name: Build and Test (.NET)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
9.0.x
8.0.x
- name: Restore
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Test
run: dotnet test --configuration Release --no-build --collect:"XPlat Code Coverage"
env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
images:
name: Build and Push Images (GHCR)
runs-on: ubuntu-latest
needs: tests
if: >
github.event_name != 'pull_request' &&
(startsWith(github.ref, 'refs/heads/master') || startsWith(github.ref, 'refs/tags/v'))
env:
# Make secrets available as env so we can safely reference env.* in `if:`
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Meta (userapi)
id: meta_user
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/${{ env.REPO_SLUG }}/userapi
tags: |
type=raw,value=edge,enable=${{ startsWith(github.ref,'refs/heads/master') || startsWith(github.ref,'refs/tags/v') }}
type=raw,value=latest,enable=${{ startsWith(github.ref,'refs/heads/master') }}
type=semver,pattern={{version}},enable=${{ startsWith(github.ref,'refs/tags/v') }}
type=semver,pattern={{major}}.{{minor}},enable=${{ startsWith(github.ref,'refs/tags/v') }}
- name: Meta (api)
id: meta_api
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/${{ env.REPO_SLUG }}/api
tags: |
type=raw,value=edge,enable=${{ startsWith(github.ref,'refs/heads/master') || startsWith(github.ref,'refs/tags/v') }}
type=raw,value=latest,enable=${{ startsWith(github.ref,'refs/heads/master') }}
type=semver,pattern={{version}},enable=${{ startsWith(github.ref,'refs/tags/v') }}
type=semver,pattern={{major}}.{{minor}},enable=${{ startsWith(github.ref,'refs/tags/v') }}
- name: Meta (web)
id: meta_web
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/${{ env.REPO_SLUG }}/web
tags: |
type=raw,value=edge,enable=${{ startsWith(github.ref,'refs/heads/master') || startsWith(github.ref,'refs/tags/v') }}
type=raw,value=latest,enable=${{ startsWith(github.ref,'refs/heads/master') }}
type=semver,pattern={{version}},enable=${{ startsWith(github.ref,'refs/tags/v') }}
type=semver,pattern={{major}}.{{minor}},enable=${{ startsWith(github.ref,'refs/tags/v') }}
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: (Optional) Login to Docker Hub
if: ${{ env.DOCKERHUB_NAMESPACE != '' && env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' }}
uses: docker/login-action@v3
with:
username: ${{ env.DOCKERHUB_USERNAME }}
password: ${{ env.DOCKERHUB_TOKEN }}
- name: Restore build cache
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Bake and Push (multi-arch)
uses: docker/bake-action@v5
with:
files: ./docker-bake.hcl
push: true
set: |
*.platform=${{ env.PLATFORMS }}
*.cache-from=type=local,src=/tmp/.buildx-cache
*.cache-to=type=local,dest=/tmp/.buildx-cache-new,mode=max
*.labels.org.opencontainers.image.revision=${{ github.sha }}
OWNER=${{ github.repository_owner }}
REPO_SLUG=${{ env.REPO_SLUG }}
userapi.tags=${{ steps.meta_user.outputs.tags }}
api.tags=${{ steps.meta_api.outputs.tags }}
web.tags=${{ steps.meta_web.outputs.tags }}
- name: Save build cache
if: always()
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
- name: Mirror to Docker Hub (optional)
if: ${{ env.DOCKERHUB_NAMESPACE != '' && env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' }}
run: |
set -euo pipefail
mirror() { local svc="$1"; shift; for t in "$@"; do tg="$(basename "$t")"; \
ghcr="ghcr.io/${{ github.repository_owner }}/${{ env.REPO_SLUG }}/${svc}:${tg}"; \
hub="${{ env.DOCKERHUB_NAMESPACE }}/${{ env.REPO_SLUG }}-${svc}:${tg}"; \
echo "Mirroring $ghcr -> $hub"; docker pull "$ghcr"; docker tag "$ghcr" "$hub"; docker push "$hub"; done; }
mapfile -t USER_TAGS <<< "${{ steps.meta_user.outputs.tags }}"
mapfile -t API_TAGS <<< "${{ steps.meta_api.outputs.tags }}"
mapfile -t WEB_TAGS <<< "${{ steps.meta_web.outputs.tags }}"
mirror userapi "${USER_TAGS[@]}"; mirror api "${API_TAGS[@]}"; mirror web "${WEB_TAGS[@]}"