Skip to content

Auto-update, Build & Release #421

Auto-update, Build & Release

Auto-update, Build & Release #421

name: Auto-update, Build & Release
on:
schedule:
- cron: '0 6 * * *'
workflow_dispatch:
permissions:
contents: write
packages: write
jobs:
update-build-release:
runs-on: ubuntu-latest
steps:
- name: Checkout main
uses: actions/checkout@v6
with:
fetch-depth: 0
persist-credentials: true
# ─── 1. Latest k3s tag (*-amd64) ────────────────────────────────────
- name: Get latest k3s tag
id: k3s
run: |
# name= filter scopes the scan, then paginate via .next so a high
# version can't be hidden past page 1 (push-order != version-order).
latest=$(
url="https://registry.hub.docker.com/v2/repositories/rancher/k3s/tags?page_size=100&name=amd64"
for _ in $(seq 1 20); do
[ -z "$url" ] && break; [ "$url" = "null" ] && break
resp=$(curl -fsSL --retry 5 --retry-all-errors --retry-delay 3 "$url") || break
printf '%s\n' "$resp" | jq -r '.results[].name'
url=$(printf '%s' "$resp" | jq -r '.next')
done | grep -E 'amd64$' | grep -v 'rc' | sort -V | tail -n1
)
[ -n "$latest" ] || { echo "::error::no k3s tag resolved from registry"; exit 1; }
echo "latest=$latest" >> "$GITHUB_OUTPUT"
# ─── 2. Latest NVIDIA device plugin release (baked into the image) ───
- name: Get latest NVIDIA device plugin version
id: nvidia_plugin
run: |
latest=$(curl -fsSL --retry 5 --retry-all-errors --retry-delay 3 \
"https://api.github.com/repos/NVIDIA/k8s-device-plugin/releases/latest" \
| jq -r '.tag_name')
[ -n "$latest" ] && [ "$latest" != "null" ] || { echo "::error::no device-plugin release resolved"; exit 1; }
echo "latest=$latest" >> "$GITHUB_OUTPUT"
# ─── 3. Latest CUDA base — used ONLY for the `k3d-gpu test` pod image, ─
# not the node base (the node runs on Ubuntu now).
- name: Get latest CUDA tag for the test pod image
id: cuda
run: |
latest=$(
url="https://registry.hub.docker.com/v2/repositories/nvidia/cuda/tags?page_size=100&name=base-ubuntu"
for _ in $(seq 1 20); do
[ -z "$url" ] && break; [ "$url" = "null" ] && break
resp=$(curl -fsSL --retry 5 --retry-all-errors --retry-delay 3 "$url") || break
printf '%s\n' "$resp" | jq -r '.results[].name'
url=$(printf '%s' "$resp" | jq -r '.next')
done | grep -E '^[0-9][0-9.]*-base-ubuntu[0-9.]+$' | sort -V | tail -n1
)
[ -n "$latest" ] || { echo "::error::no CUDA test-image tag resolved"; exit 1; }
echo "latest=$latest" >> "$GITHUB_OUTPUT"
- name: Read current pinned versions
id: current
run: |
kt=$(grep '^ARG K3S_TAG' Dockerfile | cut -d= -f2 | tr -d '"')
pp=$(grep -oE 'k8s-device-plugin:v[0-9]+\.[0-9]+\.[0-9]+' share/nvidia-device-plugin.yml | cut -d: -f2)
ti=$(grep -oE 'K3D_GPU_TEST_IMAGE:-nvidia/cuda:[^}]*' scripts/k3d-gpu | sed 's#.*nvidia/cuda:##')
echo "k3s=$kt" >> "$GITHUB_OUTPUT"
echo "plugin=$pp" >> "$GITHUB_OUTPUT"
echo "testcuda=$ti" >> "$GITHUB_OUTPUT"
- name: Determine if update is needed
id: need
run: |
if [ "${{ steps.k3s.outputs.latest }}" != "${{ steps.current.outputs.k3s }}" ] || \
[ "${{ steps.nvidia_plugin.outputs.latest }}" != "${{ steps.current.outputs.plugin }}" ] || \
[ "${{ steps.cuda.outputs.latest }}" != "${{ steps.current.outputs.testcuda }}" ]; then
echo "update=true" >> "$GITHUB_OUTPUT"
else
echo "update=false" >> "$GITHUB_OUTPUT"
fi
- name: Abort if nothing to do
if: steps.need.outputs.update == 'false'
run: exit 0
- name: Bump pinned versions
if: steps.need.outputs.update == 'true'
run: |
sed -i "s|^ARG K3S_TAG=.*|ARG K3S_TAG=\"${{ steps.k3s.outputs.latest }}\"|" Dockerfile
sed -i "s|k8s-device-plugin:v[0-9]*\.[0-9]*\.[0-9]*|k8s-device-plugin:${{ steps.nvidia_plugin.outputs.latest }}|" share/nvidia-device-plugin.yml
sed -i "s|K3D_GPU_TEST_IMAGE:-nvidia/cuda:[^}]*|K3D_GPU_TEST_IMAGE:-nvidia/cuda:${{ steps.cuda.outputs.latest }}|" scripts/k3d-gpu
- name: Update README
if: steps.need.outputs.update == 'true'
run: |
today=$(date -u +'%Y-%m-%d')
entry="| $today | ${{ steps.k3s.outputs.latest }} | ${{ steps.nvidia_plugin.outputs.latest }} |"
awk -v e="$entry" \
-v k3s="${{ steps.k3s.outputs.latest }}" \
-v plugin="${{ steps.nvidia_plugin.outputs.latest }}" '
/^## Release History/ { in_rh = 1 }
in_rh && /^\|----------/ { print; print e; in_rh = 0; next }
/^\| `K3S_TAG`/ { sub(/`v[0-9][^`]*-amd64`/, "`" k3s "`"); print; next }
/k8s-device-plugin\/v[0-9]/ { sub(/v[0-9]+\.[0-9]+\.[0-9]+/, plugin); print; next }
{ print }
' README.md > README.md.new && mv README.md.new README.md
- name: Commit & push version bump
if: steps.need.outputs.update == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Dockerfile README.md share/nvidia-device-plugin.yml scripts/k3d-gpu
git commit -m "chore: bump k3s→${{ steps.k3s.outputs.latest }} & device-plugin→${{ steps.nvidia_plugin.outputs.latest }}"
git push origin HEAD:main
- name: Set up Docker Buildx
if: steps.need.outputs.update == 'true'
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
if: steps.need.outputs.update == 'true'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
if: steps.need.outputs.update == 'true'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Ubuntu 26.04 is the default (:latest); 24.04 is also published. Each
# carries the baked device plugin, so clusters expose GPUs with no apply.
- name: Build & push — Ubuntu 26.04 (default / latest)
if: steps.need.outputs.update == 'true'
uses: docker/build-push-action@v6
with:
context: .
push: true
platforms: linux/amd64
build-args: |
UBUNTU_TAG=26.04
tags: |
cryptoandcoffee/k3d-gpu:latest
cryptoandcoffee/k3d-gpu:ubuntu26.04
cryptoandcoffee/k3d-gpu:${{ steps.k3s.outputs.latest }}-ubuntu26.04
ghcr.io/${{ github.repository_owner }}/k3d-gpu:latest
ghcr.io/${{ github.repository_owner }}/k3d-gpu:ubuntu26.04
ghcr.io/${{ github.repository_owner }}/k3d-gpu:${{ steps.k3s.outputs.latest }}-ubuntu26.04
- name: Build & push — Ubuntu 24.04 (variant)
if: steps.need.outputs.update == 'true'
uses: docker/build-push-action@v6
with:
context: .
push: true
platforms: linux/amd64
build-args: |
UBUNTU_TAG=24.04
tags: |
cryptoandcoffee/k3d-gpu:ubuntu24.04
cryptoandcoffee/k3d-gpu:${{ steps.k3s.outputs.latest }}-ubuntu24.04
ghcr.io/${{ github.repository_owner }}/k3d-gpu:ubuntu24.04
ghcr.io/${{ github.repository_owner }}/k3d-gpu:${{ steps.k3s.outputs.latest }}-ubuntu24.04
- name: Create GitHub Release
if: steps.need.outputs.update == 'true'
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.k3s.outputs.latest }}-ndp${{ steps.nvidia_plugin.outputs.latest }}
name: k3d-gpu ${{ steps.k3s.outputs.latest }} (device-plugin ${{ steps.nvidia_plugin.outputs.latest }})
body: |
## 🚀 k3d-gpu release
Ubuntu node base — **26.04** (default) and **24.04**. k3s
`${{ steps.k3s.outputs.latest }}`, NVIDIA device plugin
`${{ steps.nvidia_plugin.outputs.latest }}` (baked in — GPUs are
exposed on `up` with no `kubectl apply`).
**Docker Hub**
- `cryptoandcoffee/k3d-gpu:latest` (= ubuntu26.04)
- `cryptoandcoffee/k3d-gpu:ubuntu26.04`
- `cryptoandcoffee/k3d-gpu:ubuntu24.04`
**GHCR**
- `ghcr.io/${{ github.repository_owner }}/k3d-gpu:latest`
- `ghcr.io/${{ github.repository_owner }}/k3d-gpu:ubuntu26.04`
- `ghcr.io/${{ github.repository_owner }}/k3d-gpu:ubuntu24.04`