Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 51 additions & 103 deletions .github/workflows/build-lkl.yml
Original file line number Diff line number Diff line change
@@ -1,34 +1,39 @@
# Build prebuilt liblkl.a and publish to lkl-nightly release.
#
# Schedule: nightly at 03:00 UTC. Skips build if upstream LKL HEAD
# has not changed since the last successful publish.
# Schedule: nightly at 00:30 UTC (08:30 TST) so results land by start
# of Taiwan workday during GitHub Actions off-peak (US evening).
# Skips build if upstream LKL HEAD has not changed since the last
# successful publish.
#
# The lkl-nightly release on sysprog21/kbox always contains exactly
# one x86_64 and one aarch64 tarball (the latest build).
name: Build LKL (nightly)

on:
schedule:
- cron: '0 3 * * *'
- cron: '30 0 * * *'
workflow_dispatch:
inputs:
force:
description: 'Force rebuild even if upstream is unchanged'
type: boolean
default: false

permissions:
contents: write
concurrency:
group: lkl-nightly
cancel-in-progress: false

env:
LKL_UPSTREAM: lkl/linux
KBOX_REPO: sysprog21/kbox
KBOX_REPO: ${{ github.repository }}
NIGHTLY_TAG: lkl-nightly

jobs:
# ---- Check whether upstream LKL has new commits ----
check-upstream:
runs-on: ubuntu-24.04
permissions:
contents: read
outputs:
lkl_commit: ${{ steps.head.outputs.commit }}
needs_build: ${{ steps.compare.outputs.needs_build }}
Expand All @@ -37,6 +42,10 @@ jobs:
id: head
run: |
COMMIT=$(git ls-remote "https://github.com/${{ env.LKL_UPSTREAM }}.git" HEAD | awk '{print $1}')
if [ -z "$COMMIT" ]; then
echo "::error::Failed to resolve upstream LKL HEAD"
exit 1
fi
echo "commit=${COMMIT}" >> "$GITHUB_OUTPUT"
echo "Upstream LKL HEAD: ${COMMIT}"

Expand All @@ -45,8 +54,7 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}
run: |
FORCE="${{ inputs.force || 'false' }}"
if [ "$FORCE" = "true" ]; then
if [ "${{ inputs.force }}" = "true" ]; then
echo "needs_build=true" >> "$GITHUB_OUTPUT"
echo "Forced rebuild requested."
exit 0
Expand All @@ -68,20 +76,33 @@ jobs:
fi

# ---- Build x86_64 and aarch64 in parallel ----
build-x86_64:
build:
needs: check-upstream
if: needs.check-upstream.outputs.needs_build == 'true'
runs-on: ubuntu-24.04
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- arch: x86_64
runner: ubuntu-24.04
- arch: aarch64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
timeout-minutes: 30
steps:
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential flex bison bc libelf-dev

- name: Clone LKL at pinned commit
- name: Shallow-fetch LKL at pinned commit
run: |
git clone --no-checkout "https://github.com/${{ env.LKL_UPSTREAM }}.git" lkl
cd lkl && git checkout ${{ needs.check-upstream.outputs.lkl_commit }}
git init lkl && cd lkl
git remote add origin "https://github.com/${{ env.LKL_UPSTREAM }}.git"
git fetch --depth=1 origin ${{ needs.check-upstream.outputs.lkl_commit }}
git checkout FETCH_HEAD

- name: Configure LKL
working-directory: lkl
Expand All @@ -107,86 +128,13 @@ jobs:
./scripts/config --disable CONFIG_CIFS
make ARCH=lkl olddefconfig

- name: Build LKL
- name: Build LKL kernel
working-directory: lkl
run: make ARCH=lkl -j$(nproc)

- name: Verify symbols
working-directory: lkl
run: |
test -f tools/lkl/liblkl.a || { echo "liblkl.a not found"; exit 1; }
for sym in lkl_init lkl_start_kernel lkl_cleanup lkl_syscall \
lkl_strerror lkl_disk_add lkl_mount_dev \
lkl_host_ops lkl_dev_blk_ops; do
if ! nm tools/lkl/liblkl.a 2>/dev/null | awk -v s="$sym" \
'$3 == s && $2 ~ /^[TtDdBbRr]$/ {found=1} END {exit !found}'; then
echo "MISSING symbol: ${sym}"; exit 1
fi
done

- name: Package
working-directory: lkl
run: |
mkdir -p pkg
cp tools/lkl/liblkl.a pkg/
cp tools/lkl/include/lkl.h pkg/ 2>/dev/null || true
cp tools/lkl/include/lkl/autoconf.h pkg/ 2>/dev/null || true
cp scripts/gdb/vmlinux-gdb.py pkg/ 2>/dev/null || true
echo "commit=$(git rev-parse HEAD)" > pkg/BUILD_INFO
echo "date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> pkg/BUILD_INFO
echo "arch=x86_64" >> pkg/BUILD_INFO
cd pkg && sha256sum ./* > sha256sums.txt
cd .. && tar czf liblkl-x86_64.tar.gz -C pkg .

- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: lkl-x86_64
path: lkl/liblkl-x86_64.tar.gz
retention-days: 3

build-aarch64:
needs: check-upstream
if: needs.check-upstream.outputs.needs_build == 'true'
runs-on: ubuntu-24.04-arm
steps:
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential flex bison bc libelf-dev

- name: Clone LKL at pinned commit
run: |
git clone --no-checkout "https://github.com/${{ env.LKL_UPSTREAM }}.git" lkl
cd lkl && git checkout ${{ needs.check-upstream.outputs.lkl_commit }}

- name: Configure LKL
- name: Build liblkl.a
working-directory: lkl
run: |
make ARCH=lkl defconfig
./scripts/config --enable CONFIG_DEVTMPFS
./scripts/config --enable CONFIG_DEVTMPFS_MOUNT
./scripts/config --enable CONFIG_DEVPTS_FS
./scripts/config --enable CONFIG_DEBUG_INFO
./scripts/config --set-val CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT y
./scripts/config --enable CONFIG_GDB_SCRIPTS
./scripts/config --enable CONFIG_SCHED_DEBUG
./scripts/config --enable CONFIG_PROC_SYSCTL
./scripts/config --enable CONFIG_PRINTK
./scripts/config --enable CONFIG_TRACEPOINTS
./scripts/config --enable CONFIG_FTRACE
./scripts/config --enable CONFIG_DEBUG_FS
./scripts/config --disable CONFIG_MODULES
./scripts/config --disable CONFIG_SOUND
./scripts/config --disable CONFIG_USB_SUPPORT
./scripts/config --disable CONFIG_INPUT
./scripts/config --disable CONFIG_NFS_FS
./scripts/config --disable CONFIG_CIFS
make ARCH=lkl olddefconfig

- name: Build LKL
working-directory: lkl
run: make ARCH=lkl -j$(nproc)
run: make -C tools/lkl -j$(nproc)

- name: Verify symbols
working-directory: lkl
Expand All @@ -211,38 +159,32 @@ jobs:
cp scripts/gdb/vmlinux-gdb.py pkg/ 2>/dev/null || true
echo "commit=$(git rev-parse HEAD)" > pkg/BUILD_INFO
echo "date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> pkg/BUILD_INFO
echo "arch=aarch64" >> pkg/BUILD_INFO
echo "arch=${{ matrix.arch }}" >> pkg/BUILD_INFO
cd pkg && sha256sum ./* > sha256sums.txt
cd .. && tar czf liblkl-aarch64.tar.gz -C pkg .
cd .. && tar czf liblkl-${{ matrix.arch }}.tar.gz -C pkg .

- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: lkl-aarch64
path: lkl/liblkl-aarch64.tar.gz
name: lkl-${{ matrix.arch }}
path: lkl/liblkl-${{ matrix.arch }}.tar.gz
retention-days: 3

# ---- Publish: replace lkl-nightly release with latest artifacts ----
publish-nightly:
needs: [check-upstream, build-x86_64, build-aarch64]
needs: [check-upstream, build]
if: needs.check-upstream.outputs.needs_build == 'true'
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- name: Download artifacts
uses: actions/download-artifact@v8
with:
path: dist/
merge-multiple: true

- name: Delete old nightly release (if exists)
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release delete "${{ env.NIGHTLY_TAG }}" \
--repo "${{ env.KBOX_REPO }}" \
--yes --cleanup-tag 2>/dev/null || true

- name: Create nightly release
- name: Publish nightly release
env:
GH_TOKEN: ${{ github.token }}
run: |
Expand All @@ -261,6 +203,12 @@ jobs:
BUILD_INFO, sha256sums.txt
EOF

# Delete-then-create is atomic enough: both build jobs succeeded,
# and the concurrency group prevents overlapping runs.
gh release delete "${{ env.NIGHTLY_TAG }}" \
--repo "${{ env.KBOX_REPO }}" \
--yes --cleanup-tag 2>/dev/null || true

gh release create "${{ env.NIGHTLY_TAG }}" \
--repo "${{ env.KBOX_REPO }}" \
--title "LKL nightly (${BUILD_DATE})" \
Expand Down
Loading