Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 99 additions & 18 deletions .github/workflows/Container.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Based on
# * <https://github.com/NumericalEarth/breeze-docker-images/blob/f06a3da11b2c7edaaf0a8e32c133270eb4103b1c/.github/workflows/DockerPublish.yml>
# * <https://docs.github.com/en/actions/publishing-packages/publishing-docker-images>
# * <https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners>.

name: Publish Docker container

on:
Expand All @@ -18,12 +23,20 @@ on:
branches:
- master

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
push_to_registry:
name: Container for ${{ matrix.platform }} - Julia ${{ matrix.julia }} - CUDA ${{ matrix.cuda }}
build:
name: Build Container for ${{ matrix.platform }} - Julia ${{ matrix.julia }} - CUDA ${{ matrix.cuda }}
permissions:
contents: read
packages: write
attestations: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write

strategy:
matrix:
Expand All @@ -46,6 +59,12 @@ jobs:
runs-on: ${{ matrix.os }}

steps:
# Docker is terrible and doesn't like uppercase image names.
- name: Lowercase image name
run: |
IMAGE_NAME=$(echo ${IMAGE_NAME} | tr A-Z a-z)
echo "IMAGE_NAME=${IMAGE_NAME}" >> "${GITHUB_ENV}"

- name: Check out the repo
uses: actions/checkout@v6

Expand Down Expand Up @@ -90,37 +109,99 @@ jobs:
- name: Log in to registry
uses: docker/login-action@v3
with:
registry: ghcr.io
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=${{ steps.pkg.outputs.name }}-julia${{ matrix.julia }}-cuda${{ steps.cuda.outputs.major }}
type=raw,value=${{ steps.pkg.outputs.name }},enable=${{ matrix.default == true && (github.ref_type == 'tag' || inputs.tag != '') }}
type=raw,value=latest,enable=${{ matrix.default == true && (github.ref_type == 'tag' || (inputs.tag != '' && inputs.mark_as_latest)) }}
type=raw,value=dev,enable=${{ matrix.default == true && github.ref_type == 'branch' && inputs.tag == '' }}
labels: |
org.opencontainers.image.version=${{ steps.pkg.outputs.version }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build and push image
id: build
uses: docker/build-push-action@v6
with:
context: .
push: true
provenance: false # the build fetches the repo again, so provenance tracking is not useful
platforms: ${{ matrix.platform }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.pkg.outputs.name }}-julia${{ matrix.julia }}-cuda${{ steps.cuda.outputs.major }}
labels: |
org.opencontainers.image.version=${{ steps.pkg.outputs.version }}
build-args: |
JULIA_VERSION=${{ matrix.julia }}
CUDA_VERSION=${{ matrix.cuda }}
PACKAGE_SPEC=CUDA#${{ steps.pkg.outputs.ref }}
JULIA_CPU_TARGET=${{ steps.cpu_target.outputs.target }}

- name: Export digest
id: export-digest
run: |
mkdir -p /tmp/digests
digest_name=${{ steps.pkg.outputs.name }}-julia${{ matrix.julia }}-cuda${{ steps.cuda.outputs.major }}-$(echo ${{ matrix.platform }} | tr / -)
echo "digest_name=${digest_name}" | tee "${GITHUB_OUTPUT}"
echo "${{ steps.build.outputs.digest }}" > "/tmp/digests/${digest_name}"

- name: Upload digest
uses: actions/upload-artifact@v6
with:
name: digests-${{ steps.export-digest.outputs.digest_name }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

merge:
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write
if: github.event_name != 'pull_request'

steps:
# Docker is terrible and doesn't like uppercase image names.
- name: Lowercase image name
run: |
IMAGE_NAME=$(echo ${IMAGE_NAME} | tr A-Z a-z)
echo "IMAGE_NAME=${IMAGE_NAME}" >> "${GITHUB_ENV}"

- name: Download digests
uses: actions/download-artifact@v7
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true

# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

# Log into the registry.
# https://github.com/docker/login-action
- name: Log into registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Create manifest lists for each tag
run: |
for file in /tmp/digests/*; do
TAG=${file##*/} # e.g. "dev-julia1.11-cuda11-linux-amd64"
VARIANT=$(echo ${TAG} | cut -d- -f1-3) # e.g. "dev-julia1.11-cuda11"
# buildx imagetools needs: -t registry/image:tag and sources
SOURCES=""
for f in /tmp/digests/${VARIANT}-*; do
# each f contains a digest per arch
DIG=$(cat "${f}")
PLATFORM=${f##*/} # e.g. "docs-linux-amd64"
SOURCES="${SOURCES} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${DIG}"
done
docker buildx imagetools create \
--tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${VARIANT} \
${SOURCES}
done