Skip to content

Build LKL (nightly) #16

Build LKL (nightly)

Build LKL (nightly) #16

Workflow file for this run

# Build prebuilt liblkl.a and publish to lkl-nightly release.
#
# 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: '30 0 * * *'
workflow_dispatch:
inputs:
force:
description: 'Force rebuild even if upstream is unchanged'
type: boolean
default: false
concurrency:
group: lkl-nightly
cancel-in-progress: false
env:
LKL_UPSTREAM: lkl/linux
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 }}
steps:
- name: Get upstream LKL HEAD
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}"
- name: Compare with last published build
id: compare
env:
GH_TOKEN: ${{ github.token }}
run: |
if [ "${{ inputs.force }}" = "true" ]; then
echo "needs_build=true" >> "$GITHUB_OUTPUT"
echo "Forced rebuild requested."
exit 0
fi
# Fetch BUILD_INFO from existing nightly release.
LAST_COMMIT=$(gh release view "${{ env.NIGHTLY_TAG }}" \
--repo "${{ env.KBOX_REPO }}" \
--json body --jq '.body' 2>/dev/null \
| grep -oP 'commit=\K[0-9a-f]+' | head -1) || LAST_COMMIT=""
CURRENT="${{ steps.head.outputs.commit }}"
if [ "$LAST_COMMIT" = "$CURRENT" ]; then
echo "needs_build=false" >> "$GITHUB_OUTPUT"
echo "Upstream unchanged (${CURRENT}). Skipping build."
else
echo "needs_build=true" >> "$GITHUB_OUTPUT"
echo "New upstream commit: ${CURRENT} (was: ${LAST_COMMIT:-none})"
fi
# ---- Build x86_64 and aarch64 in parallel ----
build:
needs: check-upstream
if: needs.check-upstream.outputs.needs_build == 'true'
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: Checkout
uses: actions/checkout@v6
- name: Cache apt packages
uses: actions/cache@v5
with:
path: ~/apt-cache
key: apt-lkl-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('.github/workflows/build-lkl.yml') }}
- name: Install build dependencies
run: |
mkdir -p ~/apt-cache
sudo apt-get update
sudo apt-get install -y -o Dir::Cache::Archives=$HOME/apt-cache \
build-essential flex bison bc libelf-dev
- name: Build LKL from source
env:
LKL_REF: ${{ needs.check-upstream.outputs.lkl_commit }}
run: make build-lkl
- name: Package
run: |
tar czf liblkl-${{ matrix.arch }}.tar.gz lkl-${{ matrix.arch }}/
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: lkl-${{ matrix.arch }}
path: liblkl-${{ matrix.arch }}.tar.gz
retention-days: 3
# ---- Publish: replace lkl-nightly release with latest artifacts ----
publish-nightly:
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: Publish nightly release
env:
GH_TOKEN: ${{ github.token }}
run: |
LKL_COMMIT="${{ needs.check-upstream.outputs.lkl_commit }}"
BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
cat > /tmp/release-notes.md <<EOF
Nightly prebuilt liblkl.a for kbox.
commit=${LKL_COMMIT}
date=${BUILD_DATE}
upstream=https://github.com/${{ env.LKL_UPSTREAM }}/commit/${LKL_COMMIT}
Contains: liblkl-x86_64.tar.gz, liblkl-aarch64.tar.gz
Each tarball includes: liblkl.a, lkl.h, autoconf.h, vmlinux-gdb.py,
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})" \
--notes-file /tmp/release-notes.md \
--prerelease \
dist/liblkl-x86_64.tar.gz \
dist/liblkl-aarch64.tar.gz