Skip to content

Fix artifacts OCI image to work with containerd #80

Fix artifacts OCI image to work with containerd

Fix artifacts OCI image to work with containerd #80

Workflow file for this run

name: For each commit and PR
on:
push:
branches:
- "main"
pull_request:
env:
KERNEL_VERSION: "6.12.69"
permissions:
contents: read
packages: write
jobs:
# -------------------------------------------------------------------
# Lint — ruff (lint + format) and pyright (type checking)
# -------------------------------------------------------------------
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install lint tools
run: make lint-install
- name: Lint
run: make lint
# -------------------------------------------------------------------
# Fast cache lookup – decides whether the OCI runner is needed
# There are consistent issues with OCI runners not getting scheduled.
# This is the workaround.
# -------------------------------------------------------------------
check-kernel-cache:
runs-on: ubuntu-latest
outputs:
amd64-cache-hit: ${{ steps.amd64-cache.outputs.cache-hit }}
arm64-cache-hit: ${{ steps.arm64-cache.outputs.cache-hit }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Check amd64 kernel cache
id: amd64-cache
uses: actions/cache/restore@v4
with:
path: |
mkosi.output/extra-tree/amd64/usr/lib/modules
mkosi.output/vmlinuz/amd64
key: kernel-amd64-${{ env.KERNEL_VERSION }}-${{ hashFiles('config/defconfig.*', 'Dockerfile') }}
lookup-only: true
- name: Check arm64 kernel cache
id: arm64-cache
uses: actions/cache/restore@v4
with:
path: |
mkosi.output/extra-tree/arm64/usr/lib/modules
mkosi.output/vmlinuz/arm64
key: kernel-arm64-${{ env.KERNEL_VERSION }}-${{ hashFiles('config/defconfig.*', 'Dockerfile') }}
lookup-only: true
# -------------------------------------------------------------------
# Build kernel (vmlinuz + modules) inside Docker
# -------------------------------------------------------------------
build-kernel:
needs: [lint, check-kernel-cache]
# Forks / cache-hit → cheap default runner; mainline cache-miss → fast oracle runner
runs-on: >
${{ github.repository != 'tinkerbell/captain' && matrix.fork_runner
|| needs.check-kernel-cache.outputs[format('{0}-cache-hit', matrix.arch)] == 'true' && matrix.fork_runner
|| fromJSON(matrix.mainline_runner) }}
strategy:
fail-fast: false
matrix:
arch: [amd64, arm64]
include:
- arch: amd64
fork_runner: ubuntu-latest
mainline_runner: '{"group":"Default","labels":["oracle-vm-16cpu-64gb-x86-64"]}'
- arch: arm64
fork_runner: ubuntu-24.04-arm
mainline_runner: '{"group":"Default","labels":["oracle-vm-16cpu-64gb-arm64"]}'
env:
ARCH: ${{ matrix.arch }}
KERNEL_MODE: docker
MKOSI_MODE: skip
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Load shared config
run: cat .github/config.env >> "$GITHUB_ENV"
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Compute Dockerfile hash
id: dockerfile-hash
run: echo "hash=$(sha256sum Dockerfile | awk '{print $1}')" >> "$GITHUB_OUTPUT"
- name: Pull or build builder image
id: builder
run: |
HASH="${{ steps.dockerfile-hash.outputs.hash }}"
REMOTE="ghcr.io/${{ github.repository }}/${{ env.BUILDER_IMAGE }}"
if docker pull "${REMOTE}:${HASH}-${{ matrix.arch }}"; then
docker tag "${REMOTE}:${HASH}-${{ matrix.arch }}" "${{ env.BUILDER_IMAGE }}:${HASH}"
docker tag "${REMOTE}:${HASH}-${{ matrix.arch }}" "${{ env.BUILDER_IMAGE }}"
echo "built=false" >> "$GITHUB_OUTPUT"
else
docker build -t "${{ env.BUILDER_IMAGE }}:${HASH}" -t "${{ env.BUILDER_IMAGE }}" .
echo "built=true" >> "$GITHUB_OUTPUT"
fi
- name: Push builder image to GHCR
if: github.ref == 'refs/heads/main' && steps.builder.outputs.built == 'true'
run: |
HASH="${{ steps.dockerfile-hash.outputs.hash }}"
REMOTE="ghcr.io/${{ github.repository }}/${{ env.BUILDER_IMAGE }}"
docker tag "${{ env.BUILDER_IMAGE }}:${HASH}" "${REMOTE}:${HASH}-${{ matrix.arch }}"
docker push "${REMOTE}:${HASH}-${{ matrix.arch }}"
- name: Restore kernel cache
id: kernel-cache
uses: actions/cache/restore@v4
with:
path: |
mkosi.output/extra-tree/${{ matrix.arch }}/usr/lib/modules
mkosi.output/vmlinuz/${{ matrix.arch }}
key: kernel-${{ matrix.arch }}-${{ env.KERNEL_VERSION }}-${{ hashFiles('config/defconfig.*', 'Dockerfile') }}
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Build kernel
run: ./build.py kernel
- name: Fix output file ownership
run: sudo chown -R "$(id -u):$(id -g)" mkosi.output/
- name: Save kernel cache
if: github.ref == 'refs/heads/main'
uses: actions/cache/save@v4
with:
path: |
mkosi.output/extra-tree/${{ matrix.arch }}/usr/lib/modules
mkosi.output/vmlinuz/${{ matrix.arch }}
key: kernel-${{ matrix.arch }}-${{ env.KERNEL_VERSION }}-${{ hashFiles('config/defconfig.*', 'Dockerfile') }}
- name: Upload kernel artifacts
uses: actions/upload-artifact@v4
with:
name: kernel-${{ matrix.arch }}
path: |
mkosi.output/extra-tree/${{ matrix.arch }}/usr/lib/modules
mkosi.output/vmlinuz/${{ matrix.arch }}
retention-days: 1
# -------------------------------------------------------------------
# Download tools (containerd, runc, nerdctl, CNI plugins)
# -------------------------------------------------------------------
download-tools:
needs: [lint]
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
strategy:
fail-fast: false
matrix:
arch: [amd64, arm64]
env:
ARCH: ${{ matrix.arch }}
KERNEL_MODE: skip
MKOSI_MODE: skip
TOOLS_MODE: native
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Restore tools cache
id: tools-cache
uses: actions/cache/restore@v4
with:
path: |
mkosi.output/extra-tree/${{ matrix.arch }}/usr/local/bin
mkosi.output/extra-tree/${{ matrix.arch }}/opt/cni
key: tools-${{ matrix.arch }}-${{ hashFiles('captain/tools.py') }}
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Download tools
run: ./build.py tools
- name: Save tools cache
if: github.ref == 'refs/heads/main'
uses: actions/cache/save@v4
with:
path: |
mkosi.output/extra-tree/${{ matrix.arch }}/usr/local/bin
mkosi.output/extra-tree/${{ matrix.arch }}/opt/cni
key: tools-${{ matrix.arch }}-${{ hashFiles('captain/tools.py') }}
- name: Upload tools artifacts
uses: actions/upload-artifact@v4
with:
name: tools-${{ matrix.arch }}
path: |
mkosi.output/extra-tree/${{ matrix.arch }}/usr/local/bin
mkosi.output/extra-tree/${{ matrix.arch }}/opt/cni
retention-days: 1
# -------------------------------------------------------------------
# Build initramfs via mkosi (depends on kernel + tools)
# -------------------------------------------------------------------
build-initramfs:
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
needs: [build-kernel, download-tools]
strategy:
fail-fast: false
matrix:
arch: [amd64, arm64]
env:
ARCH: ${{ matrix.arch }}
KERNEL_MODE: skip
MKOSI_MODE: native
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Download kernel artifacts
uses: actions/download-artifact@v4
with:
name: kernel-${{ matrix.arch }}
path: mkosi.output
- name: Download tools artifacts
uses: actions/download-artifact@v4
with:
name: tools-${{ matrix.arch }}
path: mkosi.output/extra-tree/${{ matrix.arch }}
- name: Refresh apt cache
run: sudo apt-get update
- name: setup-mkosi
uses: systemd/mkosi@v26
- name: Install bubblewrap
run: |
sudo apt-get update
sudo apt-get install -y bubblewrap
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Build initramfs
run: ./build.py initramfs
- name: Upload initramfs artifacts
uses: actions/upload-artifact@v4
with:
name: initramfs-${{ matrix.arch }}
path: out/
retention-days: 1
# -------------------------------------------------------------------
# Build UEFI-bootable ISO (depends on initramfs)
# -------------------------------------------------------------------
build-iso:
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
needs: [build-initramfs]
strategy:
fail-fast: false
matrix:
arch: [amd64, arm64]
env:
ARCH: ${{ matrix.arch }}
KERNEL_MODE: skip
MKOSI_MODE: skip
ISO_MODE: docker
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Load shared config
run: cat .github/config.env >> "$GITHUB_ENV"
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Compute Dockerfile hash
id: dockerfile-hash
run: echo "hash=$(sha256sum Dockerfile | awk '{print $1}')" >> "$GITHUB_OUTPUT"
- name: Pull or build builder image
id: builder
run: |
HASH="${{ steps.dockerfile-hash.outputs.hash }}"
REMOTE="ghcr.io/${{ github.repository }}/${{ env.BUILDER_IMAGE }}"
if docker pull "${REMOTE}:${HASH}-${{ matrix.arch }}"; then
docker tag "${REMOTE}:${HASH}-${{ matrix.arch }}" "${{ env.BUILDER_IMAGE }}:${HASH}"
docker tag "${REMOTE}:${HASH}-${{ matrix.arch }}" "${{ env.BUILDER_IMAGE }}"
echo "built=false" >> "$GITHUB_OUTPUT"
else
docker build -t "${{ env.BUILDER_IMAGE }}:${HASH}" -t "${{ env.BUILDER_IMAGE }}" .
echo "built=true" >> "$GITHUB_OUTPUT"
fi
- name: Push builder image to GHCR
if: github.ref == 'refs/heads/main' && steps.builder.outputs.built == 'true'
run: |
HASH="${{ steps.dockerfile-hash.outputs.hash }}"
REMOTE="ghcr.io/${{ github.repository }}/${{ env.BUILDER_IMAGE }}"
docker tag "${{ env.BUILDER_IMAGE }}:${HASH}" "${REMOTE}:${HASH}-${{ matrix.arch }}"
docker push "${REMOTE}:${HASH}-${{ matrix.arch }}"
- name: Download kernel artifacts
uses: actions/download-artifact@v4
with:
name: kernel-${{ matrix.arch }}
path: mkosi.output
- name: Download initramfs artifacts
uses: actions/download-artifact@v4
with:
name: initramfs-${{ matrix.arch }}
path: out
- name: Stage initramfs for ISO build
run: |
mkdir -p mkosi.output/initramfs/${{ matrix.arch }}
cp out/initramfs-${{ matrix.arch }}.cpio.zst mkosi.output/initramfs/${{ matrix.arch }}/image.cpio.zst
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Build ISO
run: ./build.py iso
- name: Upload ISO artifact
uses: actions/upload-artifact@v4
with:
name: iso-${{ matrix.arch }}
path: out/captainos-${{ matrix.arch }}.iso
retention-days: 1
# -------------------------------------------------------------------
# Publish artifacts and compute checksums
# -------------------------------------------------------------------
publish-artifacts:
if: github.ref == 'refs/heads/main'
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
needs: [build-iso]
strategy:
fail-fast: false
matrix:
arch: [amd64, arm64]
env:
ARCH: ${{ matrix.arch }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Load shared config
run: cat .github/config.env >> "$GITHUB_ENV"
- name: Download kernel artifacts
uses: actions/download-artifact@v4
with:
name: kernel-${{ matrix.arch }}
path: mkosi.output
- name: Download initramfs artifacts
uses: actions/download-artifact@v4
with:
name: initramfs-${{ matrix.arch }}
path: out
- name: Download ISO artifact
uses: actions/download-artifact@v4
with:
name: iso-${{ matrix.arch }}
path: out
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Install crane
uses: imjasonh/setup-crane@v0.4
- name: Publish artifacts to GHCR
run: ./build.py release publish
# -------------------------------------------------------------------
# Create multi-arch OCI index from per-arch artifact manifests
# -------------------------------------------------------------------
create-artifact-index:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
needs: [publish-artifacts]
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Load shared config
run: cat .github/config.env >> "$GITHUB_ENV"
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Install crane
uses: imjasonh/setup-crane@v0.4
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Create multi-arch artifact index
run: ./build.py release index