Skip to content

Commit ea4838d

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

File tree

3 files changed

+264
-4
lines changed

3 files changed

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

.github/workflows/build-kernel.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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+
default: '16'
14+
15+
permissions:
16+
contents: read
17+
18+
jobs:
19+
build-kernel:
20+
name: Build Kernel ${{ inputs.kernel_version }}-${{ matrix.kernel_arch }}
21+
runs-on: ${{ matrix.os }}
22+
timeout-minutes: 60
23+
24+
strategy:
25+
fail-fast: false
26+
matrix:
27+
include:
28+
- os: ubuntu-latest
29+
kernel_arch: x86_64
30+
- os: ubuntu-24.04-arm
31+
kernel_arch: arm64
32+
33+
steps:
34+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
35+
36+
- uses: ./.github/actions/build-kernel
37+
with:
38+
kernel_version: ${{ inputs.kernel_version }}
39+
kernel_arch: ${{ matrix.kernel_arch }}
40+
kernel_nproc: ${{ inputs.kernel_nproc }}

.github/workflows/ci.yml

Lines changed: 106 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,23 +93,125 @@ jobs:
9393
- run: make proto-fmt
9494
- run: make check-protos check-api-descriptors
9595

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

135+
strategy:
136+
fail-fast: false
137+
matrix:
138+
os: [ubuntu-latest, macos-latest]
139+
140+
env:
141+
KERNEL_VERSION: "6.12.46"
142+
104143
steps:
105144
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
106145

107146
- uses: ./.github/actions/install-go
108147

109148
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
110149

111-
- name: Build project
112-
run: make all
150+
- name: Set architecture variable
151+
id: arch
152+
shell: bash
153+
run: |
154+
KERNEL_ARCH=$(uname -m)
155+
echo "kernel_arch=${KERNEL_ARCH}" >> $GITHUB_ENV
156+
echo "Testing with architecture: ${KERNEL_ARCH}"
157+
158+
- name: Calculate kernel cache key
159+
id: cache-key
160+
run: |
161+
# Hash the kernel config and patches to create a unique cache key
162+
CONFIG_FILE="kernel/config-${KERNEL_VERSION}-${KERNEL_ARCH}"
163+
164+
if [ ! -f "$CONFIG_FILE" ]; then
165+
echo "Error: Kernel config file $CONFIG_FILE not found"
166+
exit 1
167+
fi
168+
169+
# Calculate hash of config file and all patches
170+
CONFIG_HASH=$(sha256sum "$CONFIG_FILE" | cut -d' ' -f1)
171+
PATCHES_HASH=$(find kernel/patches -type f -name "*.patch" -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
172+
173+
# Combine version, arch, config hash, and patches hash
174+
CACHE_KEY="kernel-${KERNEL_VERSION}-${KERNEL_ARCH}-${CONFIG_HASH:0:8}-${PATCHES_HASH:0:8}"
175+
176+
echo "cache-key=${CACHE_KEY}" >> $GITHUB_OUTPUT
177+
echo "Kernel cache key: ${CACHE_KEY}"
178+
179+
- name: Restore cached kernel
180+
id: cache-kernel
181+
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
182+
with:
183+
path: _output/nerdbox-kernel-${{ env.KERNEL_ARCH }}
184+
key: ${{ steps.cache-key.outputs.cache-key }}
185+
186+
- name: Verify kernel from cache
187+
run: |
188+
if [ "${{ steps.cache-kernel.outputs.cache-hit }}" = "true" ]; then
189+
echo "✅ Kernel restored from cache"
190+
else
191+
echo "❌ Kernel not in cache - this should not happen after build-kernels-on-demand"
192+
exit 1
193+
fi
194+
ls -lh _output/nerdbox-kernel-${KERNEL_ARCH}
195+
file _output/nerdbox-kernel-${KERNEL_ARCH}
196+
197+
- name: Build remaining artifacts (initrd and shim)
198+
run: |
199+
echo "Building initrd and shim..."
200+
docker buildx bake initrd shim
201+
202+
- name: Verify all artifacts
203+
run: |
204+
echo "Verifying build artifacts:"
205+
ls -lh _output/
206+
echo ""
207+
echo "Kernel:"
208+
file _output/nerdbox-kernel-${KERNEL_ARCH}
209+
echo ""
210+
echo "Initrd:"
211+
file _output/nerdbox-initrd
212+
echo ""
213+
echo "Shim:"
214+
file _output/containerd-shim-nerdbox-v1
113215
114216
- name: Run integration tests
115217
run: go test -v ./integration/...

0 commit comments

Comments
 (0)