name: CI on: pull_request: push: branches: - "**" tags-ignore: - "**" concurrency: group: ci-${{ github.repository }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} permissions: contents: read jobs: security: name: Run security workflow uses: ./.github/workflows/security.yml permissions: contents: read packages: read security-events: write tests: name: Run test workflow uses: ./.github/workflows/tests.yml lint: name: Run lint workflow uses: ./.github/workflows/lint.yml permissions: contents: read security-events: write version: name: Detect release version runs-on: ubuntu-latest needs: - security - tests - lint if: github.event_name == 'push' permissions: contents: read outputs: found: ${{ steps.semver.outputs.found }} version: ${{ steps.semver.outputs.version }} image: ${{ steps.image.outputs.name }} steps: - name: Checkout repository uses: actions/checkout@v7 with: fetch-depth: 0 - name: Detect semver tag on current commit id: semver run: | SEMVER_TAG="$(git tag --points-at "$GITHUB_SHA" | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1 || true)" if [ -n "$SEMVER_TAG" ]; then { echo "found=true" echo "raw_tag=$SEMVER_TAG" echo "version=${SEMVER_TAG#v}" } >> "$GITHUB_OUTPUT" else echo "found=false" >> "$GITHUB_OUTPUT" fi - name: Compute image name id: image run: echo "name=ghcr.io/$(echo "${GITHUB_REPOSITORY}" | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT" publish: name: Publish image (${{ matrix.arch }}) runs-on: ${{ matrix.runner }} needs: - version if: needs.version.outputs.found == 'true' permissions: contents: read packages: write strategy: matrix: include: - arch: amd64 runner: ubuntu-latest - arch: arm64 runner: ubuntu-24.04-arm steps: - name: Checkout repository uses: actions/checkout@v7 - name: Set up Docker Buildx uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 - name: Login to GHCR uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and publish image uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 with: context: . file: ./Dockerfile platforms: linux/${{ matrix.arch }} push: true tags: ${{ needs.version.outputs.image }}:${{ needs.version.outputs.version }}-${{ matrix.arch }} manifest: name: Join architectures runs-on: ubuntu-latest needs: - version - publish permissions: contents: read packages: write steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 - name: Login to GHCR uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Create the multi-arch manifest env: IMAGE: ${{ needs.version.outputs.image }} VERSION: ${{ needs.version.outputs.version }} run: | set -euo pipefail docker buildx imagetools create -t "${IMAGE}:${VERSION}" \ "${IMAGE}:${VERSION}-amd64" \ "${IMAGE}:${VERSION}-arm64" docker buildx imagetools inspect "${IMAGE}:${VERSION}"