Skip to content
Merged
Show file tree
Hide file tree
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
264 changes: 27 additions & 237 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,100 +23,8 @@ env:


jobs:
# Build jobs for PRs, main, and tags - no publishing
build-amd64:
if: github.event_name == 'pull_request' || (github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')))
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v4

# Fetch latest versions of CMake and Catch2
- name: Get latest CMake version
id: cmake_version
run: |
CMAKE_VERSION=$(curl -s https://api.github.com/repos/Kitware/CMake/releases/latest | jq -r '.tag_name')
echo "version=$CMAKE_VERSION" >> $GITHUB_OUTPUT
echo "Latest CMake version: $CMAKE_VERSION"

- name: Get latest Catch2 version
id: catch2_version
run: |
CATCH2_VERSION=$(curl -s https://api.github.com/repos/catchorg/Catch2/releases/latest | jq -r '.tag_name')
echo "version=$CATCH2_VERSION" >> $GITHUB_OUTPUT
echo "Latest Catch2 version: $CATCH2_VERSION"

# Set up BuildKit Docker container builder
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0

# Build Docker image for amd64 (no push)
- name: Build Docker image (amd64)
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
platforms: linux/amd64
push: false
cache-from: type=gha,scope=amd64
cache-to: type=gha,mode=max,scope=amd64
# Enable build optimizations
provenance: false
sbom: false
build-args: |
CMAKE_VERSION=${{ steps.cmake_version.outputs.version }}
CATCH2_VERSION=${{ steps.catch2_version.outputs.version }}

build-arm64:
if: github.event_name == 'pull_request' || (github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')))
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v4
build:

# Fetch latest versions of CMake and Catch2
- name: Get latest CMake version
id: cmake_version
run: |
CMAKE_VERSION=$(curl -s https://api.github.com/repos/Kitware/CMake/releases/latest | jq -r '.tag_name')
echo "version=$CMAKE_VERSION" >> $GITHUB_OUTPUT
echo "Latest CMake version: $CMAKE_VERSION"

- name: Get latest Catch2 version
id: catch2_version
run: |
CATCH2_VERSION=$(curl -s https://api.github.com/repos/catchorg/Catch2/releases/latest | jq -r '.tag_name')
echo "version=$CATCH2_VERSION" >> $GITHUB_OUTPUT
echo "Latest Catch2 version: $CATCH2_VERSION"

# Set up BuildKit Docker container builder
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0

# Build Docker image for arm64 (no push)
- name: Build Docker image (arm64)
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
platforms: linux/arm64
push: false
cache-from: type=gha,scope=arm64
cache-to: type=gha,mode=max,scope=arm64
# Enable ARM64 build optimizations
provenance: false
sbom: false
build-args: |
CMAKE_VERSION=${{ steps.cmake_version.outputs.version }}
CATCH2_VERSION=${{ steps.catch2_version.outputs.version }}

# Publish jobs for schedule and main - with publishing
publish-amd64:
if: github.event_name == 'schedule' || (github.event_name == 'push' && github.ref == 'refs/heads/main')
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down Expand Up @@ -144,187 +52,69 @@ jobs:
echo "version=$CATCH2_VERSION" >> $GITHUB_OUTPUT
echo "Latest Catch2 version: $CATCH2_VERSION"

# Install the cosign tool
# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 #v3.5.0
with:
cosign-release: 'v2.2.4'

# Set up BuildKit Docker container builder
# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0

# Login against Docker registry
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: |
suffix=-amd64

# Build and push Docker image for amd64
- name: Build and push Docker image (amd64)
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
platforms: linux/amd64
push: true
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=amd64
cache-to: type=gha,mode=max,scope=amd64
# Enable build optimizations
provenance: false
sbom: false
build-args: |
CMAKE_VERSION=${{ steps.cmake_version.outputs.version }}
CATCH2_VERSION=${{ steps.catch2_version.outputs.version }}

# Sign the published Docker image
- name: Sign the published Docker image
env:
TAGS: ${{ steps.meta.outputs.tags }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}

publish-arm64:
if: github.event_name == 'schedule' || (github.event_name == 'push' && github.ref == 'refs/heads/main')
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

# Fetch latest versions of CMake and Catch2
- name: Get latest CMake version
id: cmake_version
run: |
CMAKE_VERSION=$(curl -s https://api.github.com/repos/Kitware/CMake/releases/latest | jq -r '.tag_name')
echo "version=$CMAKE_VERSION" >> $GITHUB_OUTPUT
echo "Latest CMake version: $CMAKE_VERSION"

- name: Get latest Catch2 version
id: catch2_version
run: |
CATCH2_VERSION=$(curl -s https://api.github.com/repos/catchorg/Catch2/releases/latest | jq -r '.tag_name')
echo "version=$CATCH2_VERSION" >> $GITHUB_OUTPUT
echo "Latest Catch2 version: $CATCH2_VERSION"

# Install the cosign tool
- name: Install cosign
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 #v3.5.0
with:
cosign-release: 'v2.2.4'

# Set up BuildKit Docker container builder
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0

# Login against Docker registry
- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: |
suffix=-arm64

# Build and push Docker image for arm64
- name: Build and push Docker image (arm64)
id: build-and-push
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
platforms: linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=arm64
cache-to: type=gha,mode=max,scope=arm64
cache-from: type=gha
cache-to: type=gha,mode=max
# Enable ARM64 build optimizations
provenance: false
sbom: false
build-args: |
CMAKE_VERSION=${{ steps.cmake_version.outputs.version }}
CATCH2_VERSION=${{ steps.catch2_version.outputs.version }}

# Sign the published Docker image
# Sign the resulting Docker image digest except on PRs.
# This will only write to the public Rekor transparency log when the Docker
# repository is public to avoid leaking data. If you would like to publish
# transparency data even for private images, pass --force to cosign below.
# https://github.com/sigstore/cosign
- name: Sign the published Docker image
if: ${{ github.event_name != 'pull_request' }}
env:
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
TAGS: ${{ steps.meta.outputs.tags }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
# This step uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}


# Create multi-arch manifest combining both architectures
create-manifest:
if: github.event_name == 'schedule' || (github.event_name == 'push' && github.ref == 'refs/heads/main')
needs: [publish-amd64, publish-arm64]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

# Set up BuildKit Docker container builder
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0

# Login against Docker registry
- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

# Create and push multi-arch manifest
- name: Create and push multi-arch manifest
run: |
# Get the tags that were created
TAGS="${{ steps.meta.outputs.tags }}"

for TAG in $TAGS; do
echo "Creating manifest for tag: $TAG"

# Create manifest list combining both architectures
docker buildx imagetools create \
--tag "$TAG" \
"$TAG-amd64" \
"$TAG-arm64"
done
21 changes: 0 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,6 @@ The image sets the following environment variables to optimize builds:
- `MAKEFLAGS="-j$(nproc)"` - Enables parallel make builds
- `CMAKE_BUILD_PARALLEL_LEVEL=$(nproc)` - Enables parallel CMake builds

## CI/CD Pipeline

The project uses a multi-job GitHub Actions workflow that separates build and publish operations for better parallelization and control:

### Build Jobs
- **build-amd64**: Tests building for linux/amd64 on PRs, main branch, and tags
- **build-arm64**: Tests building for linux/arm64 on PRs, main branch, and tags
- Build jobs validate the Docker image can be built successfully but don't publish to registry

### Publish Jobs
- **publish-amd64**: Builds and publishes linux/amd64 images on scheduled runs and main branch pushes
- **publish-arm64**: Builds and publishes linux/arm64 images on scheduled runs and main branch pushes
- **create-manifest**: Combines both architecture-specific images into a multi-architecture manifest

### Benefits
- **Parallel Execution**: Each architecture builds independently for faster CI/CD
- **Clear Separation**: Build validation separate from publishing reduces complexity
- **Architecture-Specific Control**: Individual job control and troubleshooting per architecture
- **Optimized Caching**: Separate cache scopes for each architecture improve build performance
- **Multi-arch Support**: Final images support both amd64 and arm64 architectures seamlessly

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
Loading