Skip to content

Commit 67d3539

Browse files
committed
ci: add build kernel workflow
Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
1 parent 6c8e642 commit 67d3539

File tree

5 files changed

+3725
-6
lines changed

5 files changed

+3725
-6
lines changed

.github/.tool-versions

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
go 1.25.5
1+
go 1.25.5
2+
kernel 6.12.46
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
name: "Build Kernel"
2+
description: "Reusable workflow to build Linux kernels"
3+
inputs:
4+
kernel_version:
5+
description: 'Kernel version to build'
6+
required: true
7+
default: '6.12.46'
8+
kernel_arch:
9+
description: 'Kernel architecture to build'
10+
required: true
11+
default: 'x86_64'
12+
kernel_nproc:
13+
description: 'Number of parallel build processes'
14+
required: false
15+
# Public runners provide 4 cores; default to that to avoid overloading
16+
# https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for-public-repositories
17+
default: '4'
18+
19+
runs:
20+
using: composite
21+
steps:
22+
- name: Checkout code
23+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
24+
25+
- name: Set up Docker Buildx
26+
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
27+
28+
- name: Calculate kernel cache key
29+
id: cache-key
30+
shell: bash
31+
run: |
32+
# Hash the kernel config and patches to create a unique cache key
33+
CONFIG_FILE="kernel/config-${{ inputs.kernel_version }}-${{ inputs.kernel_arch }}"
34+
35+
if [ ! -f "$CONFIG_FILE" ]; then
36+
echo "Error: Kernel config file $CONFIG_FILE not found"
37+
exit 1
38+
fi
39+
40+
# Calculate hash of config file and all patches
41+
CONFIG_HASH=$(sha256sum "$CONFIG_FILE" | cut -d' ' -f1)
42+
PATCHES_HASH=$(find kernel/patches -type f -name "*.patch" -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
43+
44+
# Combine version, arch, config hash, and patches hash
45+
CACHE_KEY="kernel-${{ inputs.kernel_version }}-${{ inputs.kernel_arch }}-${CONFIG_HASH:0:8}-${PATCHES_HASH:0:8}"
46+
47+
echo "cache-key=${CACHE_KEY}" >> $GITHUB_OUTPUT
48+
echo "config-hash=${CONFIG_HASH:0:8}" >> $GITHUB_OUTPUT
49+
echo "patches-hash=${PATCHES_HASH:0:8}" >> $GITHUB_OUTPUT
50+
51+
echo "Kernel cache key: ${CACHE_KEY}"
52+
echo "Config hash: ${CONFIG_HASH:0:8}"
53+
echo "Patches hash: ${PATCHES_HASH:0:8}"
54+
55+
- name: Check cache for existing kernel
56+
id: cache-kernel
57+
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
58+
with:
59+
path: _output/nerdbox-kernel-${{ inputs.kernel_arch }}
60+
key: ${{ steps.cache-key.outputs.cache-key }}
61+
lookup-only: true
62+
63+
- name: Build kernel
64+
if: steps.cache-kernel.outputs.cache-hit != 'true'
65+
shell: bash
66+
run: |
67+
docker buildx bake kernel \
68+
--set kernel.args.KERNEL_VERSION=${{ inputs.kernel_version }} \
69+
--set kernel.args.KERNEL_ARCH=${{ inputs.kernel_arch }} \
70+
--set kernel.args.KERNEL_NPROC=${{ inputs.kernel_nproc }}
71+
72+
- name: Verify kernel artifact
73+
if: steps.cache-kernel.outputs.cache-hit != 'true'
74+
shell: bash
75+
run: |
76+
kernel_file="_output/nerdbox-kernel-${{ inputs.kernel_arch }}"
77+
if [ ! -f "$kernel_file" ]; then
78+
echo "Error: Kernel file $kernel_file not found after build"
79+
exit 1
80+
fi
81+
82+
echo "Kernel built successfully:"
83+
ls -lh "$kernel_file"
84+
file "$kernel_file"
85+
86+
- name: Save kernel to cache
87+
if: steps.cache-kernel.outputs.cache-hit != 'true'
88+
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
89+
with:
90+
path: _output/nerdbox-kernel-${{ inputs.kernel_arch }}
91+
key: ${{ steps.cache-key.outputs.cache-key }}
92+
93+
- name: Upload kernel artifact
94+
if: steps.cache-kernel.outputs.cache-hit != 'true'
95+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
96+
with:
97+
name: nerdbox-kernel-${{ inputs.kernel_version }}-${{ inputs.kernel_arch }}
98+
path: _output/nerdbox-kernel-${{ inputs.kernel_arch }}
99+
retention-days: 90
100+
if-no-files-found: error
101+
102+
- name: Cache summary
103+
shell: bash
104+
run: |
105+
echo "## Kernel Build Summary" >> $GITHUB_STEP_SUMMARY
106+
echo "" >> $GITHUB_STEP_SUMMARY
107+
echo "- **Version**: ${{ inputs.kernel_version }}" >> $GITHUB_STEP_SUMMARY
108+
echo "- **Architecture**: ${{ inputs.kernel_arch }}" >> $GITHUB_STEP_SUMMARY
109+
echo "- **Cache Key**: \`${{ steps.cache-key.outputs.cache-key }}\`" >> $GITHUB_STEP_SUMMARY
110+
echo "- **Config Hash**: ${{ steps.cache-key.outputs.config-hash }}" >> $GITHUB_STEP_SUMMARY
111+
echo "- **Patches Hash**: ${{ steps.cache-key.outputs.patches-hash }}" >> $GITHUB_STEP_SUMMARY
112+
echo "- **Cache Hit**: ${{ steps.cache-kernel.outputs.cache-hit == 'true' && '✅ Yes (reused existing)' || '❌ No (built from scratch)' }}" >> $GITHUB_STEP_SUMMARY
113+
echo "" >> $GITHUB_STEP_SUMMARY
114+
if [ -f "_output/nerdbox-kernel-${{ inputs.kernel_arch }}" ]; then
115+
echo "### Kernel Details" >> $GITHUB_STEP_SUMMARY
116+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
117+
ls -lh "_output/nerdbox-kernel-${{ inputs.kernel_arch }}" >> $GITHUB_STEP_SUMMARY
118+
file "_output/nerdbox-kernel-${{ inputs.kernel_arch }}" >> $GITHUB_STEP_SUMMARY
119+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
120+
fi

.github/workflows/build-kernel.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Build Kernel
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
kernel_version:
7+
description: 'Kernel version to build'
8+
required: true
9+
default: '6.12.46'
10+
kernel_nproc:
11+
description: 'Number of parallel build processes'
12+
required: false
13+
# Public runners provide 4 cores; default to that to avoid overloading
14+
# https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for-public-repositories
15+
default: '4'
16+
17+
permissions:
18+
contents: read
19+
20+
jobs:
21+
build-kernel:
22+
name: Build Kernel ${{ inputs.kernel_version }}-${{ matrix.kernel_arch }}
23+
runs-on: ${{ matrix.os }}
24+
timeout-minutes: 60
25+
26+
strategy:
27+
fail-fast: false
28+
matrix:
29+
include:
30+
- os: ubuntu-latest
31+
kernel_arch: x86_64
32+
- os: ubuntu-24.04-arm
33+
kernel_arch: arm64
34+
35+
steps:
36+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
37+
38+
- uses: ./.github/actions/build-kernel
39+
with:
40+
kernel_version: ${{ inputs.kernel_version }}
41+
kernel_arch: ${{ matrix.kernel_arch }}
42+
kernel_nproc: ${{ inputs.kernel_nproc }}

.github/workflows/ci.yml

Lines changed: 113 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,23 @@ permissions: # added using https://github.com/step-security/secure-workflows
1010
contents: read
1111

1212
jobs:
13+
setup:
14+
name: Setup
15+
runs-on: ubuntu-latest
16+
outputs:
17+
kernel-version: ${{ steps.set-vars.outputs.kernel-version }}
18+
steps:
19+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
20+
with:
21+
sparse-checkout: |
22+
.github/.tool-versions
23+
24+
- name: Set variables
25+
id: set-vars
26+
run: |
27+
kernel_version=$(grep -E '^kernel [0-9.]+$' .github/.tool-versions | sed -E 's/^kernel ([0-9.]+)$/\1/')
28+
echo "kernel-version=${kernel_version}" >> $GITHUB_OUTPUT
29+
1330
linters:
1431
permissions:
1532
contents: read # for actions/checkout to fetch code
@@ -97,11 +114,40 @@ jobs:
97114
- run: make proto-fmt
98115
- run: make check-protos check-api-descriptors
99116

117+
#
118+
# Build kernels on cache miss
119+
#
120+
build-kernels:
121+
name: Build Kernels (if needed)
122+
runs-on: ${{ matrix.os }}
123+
needs: setup
124+
125+
strategy:
126+
fail-fast: false
127+
matrix:
128+
include:
129+
- os: ubuntu-latest
130+
arch: x86_64
131+
- os: ubuntu-24.04-arm
132+
arch: arm64
133+
134+
steps:
135+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
136+
- uses: ./.github/actions/build-kernel
137+
with:
138+
kernel_version: ${{ needs.setup.outputs.kernel-version }}
139+
kernel_arch: ${{ matrix.arch }}
140+
100141
#
101142
# Integration tests
102143
#
103144
integration:
104-
name: Integration Tests
145+
name: Integration Tests (${{ matrix.os }})
146+
needs: [setup, build-kernels]
147+
# Always run after kernel builds complete (whether they were cached or not)
148+
if: |
149+
always() &&
150+
(needs.build-kernels.result == 'success' || needs.build-kernels.result == 'skipped')
105151
runs-on: ${{ matrix.os }}
106152
timeout-minutes: 20
107153

@@ -110,17 +156,79 @@ jobs:
110156
matrix:
111157
os: [ubuntu-latest, ubuntu-24.04-arm]
112158

159+
env:
160+
KERNEL_ARCH: ""
161+
113162
steps:
114163
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
115164

116-
- uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
165+
- name: Set env
166+
run: |
167+
echo "KERNEL_ARCH=$(uname -m)" >> $GITHUB_ENV
168+
169+
- name: Calculate kernel cache key
170+
id: cache-key
171+
run: |
172+
# Hash the kernel config and patches to create a unique cache key
173+
CONFIG_FILE="kernel/config-${{ needs.setup.outputs.kernel-version }}-${KERNEL_ARCH}"
174+
175+
if [ ! -f "$CONFIG_FILE" ]; then
176+
echo "Error: Kernel config file $CONFIG_FILE not found"
177+
exit 1
178+
fi
179+
180+
# Calculate hash of config file and all patches
181+
CONFIG_HASH=$(sha256sum "$CONFIG_FILE" | cut -d' ' -f1)
182+
PATCHES_HASH=$(find kernel/patches -type f -name "*.patch" -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
183+
184+
# Combine version, arch, config hash, and patches hash
185+
CACHE_KEY="kernel-${{ needs.setup.outputs.kernel-version }}-${KERNEL_ARCH}-${CONFIG_HASH:0:8}-${PATCHES_HASH:0:8}"
186+
187+
echo "cache-key=${CACHE_KEY}" >> $GITHUB_OUTPUT
188+
echo "Kernel cache key: ${CACHE_KEY}"
189+
190+
- name: Restore cached kernel
191+
id: cache-kernel
192+
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
117193
with:
118-
go-version-file: .github/.tool-versions
194+
path: _output/nerdbox-kernel-${{ env.KERNEL_ARCH }}
195+
key: ${{ steps.cache-key.outputs.cache-key }}
196+
197+
- name: Verify kernel from cache
198+
run: |
199+
if [ "${{ steps.cache-kernel.outputs.cache-hit }}" = "true" ]; then
200+
echo "✅ Kernel restored from cache"
201+
else
202+
echo "❌ Kernel not in cache - this should not happen after build-kernels-on-demand"
203+
exit 1
204+
fi
205+
ls -lh _output/nerdbox-kernel-${KERNEL_ARCH}
206+
file _output/nerdbox-kernel-${KERNEL_ARCH}
119207
120208
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
121209

122-
- name: Build project
123-
run: make all
210+
- name: Build remaining artifacts (initrd and shim)
211+
run: |
212+
echo "Building shim, initrd and libkrun..."
213+
docker buildx bake shim initrd libkrun
214+
215+
- name: Verify all artifacts
216+
run: |
217+
echo "Verifying build artifacts:"
218+
ls -lh _output/
219+
echo ""
220+
echo "Kernel:"
221+
file _output/nerdbox-kernel-${KERNEL_ARCH}
222+
echo ""
223+
echo "Initrd:"
224+
file _output/nerdbox-initrd
225+
echo ""
226+
echo "Shim:"
227+
file _output/containerd-shim-nerdbox-v1
228+
229+
- uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
230+
with:
231+
go-version-file: .github/.tool-versions
124232

125233
- name: Run integration tests
126234
run: go test -v ./integration/...

0 commit comments

Comments
 (0)