name: Build and Push Docker Image to GHCR env: OCI_TOKEN: ${{ secrets.OCI_TOKEN || secrets.GITHUB_TOKEN }} on: push: branches: ["main"] tags: ["v*.*.*"] jobs: build-and-push: strategy: matrix: include: - arch: amd64 docker-platform: linux/amd64 tag-suffix: "" - arch: arm64 docker-platform: linux/arm64 tag-suffix: "-arm64" runs-on: ubuntu-latest architecture: ${{ matrix.arch }} permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v4 - name: Log in to GHCR uses: docker/login-action@v3 with: registry: ${{ vars.OCI_REGISTRY || 'ghcr.io' }} username: ${{ github.actor }} password: ${{ env.OCI_TOKEN }} - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@v3 - name: Extract Docker metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ vars.OCI_REGISTRY || 'ghcr.io' }}/${{ github.repository }} tags: | type=schedule type=ref,event=branch type=semver,pattern={{version}}${{ matrix.tag_suffix }} type=semver,pattern={{major}}.{{minor}}${{ matrix.tag_suffix }} type=semver,pattern={{major}}${{ matrix.tag_suffix }} type=raw,value=latest${{ matrix.tag_suffix }},enable={{is_default_branch}} - name: Build and push Docker image uses: docker/build-push-action@v6 with: context: . push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} platforms: ${{ matrix.docker_platform }} build-args: TARGETARCH=${{ matrix.arch }} combine-manifests: needs: build-and-push runs-on: ubuntu-latest steps: - name: Log in to GHCR uses: docker/login-action@v3 with: registry: ${{ vars.OCI_REGISTRY || 'ghcr.io' }} username: ${{ github.actor }} password: ${{ env.OCI_TOKEN }} - name: Create combined manifest run: | # Get the base image name IMAGE_NAME=${{ vars.OCI_REGISTRY || 'ghcr.io' }}/${{ github.repository }} # Determine tags based on ref_type (branch/tag) if [[ "${{ github.ref_type }}" == "tag" ]]; then TAG_VERSION="${{ github.ref_name }}" # e.g., v1.0.0 TAG_LATEST="latest" elif [[ "${{ github.ref_name }}" == "refs/heads/main" ]]; then TAG_VERSION="" # No version tag for main head TAG_LATEST="latest" else echo "Skipping manifest for non-tag/non-main branch" exit 0 fi if [ -n "$TAG_LATEST" ]; then docker buildx imagetools create -t ${IMAGE_NAME}:${TAG_LATEST} \ ${IMAGE_NAME}:${TAG_LATEST}-amd64 \ ${IMAGE_NAME}:${TAG_LATEST}-arm64 echo "Created multi-arch manifest for ${IMAGE_NAME}:${TAG_LATEST}" fi if [ -n "$TAG_VERSION" ]; then docker buildx imagetools create -t ${IMAGE_NAME}:${TAG_VERSION} \ ${IMAGE_NAME}:${TAG_VERSION}-amd64 \ ${IMAGE_NAME}:${TAG_VERSION}-arm64 echo "Created multi-arch manifest for ${IMAGE_NAME}:${TAG_VERSION}" fi