Skip to content
Open
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
272 changes: 124 additions & 148 deletions .github/workflows/container-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,149 +17,60 @@ on:

jobs:
build:
runs-on: ubuntu-latest
runs-on: ${{ matrix.arch.runner }}

strategy:
fail-fast: false
matrix:
include:
- os: rockylinux
version: "8"
context: rockylinux-8
file: rockylinux-8/Containerfile
- os: rockylinux
version: "8.9"
context: rockylinux-8
file: rockylinux-8/Containerfile-8.9
- os: rockylinux
version: "8.10"
context: rockylinux-8
file: rockylinux-8/Containerfile-8.10
- os: rockylinux
version: "9"
context: rockylinux-9
file: rockylinux-9/Containerfile
- os: rockylinux
version: "9.6"
context: rockylinux-9
file: rockylinux-9/Containerfile-9.6
- os: rockylinux
version: "9.7"
context: rockylinux-9
file: rockylinux-9/Containerfile-9.7
- os: rockylinux
version: "10"
context: rockylinux-10
file: rockylinux-10/Containerfile
- os: rockylinux
version: "10.0"
context: rockylinux-10
file: rockylinux-10/Containerfile-10.0
- os: rockylinux
version: "10.1"
context: rockylinux-10
file: rockylinux-10/Containerfile-10.1
- os: almalinux
version: "8"
context: almalinux-8
file: almalinux-8/Containerfile
- os: almalinux
version: "8.9"
context: almalinux-8
file: almalinux-8/Containerfile-8.9
- os: almalinux
version: "8.10"
context: almalinux-8
file: almalinux-8/Containerfile-8.10
- os: almalinux
version: "9"
context: almalinux-9
file: almalinux-9/Containerfile
- os: almalinux
version: "9.6"
context: almalinux-9
file: almalinux-9/Containerfile-9.6
- os: almalinux
version: "9.7"
context: almalinux-9
file: almalinux-9/Containerfile-9.7
- os: almalinux
version: "10"
context: almalinux-10
file: almalinux-10/Containerfile
- os: almalinux
version: "10.0"
context: almalinux-10
file: almalinux-10/Containerfile-10.0
- os: almalinux
version: "10.1"
context: almalinux-10
file: almalinux-10/Containerfile-10.1
- os: leap
version: "15"
context: leap
file: leap/Containerfile-15
- os: leap
version: "16"
context: leap
file: leap/Containerfile-16.0
- os: leap
version: "16.0"
context: leap
file: leap/Containerfile-16.0
- os: tumbleweed
version: latest
context: tumbleweed
file: tumbleweed/Containerfile
- os: debian
version: "12"
context: debian
file: debian/Containerfile-12
- os: debian
version: "13"
context: debian
file: debian/Containerfile-13
- os: openeuler
version: "24.03"
context: openeuler-24.03
file: openeuler-24.03/Containerfile
- os: ubuntu
version: "24.04"
context: ubuntu
file: ubuntu/Containerfile-24.04
- os: ubuntu
version: "26.04"
context: ubuntu
file: ubuntu/Containerfile-26.04
arch:
- {platform: linux/amd64, runner: ubuntu-latest, platform_pair: linux-amd64}
- {platform: linux/arm64, runner: ubuntu-24.04-arm, platform_pair: linux-arm64}
image:
- {os: rockylinux, version: "8", context: rockylinux-8, file: rockylinux-8/Containerfile}
- {os: rockylinux, version: "8.9", context: rockylinux-8, file: rockylinux-8/Containerfile-8.9}
- {os: rockylinux, version: "8.10", context: rockylinux-8, file: rockylinux-8/Containerfile-8.10}
- {os: rockylinux, version: "9", context: rockylinux-9, file: rockylinux-9/Containerfile}
- {os: rockylinux, version: "9.7", context: rockylinux-9, file: rockylinux-9/Containerfile-9.7}
- {os: rockylinux, version: "9.8", context: rockylinux-9, file: rockylinux-9/Containerfile-9.8}
- {os: rockylinux, version: "10", context: rockylinux-10, file: rockylinux-10/Containerfile}
- {os: rockylinux, version: "10.1", context: rockylinux-10, file: rockylinux-10/Containerfile-10.1}
- {os: rockylinux, version: "10.2", context: rockylinux-10, file: rockylinux-10/Containerfile-10.2}
- {os: almalinux, version: "8", context: almalinux-8, file: almalinux-8/Containerfile}
- {os: almalinux, version: "8.9", context: almalinux-8, file: almalinux-8/Containerfile-8.9}
- {os: almalinux, version: "8.10", context: almalinux-8, file: almalinux-8/Containerfile-8.10}
- {os: almalinux, version: "9", context: almalinux-9, file: almalinux-9/Containerfile}
- {os: almalinux, version: "9.7", context: almalinux-9, file: almalinux-9/Containerfile-9.7}
- {os: almalinux, version: "9.8", context: almalinux-9, file: almalinux-9/Containerfile-9.8}
- {os: almalinux, version: "10", context: almalinux-10, file: almalinux-10/Containerfile}
- {os: almalinux, version: "10.1", context: almalinux-10, file: almalinux-10/Containerfile-10.1}
- {os: almalinux, version: "10.2", context: almalinux-10, file: almalinux-10/Containerfile-10.2}
- {os: leap, version: "15", context: leap, file: leap/Containerfile-15}
- {os: leap, version: "16", context: leap, file: leap/Containerfile-16.0}
- {os: leap, version: "16.0", context: leap, file: leap/Containerfile-16.0}
- {os: tumbleweed, version: "latest", context: tumbleweed, file: tumbleweed/Containerfile}
- {os: debian, version: "12", context: debian, file: debian/Containerfile-12}
- {os: debian, version: "13", context: debian, file: debian/Containerfile-13}
- {os: openeuler, version: "24.03", context: openeuler-24.03, file: openeuler-24.03/Containerfile}
- {os: ubuntu, version: "24.04", context: ubuntu, file: ubuntu/Containerfile-24.04}
- {os: ubuntu, version: "26.04", context: ubuntu, file: ubuntu/Containerfile-26.04}

permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
# Required for keyless signing with sigstore/fulcio when not in a PR.
id-token: write


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

- name: Make Containerfiles
# Some OS directories generate versioned Containerfiles from templates.
- name: Generate versioned Containerfiles
run: |
make -C rockylinux-8
make -C rockylinux-9
make -C rockylinux-10
make -C almalinux-8
make -C almalinux-9
make -C almalinux-10
if [ -f "${{ matrix.image.context }}/Makefile" ]; then
make -C "${{ matrix.image.context }}"
fi

# Install the cosign tool
# https://github.com/sigstore/cosign-installer
- name: Install Cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@v3.5.0

# Workaround: https://github.com/docker/build-push-action/issues/461
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v4

Expand All @@ -179,31 +90,96 @@ jobs:
id: meta
uses: docker/metadata-action@v6
with:
images: |
ghcr.io/${{ github.repository_owner }}/warewulf-${{ matrix.os }}
tags: |
type=schedule
type=raw,${{ matrix.version }}
images: ghcr.io/${{ github.repository_owner }}/warewulf-${{ matrix.image.os }}

# Build and push Docker image with Buildx
# Build single-platform image and push by content-addressed digest.
# No tag is written here; the merge job assembles the manifest index.
# https://github.com/docker/build-push-action
- name: Build and push image
id: build-and-push
- name: Build and push image by digest
id: build
uses: docker/build-push-action@v7
with:
context: ${{ matrix.context }}
file: ${{ matrix.file }}
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
context: ${{ matrix.image.context }}
file: ${{ matrix.image.file }}
platforms: ${{ matrix.arch.platform }}
outputs: type=image,name=ghcr.io/${{ github.repository_owner }}/warewulf-${{ matrix.image.os }},oci-mediatypes=true,push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
cache-from: type=gha,scope=${{ matrix.image.os }}-${{ matrix.image.version }}-${{ matrix.arch.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.image.os }}-${{ matrix.image.version }}-${{ matrix.arch.platform }}

# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
- name: Sign the images with GitHub OIDC Token
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
echo "${{ matrix.image.os }}:${{ matrix.image.version }}" > "/tmp/digests/${digest#sha256:}"

- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ matrix.image.os }}-${{ matrix.image.version }}-${{ matrix.arch.platform_pair }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1


# Combine per-arch digests into a multi-arch manifest index, then sign.
# On pull requests, logs the imagetools commands that would run without executing them.
merge:
runs-on: ubuntu-latest
needs: build

permissions:
contents: read
packages: write
id-token: write

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

- name: Setup Docker buildx
uses: docker/setup-buildx-action@v4

- name: Log into registry ghcr.io
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Install the cosign tool
# https://github.com/sigstore/cosign-installer
- name: Install Cosign
if: github.event_name != 'pull_request'
env:
DIGEST: ${{ steps.build-and-push.outputs.digest }}
TAGS: ${{ steps.meta.outputs.tags }}
run: cosign sign --yes "${TAGS}@${DIGEST}"
uses: sigstore/cosign-installer@v3.5.0

# Each digest file is named by its hash; its content is "{os}:{version}".
# Group digests by image, create one manifest index per image, then sign.
# On PRs, log the imagetools commands instead of running them.
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
- name: Create manifest lists and sign
run: |
declare -A image_digests
for f in /tmp/digests/*; do
hash=$(basename "$f")
read -r os_version < "$f"
os="${os_version%%:*}"; version="${os_version#*:}"
repo="ghcr.io/${{ github.repository_owner }}/warewulf-${os}"
image_digests["${os}:${version}"]+=" ${repo}@sha256:${hash}"
done

for key in "${!image_digests[@]}"; do
os="${key%%:*}"; version="${key#*:}"
image="ghcr.io/${{ github.repository_owner }}/warewulf-${os}:${version}"
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "[dry-run] docker buildx imagetools create -t ${image} ${image_digests[$key]}"
else
docker buildx imagetools create -t "${image}" ${image_digests["$key"]}
digest=$(docker buildx imagetools inspect "${image}" --format '{{.Manifest.Digest}}')
cosign sign --yes "${image}@${digest}"
fi
done
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ These containers are published on the [GitHub container registry][1].
* [AlmaLinux 10](almalinux-10)
* [openEuler 24.03](openeuler-24.03)
* [openSUSE Leap](leap)
* [openSUSE Tumbleweed](tumbleweed)
* [Debian](debian)
* [Ubuntu](ubuntu)

## Additional examples

Expand Down
6 changes: 3 additions & 3 deletions almalinux-10/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: all
all: Containerfile-10.0
all: Containerfile-10.1
all: Containerfile-10.2

.PHONY: clean
clean:
Expand All @@ -9,5 +9,5 @@ clean:
Containerfile-10.%: Containerfile-vault
env release=10.$* envsubst '$$release' <Containerfile-vault >$@

Containerfile-10.1: Containerfile-fixed
env release=10.1 envsubst '$$release' <Containerfile-fixed >$@
Containerfile-10.2: Containerfile-fixed
env release=10.2 envsubst '$$release' <Containerfile-fixed >$@
6 changes: 3 additions & 3 deletions almalinux-9/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: all
all: Containerfile-9.6
all: Containerfile-9.7
all: Containerfile-9.8

.PHONY: clean
clean:
Expand All @@ -9,5 +9,5 @@ clean:
Containerfile-9.%: Containerfile-vault
env release=9.$* envsubst '$$release' <Containerfile-vault >$@

Containerfile-9.7: Containerfile-fixed
env release=9.7 envsubst '$$release' <Containerfile-fixed >$@
Containerfile-9.8: Containerfile-fixed
env release=9.8 envsubst '$$release' <Containerfile-fixed >$@
6 changes: 3 additions & 3 deletions rockylinux-10/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: all
all: Containerfile-10.0
all: Containerfile-10.1
all: Containerfile-10.2

.PHONY: clean
clean:
Expand All @@ -9,5 +9,5 @@ clean:
Containerfile-10.%: Containerfile-vault
env release=10.$* envsubst '$$release' <Containerfile-vault >$@

Containerfile-10.1: Containerfile-fixed
env release=10.1 envsubst '$$release' <Containerfile-fixed >$@
Containerfile-10.2: Containerfile-fixed
env release=10.2 envsubst '$$release' <Containerfile-fixed >$@
6 changes: 3 additions & 3 deletions rockylinux-9/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: all
all: Containerfile-9.6
all: Containerfile-9.7
all: Containerfile-9.8

.PHONY: clean
clean:
Expand All @@ -9,5 +9,5 @@ clean:
Containerfile-9.%: Containerfile-vault
env release=9.$* envsubst '$$release' <Containerfile-vault >$@

Containerfile-9.7: Containerfile-fixed
env release=9.7 envsubst '$$release' <Containerfile-fixed >$@
Containerfile-9.8: Containerfile-fixed
env release=9.8 envsubst '$$release' <Containerfile-fixed >$@
Loading