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 }}
Comment on lines -102 to -108
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I honestly don't quite understand what was going on here. If anything needs to be adapted, it should be done in the tags input in the Build and push image step below.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When forcing the workflow, there's params that can be set:

Image

The idea is to extract that here, and set that as metadata on the generated containers so that you can do docker run ghcr.io/juliagpu/cuda.jl:dev or ghcr.io/juliagpu/cuda.jl:cuda-12 etc.


- 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