name: Docker # This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. on: schedule: - cron: "25 0 * * *" push: branches: ["main"] # Publish semver tags as releases. tags: ["v*.*.*"] pull_request: branches: ["main"] workflow_dispatch: env: # Use docker.io for Docker Hub if empty REGISTRY: ghcr.io # github.repository as / IMAGE_NAME: ${{ github.repository }} jobs: test: runs-on: ubuntu-latest permissions: contents: read packages: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Test id: test uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64 cache-from: type=gha,scope=x64 pull: true cache-to: type=gha,mode=max,scope=x64 target: test build: needs: test runs-on: ubuntu-latest permissions: contents: read packages: write id-token: write strategy: matrix: platform: [linux/amd64, linux/arm64] steps: - name: Checkout repository uses: actions/checkout@v4 - name: Prepare variables id: vars run: | SURFIX=$(echo ${{ matrix.platform }} | cut -d'/' -f2) echo "SURFIX=$SURFIX" >> $GITHUB_OUTPUT # Generate a unique local tag for the image echo "LOCAL_TAG=local-${{ github.sha }}-$SURFIX" >> $GITHUB_OUTPUT # Set up BuildKit Docker container builder - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 # Extract metadata (tags, labels) for Docker - name: Extract Docker metadata id: meta uses: docker/metadata-action@v5 with: tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=raw,enable=${{ github.ref_type == 'tag' }}, value=latest images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} # Build and export Docker image for each platform (without pushing) - name: Build Docker image id: build uses: docker/build-push-action@v6 with: context: . pull: true push: false load: true # Export to local Docker instead of pushing tags: ${{ steps.vars.outputs.LOCAL_TAG }} labels: ${{ steps.meta.outputs.labels }} platforms: ${{ matrix.platform }} cache-from: type=gha,scope=${{ matrix.platform }} cache-to: type=gha,mode=max,scope=${{ matrix.platform }} build-args: GITHUB_BUILD=true,VERSION=${{ github.ref_type == 'tag' && github.ref_name || github.sha }} outputs: type=docker,dest=/tmp/image-${{ steps.vars.outputs.SURFIX }}.tar # Upload the tarball as an artifact - name: Upload image artifact uses: actions/upload-artifact@v4 with: name: docker-image-${{ steps.vars.outputs.SURFIX }} path: /tmp/image-${{ steps.vars.outputs.SURFIX }}.tar retention-days: 1 merge-and-push: needs: build runs-on: ubuntu-latest if: github.event_name != 'pull_request' permissions: contents: read packages: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v4 # Install the cosign tool - name: Install cosign uses: sigstore/cosign-installer@v3 # Set up Docker Buildx - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 # Log into registry - name: Log into registry ${{ env.REGISTRY }} uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} # Extract Docker metadata for tagging - name: Extract Docker metadata id: meta uses: docker/metadata-action@v5 with: tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=raw,enable=${{ github.ref_type == 'tag' }}, value=latest images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} # Download all image artifacts - name: Download AMD64 image uses: actions/download-artifact@v4 with: name: docker-image-amd64 path: /tmp - name: Download ARM64 image uses: actions/download-artifact@v4 with: name: docker-image-arm64 path: /tmp # Load images into Docker - name: Load images run: | docker load --input /tmp/image-amd64.tar docker load --input /tmp/image-arm64.tar # Create manifest lists and push - name: Create and push manifest lists run: | TAGS="${{ steps.meta.outputs.tags }}" for TAG in $TAGS; do # Tag the local images with their registry counterparts docker tag local-${{ github.sha }}-amd64 $TAG-amd64 docker tag local-${{ github.sha }}-arm64 $TAG-arm64 # Push individual platform images # docker push $TAG-amd64 # docker push $TAG-arm64 # Create manifest list and push it docker buildx imagetools create -t $TAG \ $TAG-amd64 \ $TAG-arm64 done # Sign the manifest - name: Sign the manifests env: TAGS: ${{ steps.meta.outputs.tags }} run: | for TAG in $TAGS; do cosign sign --yes $TAG done