Auto-update, Build & Release #421
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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` |