Merge pull request #2650 from tdonohue/fix_docker_manifests_again #1009
This file contains 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
# DSpace Docker image build for hub.docker.com | |
name: Docker images | |
# Run this Build for all pushes to 'main' or maintenance branches, or tagged releases. | |
# Also run for PRs to ensure PR doesn't break Docker build process | |
on: | |
push: | |
branches: | |
- main | |
- 'dspace-**' | |
tags: | |
- 'dspace-**' | |
pull_request: | |
permissions: | |
contents: read # to fetch code (actions/checkout) | |
env: | |
REGISTRY_IMAGE: dspace/dspace-angular | |
# Define tags to use for Docker images based on Git tags/branches (for docker/metadata-action) | |
# For a new commit on default branch (main), use the literal tag 'latest' on Docker image. | |
# For a new commit on other branches, use the branch name as the tag for Docker image. | |
# For a new tag, copy that tag name as the tag for Docker image. | |
IMAGE_TAGS: | | |
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} | |
type=ref,event=branch,enable=${{ !endsWith(github.ref, github.event.repository.default_branch) }} | |
type=ref,event=tag | |
# Define default tag "flavor" for docker/metadata-action per | |
# https://github.com/docker/metadata-action#flavor-input | |
# We manage the 'latest' tag ourselves to the 'main' branch (see settings above) | |
TAGS_FLAVOR: | | |
latest=false | |
jobs: | |
############################################################# | |
# Build/Push the '${{ env.REGISTRY_IMAGE }}' image | |
############################################################# | |
dspace-angular: | |
# Ensure this job never runs on forked repos. It's only executed for 'dspace/dspace-angular' | |
if: github.repository == 'dspace/dspace-angular' | |
strategy: | |
matrix: | |
# Architectures / Platforms for which we will build Docker images | |
arch: ['linux/amd64', 'linux/arm64'] | |
os: [ubuntu-latest] | |
isPr: | |
- ${{ github.event_name == 'pull_request' }} | |
# If this is a PR, we ONLY build for AMD64. For PRs we only do a sanity check test to ensure Docker builds work. | |
# The below exclude therefore ensures we do NOT build ARM64 for PRs. | |
exclude: | |
- isPr: true | |
os: ubuntu-latest | |
arch: linux/arm64 | |
runs-on: ${{ matrix.os }} | |
steps: | |
# https://github.com/actions/checkout | |
- name: Checkout codebase | |
uses: actions/checkout@v4 | |
# https://github.com/docker/setup-buildx-action | |
- name: Setup Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
# https://github.com/docker/setup-qemu-action | |
- name: Set up QEMU emulation to build for multiple architectures | |
uses: docker/setup-qemu-action@v3 | |
# https://github.com/docker/login-action | |
- name: Login to DockerHub | |
# Only login if not a PR, as PRs only trigger a Docker build and not a push | |
if: ${{ ! matrix.isPr }} | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ secrets.DOCKER_USERNAME }} | |
password: ${{ secrets.DOCKER_ACCESS_TOKEN }} | |
# https://github.com/docker/metadata-action | |
# Get Metadata for docker_build step below | |
- name: Sync metadata (tags, labels) from GitHub to Docker for 'dspace-angular' image | |
id: meta_build | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.REGISTRY_IMAGE }} | |
tags: ${{ env.IMAGE_TAGS }} | |
flavor: ${{ env.TAGS_FLAVOR }} | |
# https://github.com/docker/build-push-action | |
- name: Build and push 'dspace-angular' image | |
id: docker_build | |
uses: docker/build-push-action@v5 | |
with: | |
context: . | |
file: ./Dockerfile | |
platforms: ${{ matrix.arch }} | |
# For pull requests, we run the Docker build (to ensure no PR changes break the build), | |
# but we ONLY do an image push to DockerHub if it's NOT a PR | |
push: ${{ ! matrix.isPr }} | |
# Use tags / labels provided by 'docker/metadata-action' above | |
tags: ${{ steps.meta_build.outputs.tags }} | |
labels: ${{ steps.meta_build.outputs.labels }} | |
# Export the digest of Docker build locally (for non PRs only) | |
- name: Export digest | |
if: ${{ ! matrix.isPr }} | |
run: | | |
mkdir -p /tmp/digests | |
digest="${{ steps.docker_build.outputs.digest }}" | |
touch "/tmp/digests/${digest#sha256:}" | |
# Upload digest to an artifact, so that it can be used in manifest below | |
- name: Upload digest | |
if: ${{ ! matrix.isPr }} | |
uses: actions/upload-artifact@v3 | |
with: | |
name: digests | |
path: /tmp/digests/* | |
if-no-files-found: error | |
retention-days: 1 | |
# Merge digests into a manifest. | |
# This runs after all Docker builds complete above, and it tells hub.docker.com | |
# that these builds should be all included in the manifest for this tag. | |
# (e.g. AMD64 and ARM64 should be listed as options under the same tagged Docker image) | |
# Borrowed from https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners | |
dspace-angular_manifest: | |
if: ${{ github.event_name != 'pull_request' }} | |
runs-on: ubuntu-latest | |
needs: | |
- dspace-angular | |
steps: | |
- name: Download digests | |
uses: actions/download-artifact@v3 | |
with: | |
name: digests | |
path: /tmp/digests | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Add Docker metadata for image | |
id: meta | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.REGISTRY_IMAGE }} | |
tags: ${{ env.IMAGE_TAGS }} | |
flavor: ${{ env.TAGS_FLAVOR }} | |
- name: Login to Docker Hub | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ secrets.DOCKER_USERNAME }} | |
password: ${{ secrets.DOCKER_ACCESS_TOKEN }} | |
- name: Create manifest list from digests and push | |
working-directory: /tmp/digests | |
run: | | |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) | |
- name: Inspect image | |
run: | | |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} | |
############################################################# | |
# Build/Push the '${{ env.REGISTRY_IMAGE }}' image ('-dist' tag) | |
############################################################# | |
dspace-angular-dist: | |
# Ensure this job never runs on forked repos. It's only executed for 'dspace/dspace-angular' | |
if: github.repository == 'dspace/dspace-angular' | |
strategy: | |
matrix: | |
# Architectures / Platforms for which we will build Docker images | |
arch: ['linux/amd64', 'linux/arm64'] | |
os: [ubuntu-latest] | |
isPr: | |
- ${{ github.event_name == 'pull_request' }} | |
# If this is a PR, we ONLY build for AMD64. For PRs we only do a sanity check test to ensure Docker builds work. | |
# The below exclude therefore ensures we do NOT build ARM64 for PRs. | |
exclude: | |
- isPr: true | |
os: ubuntu-latest | |
arch: linux/arm64 | |
runs-on: ${{ matrix.os }} | |
steps: | |
# https://github.com/actions/checkout | |
- name: Checkout codebase | |
uses: actions/checkout@v4 | |
# https://github.com/docker/setup-buildx-action | |
- name: Setup Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
# https://github.com/docker/setup-qemu-action | |
- name: Set up QEMU emulation to build for multiple architectures | |
uses: docker/setup-qemu-action@v3 | |
# https://github.com/docker/login-action | |
- name: Login to DockerHub | |
# Only login if not a PR, as PRs only trigger a Docker build and not a push | |
if: ${{ ! matrix.isPr }} | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ secrets.DOCKER_USERNAME }} | |
password: ${{ secrets.DOCKER_ACCESS_TOKEN }} | |
# https://github.com/docker/metadata-action | |
# Get Metadata for docker_build_dist step below | |
- name: Sync metadata (tags, labels) from GitHub to Docker for 'dspace-angular-dist' image | |
id: meta_build_dist | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.REGISTRY_IMAGE }} | |
tags: ${{ env.IMAGE_TAGS }} | |
# As this is a "dist" image, its tags are all suffixed with "-dist". Otherwise, it uses the same | |
# tagging logic as the primary '${{ env.REGISTRY_IMAGE }}' image above. | |
flavor: ${{ env.TAGS_FLAVOR }} | |
suffix=-dist | |
- name: Build and push 'dspace-angular-dist' image | |
id: docker_build_dist | |
uses: docker/build-push-action@v5 | |
with: | |
context: . | |
file: ./Dockerfile.dist | |
platforms: ${{ matrix.arch }} | |
# For pull requests, we run the Docker build (to ensure no PR changes break the build), | |
# but we ONLY do an image push to DockerHub if it's NOT a PR | |
push: ${{ ! matrix.isPr }} | |
# Use tags / labels provided by 'docker/metadata-action' above | |
tags: ${{ steps.meta_build_dist.outputs.tags }} | |
labels: ${{ steps.meta_build_dist.outputs.labels }} | |
# Export the digest of Docker build locally (for non PRs only) | |
- name: Export digest | |
if: ${{ ! matrix.isPr }} | |
run: | | |
mkdir -p /tmp/digests | |
digest="${{ steps.docker_build_dist.outputs.digest }}" | |
touch "/tmp/digests/${digest#sha256:}" | |
# Upload Digest to an artifact, so that it can be used in manifest below | |
- name: Upload digest | |
if: ${{ ! matrix.isPr }} | |
uses: actions/upload-artifact@v3 | |
with: | |
# NOTE: It's important that this artifact has a unique name so that two | |
# image builds don't upload digests to the same artifact. | |
name: digests-dist | |
path: /tmp/digests/* | |
if-no-files-found: error | |
retention-days: 1 | |
# Merge *-dist digests into a manifest. | |
# This runs after all Docker builds complete above, and it tells hub.docker.com | |
# that these builds should be all included in the manifest for this tag. | |
# (e.g. AMD64 and ARM64 should be listed as options under the same tagged Docker image) | |
dspace-angular-dist_manifest: | |
if: ${{ github.event_name != 'pull_request' }} | |
runs-on: ubuntu-latest | |
needs: | |
- dspace-angular-dist | |
steps: | |
- name: Download digests for -dist builds | |
uses: actions/download-artifact@v3 | |
with: | |
name: digests-dist | |
path: /tmp/digests | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Add Docker metadata for image | |
id: meta_dist | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.REGISTRY_IMAGE }} | |
tags: ${{ env.IMAGE_TAGS }} | |
# As this is a "dist" image, its tags are all suffixed with "-dist". Otherwise, it uses the same | |
# tagging logic as the primary '${{ env.REGISTRY_IMAGE }}' image above. | |
flavor: ${{ env.TAGS_FLAVOR }} | |
suffix=-dist | |
- name: Login to Docker Hub | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ secrets.DOCKER_USERNAME }} | |
password: ${{ secrets.DOCKER_ACCESS_TOKEN }} | |
- name: Create manifest list from digests and push | |
working-directory: /tmp/digests | |
run: | | |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) | |
- name: Inspect image | |
run: | | |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta_dist.outputs.version }} |