Skip to content

Commit 605943f

Browse files
committed
ci: add build kernel workflow
Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
1 parent e6a8f6e commit 605943f

File tree

4 files changed

+3716
-5
lines changed

4 files changed

+3716
-5
lines changed
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: 106 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ on:
99
permissions: # added using https://github.com/step-security/secure-workflows
1010
contents: read
1111

12+
env:
13+
KERNEL_VERSION: "6.12.46"
14+
1215
jobs:
1316
linters:
1417
permissions:
@@ -93,23 +96,121 @@ jobs:
9396
- run: make proto-fmt
9497
- run: make check-protos check-api-descriptors
9598

99+
#
100+
# Build kernels on cache miss
101+
#
102+
build-kernel-x86_64:
103+
name: Build Kernel x86_64 (if needed)
104+
runs-on: ubuntu-latest
105+
steps:
106+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
107+
- uses: ./.github/actions/build-kernel
108+
with:
109+
kernel_version: ${{ env.KERNEL_VERSION }}
110+
kernel_arch: "x86_64"
111+
112+
build-kernel-arm64:
113+
name: Build Kernel arm64 (if needed)
114+
runs-on: ubuntu-24.04-arm
115+
steps:
116+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
117+
- uses: ./.github/actions/build-kernel
118+
with:
119+
kernel_version: ${{ env.KERNEL_VERSION }}
120+
kernel_arch: "arm64"
121+
96122
#
97123
# Integration tests
98124
#
99125
integration:
100-
name: Integration Tests
101-
runs-on: ubuntu-latest
126+
name: Integration Tests (${{ matrix.os }})
127+
needs: [build-kernel-x86_64, build-kernel-arm64]
128+
# Always run after kernel builds complete (whether they were cached or not)
129+
if: |
130+
always() &&
131+
(needs.build-kernel-x86_64.result == 'success' || needs.build-kernel-x86_64.result == 'skipped') &&
132+
(needs.build-kernel-arm64.result == 'success' || needs.build-kernel-arm64.result == 'skipped')
133+
runs-on: ${{ matrix.os }}
102134
timeout-minutes: 20
103135

136+
strategy:
137+
fail-fast: false
138+
matrix:
139+
os: [ubuntu-latest, macos-latest]
140+
141+
env:
142+
KERNEL_ARCH: ""
143+
104144
steps:
105145
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
106146

107-
- uses: ./.github/actions/install-go
147+
- name: Set architecture variable
148+
id: arch
149+
run: |
150+
echo "KERNEL_ARCH=$(uname -m)" >> $GITHUB_ENV
151+
echo "Testing with architecture: ${{ env.KERNEL_ARCH }}"
152+
153+
- name: Calculate kernel cache key
154+
id: cache-key
155+
run: |
156+
# Hash the kernel config and patches to create a unique cache key
157+
CONFIG_FILE="kernel/config-${KERNEL_VERSION}-${KERNEL_ARCH}"
158+
159+
if [ ! -f "$CONFIG_FILE" ]; then
160+
echo "Error: Kernel config file $CONFIG_FILE not found"
161+
exit 1
162+
fi
163+
164+
# Calculate hash of config file and all patches
165+
CONFIG_HASH=$(sha256sum "$CONFIG_FILE" | cut -d' ' -f1)
166+
PATCHES_HASH=$(find kernel/patches -type f -name "*.patch" -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
167+
168+
# Combine version, arch, config hash, and patches hash
169+
CACHE_KEY="kernel-${KERNEL_VERSION}-${KERNEL_ARCH}-${CONFIG_HASH:0:8}-${PATCHES_HASH:0:8}"
170+
171+
echo "cache-key=${CACHE_KEY}" >> $GITHUB_OUTPUT
172+
echo "Kernel cache key: ${CACHE_KEY}"
173+
174+
- name: Restore cached kernel
175+
id: cache-kernel
176+
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
177+
with:
178+
path: _output/nerdbox-kernel-${{ env.KERNEL_ARCH }}
179+
key: ${{ steps.cache-key.outputs.cache-key }}
180+
181+
- name: Verify kernel from cache
182+
run: |
183+
if [ "${{ steps.cache-kernel.outputs.cache-hit }}" = "true" ]; then
184+
echo "✅ Kernel restored from cache"
185+
else
186+
echo "❌ Kernel not in cache - this should not happen after build-kernels-on-demand"
187+
exit 1
188+
fi
189+
ls -lh _output/nerdbox-kernel-${KERNEL_ARCH}
190+
file _output/nerdbox-kernel-${KERNEL_ARCH}
108191
109192
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
110193

111-
- name: Build project
112-
run: make all
194+
- name: Build remaining artifacts (initrd and shim)
195+
run: |
196+
echo "Building shim, initrd and libkrun..."
197+
docker buildx bake shim initrd libkrun
198+
199+
- name: Verify all artifacts
200+
run: |
201+
echo "Verifying build artifacts:"
202+
ls -lh _output/
203+
echo ""
204+
echo "Kernel:"
205+
file _output/nerdbox-kernel-${KERNEL_ARCH}
206+
echo ""
207+
echo "Initrd:"
208+
file _output/nerdbox-initrd
209+
echo ""
210+
echo "Shim:"
211+
file _output/containerd-shim-nerdbox-v1
212+
213+
- uses: ./.github/actions/install-go
113214

114215
- name: Run integration tests
115216
run: go test -v ./integration/...

0 commit comments

Comments
 (0)