Skip to content
# Copyright (C) 2022 Roberto Rossini (roberros@uio.no)
# SPDX-License-Identifier: MIT
name: "Build Ubuntu Docker images for CXX development/testing"
on:
push:
branches: [ main, devel, ci-devel ]
paths:
- ".github/workflows/build-cxx-ubuntu-images.yml"
- "assets/settings.yml"
- "dockerfiles/ubuntu-cxx.Dockerfile"
pull_request:
branches: [ main, devel, ci-devel ]
paths:
- ".github/workflows/build-cxx-ubuntu-images.yml"
- "assets/settings.yml"
- "dockerfiles/ubuntu-cxx.Dockerfile"
workflow_dispatch:
schedule:
# Run weekly
- cron: "15 0 * * 0"
defaults:
run:
shell: bash
permissions:
contents: read
packages: write
jobs:
matrix-factory:
name: Generate job matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.generate-matrix.outputs.matrix }}
steps:
- name: Generate matrix
id: generate-matrix
shell: python
run: |
import json
import os
import sys
os_name = "ubuntu"
cmake_version = "3.31.*"
conan_version = "2.11.*"
templates = (
{
"compiler-name": "gcc",
"compiler-version": 8,
"os-version": "20.04",
"python-version": "3.9",
},
{
"compiler-name": "gcc",
"compiler-version": 9,
"os-version": "22.04",
"python-version": "3.11",
},
{
"compiler-name": "gcc",
"compiler-version": 10,
"os-version": "24.04",
"python-version": "3.12",
},
{
"compiler-name": "gcc",
"compiler-version": 11,
"os-version": "24.04",
"python-version": "3.12",
},
{
"compiler-name": "gcc",
"compiler-version": 12,
"os-version": "24.04",
"python-version": "3.12",
},
{
"compiler-name": "gcc",
"compiler-version": 13,
"os-version": "24.04",
"python-version": "3.12",
},
{
"compiler-name": "gcc",
"compiler-version": 14,
"os-version": "24.04",
"python-version": "3.12",
},
{
"compiler-name": "clang",
"compiler-version": 8,
"os-version": "20.04",
"python-version": "3.9",
},
{
"compiler-name": "clang",
"compiler-version": 9,
"os-version": "20.04",
"python-version": "3.9",
},
{
"compiler-name": "clang",
"compiler-version": 10,
"os-version": "20.04",
"python-version": "3.9",
},
{
"compiler-name": "clang",
"compiler-version": 11,
"os-version": "22.04",
"python-version": "3.11",
},
{
"compiler-name": "clang",
"compiler-version": 12,
"os-version": "22.04",
"python-version": "3.11",
},
{
"compiler-name": "clang",
"compiler-version": 13,
"os-version": "22.04",
"python-version": "3.11",
},
{
"compiler-name": "clang",
"compiler-version": 14,
"os-version": "24.04",
"python-version": "3.12",
},
{
"compiler-name": "clang",
"compiler-version": 15,
"os-version": "24.04",
"python-version": "3.12",
},
{
"compiler-name": "clang",
"compiler-version": 16,
"os-version": "24.04",
"python-version": "3.12",
},
{
"compiler-name": "clang",
"compiler-version": 17,
"os-version": "24.04",
"python-version": "3.12",
},
{
"compiler-name": "clang",
"compiler-version": 18,
"os-version": "24.04",
"python-version": "3.12",
},
{
"compiler-name": "clang",
"compiler-version": 19,
"os-version": "20.04",
"python-version": "3.9",
},
{
"compiler-name": "clang",
"compiler-version": 19,
"os-version": "22.04",
"python-version": "3.11",
},
{
"compiler-name": "clang",
"compiler-version": 19,
"os-version": "24.04",
"python-version": "3.12",
},
)
includes = []
for t in templates:
t |= {"os-name": os_name, "cmake-version": cmake_version, "conan-version": conan_version}
includes.append(t | {"runner": "ubuntu-24.04", "platform": "linux/amd64"})
includes.append(t | {"runner": "ubuntu-24.04-arm", "platform": "linux/arm64"})
# TODO remove me
includes = includes[-4:]
json.dump(
{"include": includes},
fp=sys.stdout,
indent=2,
sort_keys=True,
)
with open(os.environ.get("GITHUB_OUTPUT"), "a") as f:
print("matrix=", file=f, end="")
json.dump(
{"include": includes},
fp=f,
sort_keys=True,
)
build-dockerfile:
name: Build Dockerfile
needs: [matrix-factory]
outputs:
image: ${{ steps.metadata.outputs.image }}
tag: ${{ steps.metadata.outputs.build-date }}
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.matrix-factory.outputs.matrix) }}
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Extract metadata
id: metadata
run: |
cdate="$(git show -s --format='%as' HEAD | tr -d '-')"
_date="$(date +%Y%m%d)"
image='ghcr.io/${{ github.repository }}/${{ matrix.os-name }}-${{ matrix.os-version }}-cxx-${{ matrix.compiler-name }}-${{ matrix.compiler-version }}'
echo "commit-date=$cdate" | tee -a "$GITHUB_OUTPUT"
echo "build-date=$_date" | tee -a "$GITHUB_OUTPUT"
echo "image=$image" | tee -a "$GITHUB_OUTPUT"
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ steps.metadata.outputs.image }}
flavor: latest=true
tags: type=raw,value=${{ steps.metadata.outputs.build-date }}
- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker image
uses: docker/build-push-action@v6
id: build-image
with:
load: true
push: false
file: dockerfiles/ubuntu-cxx.Dockerfile
labels: ${{ steps.meta.outputs.labels }}
platforms: ${{ matrix.platform }}
tags: tmp:latest
build-args: |
BASE_OS=${{ matrix.os-name }}:${{ matrix.os-version }}
COMPILER_NAME=${{ matrix.compiler-name }}
COMPILER_VERSION=${{ matrix.compiler-version }}
CMAKE_VERSION=${{ matrix.cmake-version }}
CONAN_VERSION=${{ matrix.conan-version }}
PYTHON_VERSION=${{ matrix.python-version }}
- name: Test Docker image
run: test/test_docker_image.sh tmp:latest
- name: Push image to registries
if: github.event_name != 'pull_request'
uses: docker/build-push-action@v6
id: push-image
with:
context: ${{ github.workspace }}
push: true
file: dockerfiles/ubuntu-cxx.Dockerfile
labels: ${{ steps.meta.outputs.labels }}
platforms: ${{ matrix.platform }}
outputs: type=image,"name=${{ steps.metadata.outputs.image }}",push-by-digest=true,name-canonical=true,push=true
build-args: |
BASE_OS=${{ matrix.os-name }}:${{ matrix.os-version }}
COMPILER_NAME=${{ matrix.compiler-name }}
COMPILER_VERSION=${{ matrix.compiler-version }}
CMAKE_VERSION=${{ matrix.cmake-version }}
CONAN_VERSION=${{ matrix.conan-version }}
PYTHON_VERSION=${{ matrix.python-version }}
- name: Export digest
if: github.event_name != 'pull_request'
run: |
mkdir -p ${{ runner.temp }}/digests
digest="${{ steps.push-image.outputs.digest }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"
- name: Generate artifact name
if: github.event_name != 'pull_request'
id: generate-artifact-name
run: |
echo 'name=${{ steps.metadata.outputs.image }}-${{ matrix.platform }}' |
sed 's|[^[:alnum:]-]\+|-|g' |
tee -a $GITHUB_OUTPUT
- name: Upload digest
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v4
with:
name: digests-${{ steps.generate-artifact-name.outputs.name }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
merge-images:
name: Merge images
runs-on: ubuntu-latest
needs:
- matrix-factory
- build-dockerfile
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.matrix-factory.outputs.matrix) }}
if: github.event_name != 'pull_request' && matrix.platform == 'linux/amd64'

Check failure on line 325 in .github/workflows/build-cxx-ubuntu-images.yml

View workflow run for this annotation

GitHub Actions / Build Ubuntu Docker images for CXX development/testing

Invalid workflow file

The workflow is not valid. .github/workflows/build-cxx-ubuntu-images.yml (Line: 325, Col: 9): Unrecognized named-value: 'matrix'. Located at position 40 within expression: github.event_name != 'pull_request' && matrix.platform == 'linux/amd64'
steps:
- name: Generate artifact name
if: github.event_name != 'pull_request'
id: generate-artifact-name
run: |
echo 'name=${{ steps.metadata.outputs.image }}' |
sed 's|[^[:alnum:]-]\+|-|g' |
tee -a $GITHUB_OUTPUT
- name: Download digests
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-${{ steps.generate-artifact-name.outputs.name }}-*
merge-multiple: true
- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
flavor: latest=true
images: ${{ needs.build-dockerfile.outputs.image }}
tags: ${{ needs.build-dockerfile.outputs.tag }}
- name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests
run: |
# https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ needs.build-dockerfile.outputs.image }}@sha256:%s ' *)
- name: Inspect image
run: docker buildx imagetools inspect ${{ needs.build-dockerfile.outputs.image }}:${{ steps.meta.outputs.version }}
build-cxx-ubuntu-images-status-check:
name: Status Check (Build Ubuntu Docker images for CXX development/testing)
if: ${{ always() }}
runs-on: ubuntu-latest
needs:
- matrix-factory
- build-dockerfile
- merge-images
steps:
- name: Collect job results
if: |
needs.matrix-factory.result != 'success' ||
needs.build-dockerfile.result != 'success' ||
(
needs.merge-images.result != 'success' &&
needs.merge-images.result != 'skipped'
)
run: exit 1