Update docker/build-push-action action to v6.18.0 (#8) #9
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
# This workflow builds a multi-arch Docker image using GitHub Actions and separated Github Runners with native support for ARM64 and AMD64 architectures, without using QEMU emulation. | |
# It uses Docker Buildx to build and push the image to GitHub Container Registry (GHCR). | |
name: Build multi arch Docker Image with separate Github Runners | |
on: | |
workflow_dispatch: | |
push: | |
branches: | |
- main | |
paths: | |
- 'Dockerfile' | |
- '.github/workflows/multi-build.yaml' | |
env: | |
# The name of the Docker image to be built and pushed to GHCR | |
# The image name is derived from the GitHub repository name and the GitHub Container Registry (GHCR) URL. | |
# The image name will be in the format: ghcr.io/<owner>/<repo> | |
GHCR_IMAGE: ghcr.io/${{ github.repository }} | |
permissions: | |
# Global permissions for the workflow, which can be overridden at the job level | |
contents: read | |
concurrency: | |
# This concurrency group ensures that only one job in the group runs at a time. | |
# If a new job is triggered, the previous one will be canceled. | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
jobs: | |
# The build job builds the Docker image for each platform specified in the matrix. | |
build: | |
strategy: | |
fail-fast: false | |
matrix: | |
platform: | |
- linux/amd64 | |
- linux/arm64 | |
# The matrix includes two platforms: linux/amd64 and linux/arm64. | |
# The build job will run for each platform in the matrix. | |
permissions: | |
# Permissions for the build job, which can be overridden at the step level | |
# The permissions are set to allow the job to write to the GitHub Container Registry (GHCR) and read from the repository. | |
attestations: write | |
actions: read | |
checks: write | |
contents: write | |
deployments: none | |
id-token: write | |
issues: read | |
discussions: read | |
packages: write | |
pages: none | |
pull-requests: read | |
repository-projects: read | |
security-events: read | |
statuses: read | |
runs-on: ${{ matrix.platform == 'linux/amd64' && 'ubuntu-latest' || matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' }} | |
# The job runs on different runners based on the platform. | |
# For linux/amd64, it runs on the latest Ubuntu runner. | |
# For linux/arm64, it runs on an Ubuntu 24.04 ARM runner. | |
# The runner is selected based on the platform specified in the matrix. | |
name: Build Docker image for ${{ matrix.platform }} | |
steps: | |
- | |
name: Prepare environment for current platform | |
# This step sets up the environment for the current platform being built. | |
# It replaces the '/' character in the platform name with '-' and sets it as an environment variable. | |
# This is useful for naming artifacts and other resources that cannot contain '/'. | |
# The environment variable PLATFORMS_PAIR will be used later in the workflow. | |
id: prepare | |
run: | | |
platform=${{ matrix.platform }} | |
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV | |
- name: Checkout | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
# This step checks out the code from the repository. | |
# It uses the actions/checkout action to clone the repository into the runner's workspace. | |
- name: Docker meta default | |
# This step generates metadata for the Docker image. | |
# It uses the docker/metadata-action to create metadata based on the repository information. | |
# The metadata includes information such as the image name, tags, and labels. | |
# The metadata will be used later in the workflow to build and push the Docker image. | |
id: meta | |
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 | |
with: | |
images: ${{ env.GHCR_IMAGE }} | |
- name: Set up Docker Context for Buildx | |
# This step sets up a Docker context for Buildx. | |
# It creates a new context named "builders" that will be used for building the Docker image. | |
# The context allows Buildx to use the Docker daemon for building images. | |
id: buildx-context | |
run: | | |
docker context create builders | |
- name: Set up Docker Buildx | |
# This step sets up Docker Buildx, which is a Docker CLI plugin for extended build capabilities with BuildKit. | |
# It uses the docker/setup-buildx-action to configure Buildx with the specified context and platforms. | |
# The platforms are specified in the matrix and will be used for building the Docker image. | |
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 | |
with: | |
endpoint: builders | |
platforms: ${{ matrix.platform }} | |
- name: Login to GitHub Container Registry | |
# This step logs in to the GitHub Container Registry (GHCR) using the docker/login-action. | |
# It uses the GitHub actor's username and the GITHUB_TOKEN secret for authentication. | |
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Build and push by digest | |
# This step builds and pushes the Docker image using Buildx. | |
# It uses the docker/build-push-action to build the image with the specified context and platforms. | |
# The image is built with the labels and annotations generated in the previous steps. | |
# The outputs are configured to push the image by digest, which allows for better caching and versioning. | |
# The cache-from and cache-to options are used to enable caching for the build process. | |
# The cache is stored in GitHub Actions cache and is scoped to the repository, branch, and platform. | |
id: build | |
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 | |
env: | |
DOCKER_BUILDKIT: 1 | |
with: | |
context: . | |
platforms: ${{ matrix.platform }} | |
labels: ${{ steps.meta.outputs.labels }} | |
annotations: ${{ steps.meta.outputs.annotations }} | |
outputs: type=image,name=${{ env.GHCR_IMAGE }},push-by-digest=true,name-canonical=true,push=true,oci-mediatypes=true | |
cache-from: type=gha,scope=${{ github.repository }}-${{ github.ref_name }}-${{ matrix.platform }} | |
cache-to: type=gha,scope=${{ github.repository }}-${{ github.ref_name }}-${{ matrix.platform }} | |
- name: Export digest | |
# This step exports the digest of the built image to a file. | |
# It creates a directory in /tmp/digests and saves the digest of the image to a file. | |
# The digest is obtained from the output of the build step. | |
# The digest is used to uniquely identify the built image and can be used for further processing or verification. | |
run: | | |
mkdir -p /tmp/digests | |
digest="${{ steps.build.outputs.digest }}" | |
touch "/tmp/digests/${digest#sha256:}" | |
- name: Upload digest | |
# This step uploads the digest file to the GitHub Actions artifact storage. | |
# It uses the actions/upload-artifact action to upload the file created in the previous step. | |
# The artifact is named digests-${{ env.PLATFORM_PAIR }}, where PLATFORM_PAIR is the platform name with '/' replaced by '-'. | |
# The artifact is retained for 1 day, and if no files are found, it will throw an error. | |
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
with: | |
name: digests-${{ env.PLATFORM_PAIR }} | |
path: /tmp/digests/* | |
if-no-files-found: error | |
retention-days: 1 | |
merge: | |
# This job merges the Docker manifests for the different platforms built in the previous job. | |
name: Merge Docker manifests | |
runs-on: ubuntu-latest | |
permissions: | |
attestations: write | |
actions: read | |
checks: read | |
contents: read | |
deployments: none | |
id-token: write | |
issues: read | |
discussions: read | |
packages: write | |
pages: none | |
pull-requests: read | |
repository-projects: read | |
security-events: read | |
statuses: read | |
needs: | |
- build | |
# This job depends on the build job to complete before it starts. | |
# It ensures that the Docker images for all platforms are built before merging the manifests. | |
steps: | |
- name: Download digests | |
# This step downloads the digest files uploaded in the build job. | |
# It uses the actions/download-artifact action to download the artifacts with the pattern digests-*. | |
# The downloaded files are merged into the /tmp/digests directory. | |
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
with: | |
path: /tmp/digests | |
pattern: digests-* | |
merge-multiple: true | |
- name: Docker meta | |
# This step generates metadata for the Docker image. | |
# It uses the docker/metadata-action to create metadata based on the repository information. | |
# The metadata includes information such as the image name, tags, and labels. | |
id: meta | |
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 | |
with: | |
images: ${{ env.GHCR_IMAGE }} | |
annotations: | | |
type=org.opencontainers.image.description,value=${{ github.event.repository.description || 'No description provided' }} | |
tags: | | |
type=raw,value=main,enable=${{ github.ref_name == 'main' }} | |
type=raw,value=latest,enable=${{ github.ref_name == 'main' }} | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 | |
# This step sets up Docker Buildx, which is a Docker CLI plugin for extended build capabilities with BuildKit. | |
with: | |
driver-opts: | | |
network=host | |
- name: Login to GitHub Container Registry | |
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 | |
# This step logs in to the GitHub Container Registry (GHCR) using the docker/login-action. | |
# It uses the GitHub actor's username and the GITHUB_TOKEN secret for authentication. | |
# The login is necessary to push the merged manifest list to GHCR. | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Get execution timestamp with RFC3339 format | |
# This step gets the current execution timestamp in RFC3339 format. | |
# It uses the date command to get the current UTC time and formats it as a string. | |
# The timestamp is used for annotating the Docker manifest list. | |
id: timestamp | |
run: | | |
echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT | |
- name: Create manifest list and pushs | |
# This step creates a manifest list for the Docker images built for different platforms. | |
# It uses the docker buildx imagetools create command to create the manifest list. | |
# The manifest list is annotated with metadata such as description, creation timestamp, and source URL. | |
# The annotations are obtained from the metadata generated in the previous steps. | |
# The manifest list is pushed to the GitHub Container Registry (GHCR) with the specified tags. | |
working-directory: /tmp/digests | |
id: manifest-annotate | |
continue-on-error: true | |
run: | | |
docker buildx imagetools create \ | |
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
--annotation='index:org.opencontainers.image.description=${{ github.event.repository.description }}' \ | |
--annotation='index:org.opencontainers.image.created=${{ steps.timestamp.outputs.timestamp }}' \ | |
--annotation='index:org.opencontainers.image.url=${{ github.event.repository.url }}' \ | |
--annotation='index:org.opencontainers.image.source=${{ github.event.repository.url }}' \ | |
$(printf '${{ env.GHCR_IMAGE }}@sha256:%s ' *) | |
- name: Create manifest list and push without annotations | |
# This step creates a manifest list for the Docker images built for different platforms. | |
# It uses the docker buildx imagetools create command to create the manifest list. | |
# The manifest list is created without annotations if the previous step fails. | |
# The manifest list is pushed to the GitHub Container Registry (GHCR) with the specified tags. | |
if: steps.manifest-annotate.outcome == 'failure' | |
working-directory: /tmp/digests | |
run: | | |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
$(printf '${{ env.GHCR_IMAGE }}@sha256:%s ' *) | |
- name: Inspect image | |
# This step inspects the created manifest list to verify its contents. | |
# It uses the docker buildx imagetools inspect command to display information about the manifest list. | |
# The inspection output will show the platforms and tags associated with the manifest list. | |
id: inspect | |
run: | | |
docker buildx imagetools inspect '${{ env.GHCR_IMAGE }}:${{ steps.meta.outputs.version }}' |