Docker #3388
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Docker | |
| on: | |
| workflow_dispatch: | |
| schedule: | |
| - cron: "39 12 * * *" | |
| push: | |
| branches: ["main"] | |
| tags: ["v*.*.*"] | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| permissions: | |
| contents: read | |
| jobs: | |
| build: | |
| permissions: | |
| contents: read | |
| packages: write | |
| attestations: write | |
| id-token: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| platform: | |
| - linux/amd64 | |
| - linux/arm64 | |
| include: | |
| - platform: linux/amd64 | |
| os: ubuntu-latest | |
| - platform: linux/arm64 | |
| os: ubuntu-24.04-arm | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Prepare | |
| run: | | |
| platform=${{ matrix.platform }} | |
| echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV | |
| - name: Checkout repository | |
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 | |
| with: | |
| persist-credentials: false | |
| - name: Log into registry ${{ env.REGISTRY }} | |
| uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 | |
| - name: Extract Docker metadata | |
| id: meta | |
| uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| - name: Build and push by digest | |
| id: build | |
| uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 | |
| with: | |
| platforms: ${{ matrix.platform }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| provenance: false | |
| sbom: false | |
| - name: Generate Artifact Attestation | |
| uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a | |
| with: | |
| subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| subject-digest: ${{ steps.build.outputs.digest }} | |
| - name: Export digest | |
| run: | | |
| mkdir -p ${{ runner.temp }}/digests | |
| digest="${STEPS_BUILD_OUTPUTS_DIGEST}" | |
| touch "${{ runner.temp }}/digests/${digest#sha256:}" | |
| env: | |
| STEPS_BUILD_OUTPUTS_DIGEST: ${{ steps.build.outputs.digest }} | |
| - name: Upload digest | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: digests-${{ env.PLATFORM_PAIR }} | |
| path: ${{ runner.temp }}/digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| merge: | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| runs-on: ubuntu-latest | |
| needs: | |
| - build | |
| steps: | |
| - name: Download digests | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| path: ${{ runner.temp }}/digests | |
| pattern: digests-* | |
| merge-multiple: true | |
| - name: Log into registry ${{ env.REGISTRY }} | |
| uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 | |
| - name: Extract Docker metadata | |
| id: meta | |
| uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=branch | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| - name: Create Manifests and Push | |
| id: manifests | |
| working-directory: ${{ runner.temp }}/digests | |
| run: |- | |
| tags=($(jq -cr '[.tags[] | "-t \(.)"] | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")) | |
| images=($(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)) | |
| echo tags: "${tags[@]}" | |
| echo images: "${images[@]}" | |
| docker buildx imagetools create "${tags[@]}" "${images[@]}" | |
| # Extract the digest | |
| REF=$(jq -r '.tags[0]' <<< "$DOCKER_METADATA_OUTPUT_JSON") | |
| DIGEST=$(docker buildx imagetools inspect "$REF" | grep -i '^Digest:' | awk '{ print $2 }') | |
| echo "Image digest: $DIGEST" | |
| echo "digest=$DIGEST" >> $GITHUB_OUTPUT | |
| # confirm merged image manifests | |
| - name: Inspect Image Manifests | |
| id: inspect | |
| run: |- | |
| tags=($(jq -cr '.tags[] | select(. | endswith(":latest") | not)' <<< "$DOCKER_METADATA_OUTPUT_JSON")) | |
| for tag in "${tags[@]}"; do | |
| docker buildx imagetools inspect $tag | |
| echo | |
| done | |
| - name: Install cosign | |
| uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 | |
| - name: Sign the published Docker image | |
| env: | |
| TAGS: ${{ steps.meta.outputs.tags }} | |
| DIGEST: ${{ steps.manifests.outputs.digest }} | |
| run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} |