Skip to content

Update build-kernel.yml #76

Update build-kernel.yml

Update build-kernel.yml #76

Workflow file for this run

################################################################################
# Advanced / “Complex” Android Kernel Build Workflow (Plan C Primary: Clang + GCC binutils)
#
# Key Features:
# - Matrix over requested build “targets” (ksun / suki etc.) with per-target env configs
# - Plan C: Clang primary + optional GCC (64/32) binutils; fallback to pure GCC if chosen
# - Strong validation (toolchain guards, config file presence)
# - Automatic detection & FAIL for stray literal 'false' token in compile lines
# - Optional suppression wrapper (can be enabled via input if you want to ignore 'false')
# - CCache support
# - Toolchain caching (actions/cache) to avoid re‑downloading between runs
# - Optional “release build” switch: creates a GitHub Release (draft) with artifacts
# - Optional Kconfig patching / KernelSU / KPM / AnyKernel3 packaging
# - Rich job summary (markdown) showing build metadata & artifact sizes
# - Separate “prepare-toolchains” job to avoid repeated downloads for matrix
# - Diagnostics: environment dump, defconfig diff, grep for cc-option misuse
#
# Usage:
# 1. Provide per-target env files: config-ksun.env, config-suki.env, etc.
# 2. Only put “clean” variable assignments (KEY=VALUE) in those files.
# 3. Run workflow manually via Workflow Dispatch.
#
# Notes:
# - The “false” token error you encountered is trapped early; you *must* fix the
# offending cc-option usage in the kernel tree. The workflow will exit with a
# human-readable report pointing to possible files.
# - To temporarily bypass (NOT recommended) you can set the dispatch input
# allow_false_wrapper: true (adds a wrapper that strips literal `false` args).
################################################################################
name: Complex Kernel Build
on:
workflow_dispatch:
inputs:
select_device:
description: 'Select device codename (must match DEVICE in defconfig name: <device>_defconfig)'
required: true
type: choice
options:
- lancelot
- merlin
build_ksun:
description: 'Build KernelSU-Next (A13+)'
required: true
default: true
type: boolean
build_ksun_old:
description: 'Build KernelSU-Next (A11+)'
required: true
default: false
type: boolean
build_suki:
description: 'Build SukiSU (A13+)'
required: true
default: true
type: boolean
build_suki_old:
description: 'Build SukiSU (A11+)'
required: true
default: false
type: boolean
release_build:
description: 'Create (draft) GitHub Release with artifacts'
required: true
default: false
type: boolean
allow_false_wrapper:
description: 'TEMPORARY: Strip stray literal "false" tokens instead of failing (debug aid)'
required: true
default: false
type: boolean
concurrency:
group: complex-kernel-${{ github.ref }}-${{ github.event.inputs.select_device }}
cancel-in-progress: true
env:
# Global defaults (can be overridden by per-target config-*.env files)
KERNEL_ARCH: arm64
KERNEL_IMAGE_NAME: Image.gz-dtb
# Plan C defaults – expect Clang + GCC binutils
USE_CLANG: "true"
USE_GCC: "false"
USE_GCC_64: "true"
USE_GCC_32: "true"
# You should override CLANG_SOURCE in per-target configs if different
CLANG_SOURCE: https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.6/clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04.tar.xz
# Artifact retention tuning
ARTIFACT_RETENTION_DAYS: 7
# Fail the build if stray literal 'false' appears in compile command line
FAIL_ON_FALSE: "true"
permissions:
contents: write # Needed for creating a release
actions: read
checks: read
statuses: read
################################################################################
# Job: Generate matrix based on dispatch booleans
################################################################################
jobs:
generate-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.mk.outputs.matrix }}
steps:
- name: Compute targets
id: mk
shell: bash
run: |
set -euo pipefail
declare -a targets=()
[[ "${{ github.event.inputs.build_ksun }}" == "true" ]] && targets+=("ksun")
[[ "${{ github.event.inputs.build_ksun_old }}" == "true" ]] && targets+=("ksun-old")
[[ "${{ github.event.inputs.build_suki }}" == "true" ]] && targets+=("suki")
[[ "${{ github.event.inputs.build_suki_old }}" == "true" ]] && targets+=("suki-old")
if [[ ${#targets[@]} -eq 0 ]]; then
echo "No targets selected"; exit 1
fi
json=$(printf '%s\n' "${targets[@]}" | jq -R . | jq -s '{target: .}')
echo "matrix=$json" >> "$GITHUB_OUTPUT"
echo "Matrix: $json"
################################################################################
# Job: Prepare toolchains (cached) – runs once, provides artifact or cache
################################################################################
prepare-toolchains:
runs-on: ubuntu-24.04
needs: generate-matrix
outputs:
clang_path: ${{ steps.out.outputs.clang_path }}
steps:
- uses: actions/checkout@v4
- name: Read first target config (to pick toolchain URLs)
id: cfg
shell: bash
run: |
set -euo pipefail
FIRST="${{ fromJson(needs.generate-matrix.outputs.matrix).target[0] }}"
BASE="${FIRST/-old/}"
FILE="config-${BASE}.env"
if [[ ! -f "$FILE" ]]; then
echo "Missing configuration file $FILE" >&2
exit 1
fi
# Export into environment; we only harvest toolchain URL overrides
grep -v -E '^#|^[[:space:]]*$' "$FILE" | sed 's/[[:space:]]*#.*//' >> "$GITHUB_ENV"
- name: Restore Clang cache
id: cache-clang
uses: actions/cache@v4
with:
path: |
toolchains/clang
key: clang-${{ env.CLANG_SOURCE }}
- name: Restore GCC 64 cache
if: env.USE_GCC_64 == 'true'
id: cache-gcc64
uses: actions/cache@v4
with:
path: toolchains/gcc-64
key: gcc64-${{ env.GCC_64_SOURCE }}
- name: Restore GCC 32 cache
if: env.USE_GCC_32 == 'true'
id: cache-gcc32
uses: actions/cache@v4
with:
path: toolchains/gcc-32
key: gcc32-${{ env.GCC_32_SOURCE }}
- name: Download Clang (if cache miss)
if: steps.cache-clang.outputs.cache-hit != 'true'
shell: bash
run: |
set -euo pipefail
mkdir -p toolchains
cd toolchains
url="${{ env.CLANG_SOURCE }}"
echo "Downloading Clang: $url"
case "$url" in
*.tar.xz) wget -nv -O clang.tar.xz "$url"; mkdir clang; tar -C clang -Jxvf clang.tar.xz --strip-components=1; rm clang.tar.xz ;;
*.tar.gz) wget -nv -O clang.tar.gz "$url"; mkdir clang; tar -C clang -zxvf clang.tar.gz --strip-components=1; rm clang.tar.gz ;;
*) echo "Unsupported Clang archive: $url"; exit 1 ;;
esac
file clang/bin/clang
clang/bin/clang --version
- name: Download GCC 64 (if needed)
if: env.USE_GCC_64 == 'true' && steps.cache-gcc64.outputs.cache-hit != 'true'
shell: bash
run: |
set -euo pipefail
mkdir -p toolchains
cd toolchains
url="${{ env.GCC_64_SOURCE }}"
if [[ -z "$url" ]]; then
echo "GCC_64_SOURCE empty but USE_GCC_64=true"; exit 1
fi
wget -nv -O gcc-64.tar.xz "$url"
mkdir gcc-64
tar -C gcc-64 -Jxvf gcc-64.tar.xz --strip-components=1
rm gcc-64.tar.xz
ls gcc-64/bin | head
- name: Download GCC 32 (if needed)
if: env.USE_GCC_32 == 'true' && steps.cache-gcc32.outputs.cache-hit != 'true'
shell: bash
run: |
set -euo pipefail
mkdir -p toolchains
cd toolchains
url="${{ env.GCC_32_SOURCE }}"
if [[ -z "$url" ]]; then
echo "GCC_32_SOURCE empty but USE_GCC_32=true"; exit 1
fi
wget -nv -O gcc-32.tar.xz "$url"
mkdir gcc-32
tar -C gcc-32 -Jxvf gcc-32.tar.xz --strip-components=1
rm gcc-32.tar.xz
ls gcc-32/bin | head
- name: Archive toolchains for matrix jobs (if not cached)
# Archive only if any cache misses occurred, so matrix can reuse quickly
if: |
steps.cache-clang.outputs.cache-hit != 'true' ||
(env.USE_GCC_64 == 'true' && steps.cache-gcc64.outputs.cache-hit != 'true') ||
(env.USE_GCC_32 == 'true' && steps.cache-gcc32.outputs.cache-hit != 'true')
run: |
set -euo pipefail
tar -C toolchains -Jcvf toolchains.tar.xz .
shell: bash
- name: Upload toolchain bundle (only on new downloads)
if: |
steps.cache-clang.outputs.cache-hit != 'true' ||
(env.USE_GCC_64 == 'true' && steps.cache-gcc64.outputs.cache-hit != 'true') ||
(env.USE_GCC_32 == 'true' && steps.cache-gcc32.outputs.cache-hit != 'true')
uses: actions/upload-artifact@v4
with:
name: toolchains-bundle
path: toolchains.tar.xz
retention-days: 3
- name: Output clang dir
id: out
run: |
echo "clang_path=toolchains/clang" >> "$GITHUB_OUTPUT"
################################################################################
# Job: Build (matrix)
################################################################################
build:
needs: [generate-matrix, prepare-toolchains]
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
env:
DEVICE: ${{ github.event.inputs.select_device }}
steps:
- uses: actions/checkout@v4
- name: Fetch toolchain bundle (if present & not cached)
if: always()
uses: actions/download-artifact@v4
with:
name: toolchains-bundle
path: .
- name: Extract toolchain bundle
if: hashFiles('toolchains.tar.xz') != ''
shell: bash
run: |
set -euo pipefail
mkdir -p toolchains
tar -C toolchains -Jxvf toolchains.tar.xz
- name: Install system deps
shell: bash
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y \
lld bc bison build-essential ccache curl flex g++-multilib gcc-multilib git git-lfs gnupg gperf \
imagemagick lib32ncurses-dev lib32readline-dev lib32z1-dev liblz4-tool libncurses5-dev \
libssl-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc zip \
zlib1g-dev python3 jq unzip wget cpio tar xz-utils zstd patchelf pkg-config libelf-dev \
libdw-dev libiberty-dev file bc
- name: Prepare build workspace
shell: bash
run: |
set -euo pipefail
mkdir -p "$GITHUB_WORKSPACE/kernel_workspace"
- name: Load per-target config
id: loadcfg
shell: bash
run: |
set -euo pipefail
TARGET="${{ matrix.target }}"
BASE="${TARGET/-old/}"
FILE="config-${BASE}.env"
if [[ ! -f "$FILE" ]]; then
echo "Missing $FILE" >&2
exit 1
fi
echo "Using config file: $FILE"
grep -v -E '^#|^[[:space:]]*$' "$FILE" | sed 's/[[:space:]]*#.*//' >> "$GITHUB_ENV"
if [[ "$TARGET" == *"-old" ]]; then
echo "ANDROID_TAG=[A11+]" >> "$GITHUB_ENV"
echo "OLD_ANDROID_SUPPORT=true" >> "$GITHUB_ENV"
else
echo "ANDROID_TAG=[A13+]" >> "$GITHUB_ENV"
fi
echo "BUILD_TIME=$(TZ=UTC date '+%Y%m%d%H%M')" >> "$GITHUB_ENV"
- name: Validate toolchain mode (Plan C expectation)
shell: bash
run: |
set -euo pipefail
echo "USE_CLANG=${{ env.USE_CLANG }}"
echo "USE_GCC=${{ env.USE_GCC }}"
if [[ "${{ env.USE_CLANG }}" != "true" ]]; then
echo "Plan C expects USE_CLANG=true; continuing but verify intentionally changed."
fi
if [[ "${{ env.USE_CLANG }}" == "true" && "${{ env.USE_GCC }}" == "true" ]]; then
echo "ERROR: Both USE_CLANG and USE_GCC are true. Aborting." >&2
exit 1
fi
if [[ "${{ env.USE_GCC_32 }}" == "true" ]]; then
echo "CROSS_COMPILE_ARM32=arm-linux-gnueabihf-" >> "$GITHUB_ENV"
echo "CROSS_COMPILE_COMPAT=arm-linux-gnueabihf-" >> "$GITHUB_ENV"
fi
- name: Place toolchains into PATH
shell: bash
run: |
set -euo pipefail
if [[ -d toolchains/clang/bin ]]; then
echo "Adding Clang to PATH"
echo "$GITHUB_WORKSPACE/toolchains/clang/bin" >> $GITHUB_PATH
fi
[[ -d toolchains/gcc-64/bin ]] && echo "$GITHUB_WORKSPACE/toolchains/gcc-64/bin" >> $GITHUB_PATH
[[ -d toolchains/gcc-32/bin ]] && echo "$GITHUB_WORKSPACE/toolchains/gcc-32/bin" >> $GITHUB_PATH
- name: Toolchain sanity check
shell: bash
run: |
set -euo pipefail
which clang || true
which aarch64-linux-gnu-gcc || true
which arm-linux-gnueabihf-gcc || true
clang --version || true
aarch64-linux-gnu-gcc --version || true
- name: Download kernel source
shell: bash
run: |
set -euo pipefail
cd kernel_workspace
git clone --recursive "${{ env.KERNEL_SOURCE }}" -b "${{ env.KERNEL_SOURCE_BRANCH }}" android-kernel --depth=1
cd android-kernel
echo "SOURCE_GIT_HASH=$(git rev-parse HEAD)" >> "$GITHUB_ENV"
- name: Apply optional Kconfig patch
shell: bash
run: |
set -euo pipefail
cd kernel_workspace/android-kernel
if [[ -f "$GITHUB_WORKSPACE/patches/fix_kconfig.patch" ]]; then
git apply "$GITHUB_WORKSPACE/patches/fix_kconfig.patch"
fi
- name: Setup KernelSU (if enabled)
if: env.ENABLE_KERNELSU == 'true'
shell: bash
run: |
set -euo pipefail
cd kernel_workspace/android-kernel
curl -LSs "$KERNELSU_SETUP_SOURCE" | bash -s "${{ env.KERNELSU_TAG }}"
KSU_VERSION="_$(cd "$(echo "$KERNELSU_SETUP_SOURCE" | cut -d/ -f5)" 2>/dev/null || cd KernelSU; expr "$(git rev-list --count HEAD)" + 10200)"
echo "UPLOADNAME=-KernelSU-${{ matrix.target }}$KSU_VERSION" >> "$GITHUB_ENV"
- name: Mutate defconfig (KernelSU + extras)
shell: bash
run: |
set -euo pipefail
KDEF="kernel_workspace/android-kernel/arch/${{ env.KERNEL_ARCH }}/configs/${DEVICE}_defconfig"
[[ -f "$KDEF" ]] || { echo "Defconfig $KDEF missing"; exit 1; }
if [[ "${{ env.ENABLE_KERNELSU }}" == "true" ]]; then
# Basic ensure line
grep -q '^CONFIG_KSU=' "$KDEF" || echo "CONFIG_KSU=y" >> "$KDEF"
fi
if [[ "${{ env.DISABLE_LTO }}" == "true" ]]; then
sed -i 's/CONFIG_LTO=y/CONFIG_LTO=n/' "$KDEF" || true
sed -i 's/CONFIG_LTO_CLANG=y/CONFIG_LTO_CLANG=n/' "$KDEF" || true
sed -i 's/CONFIG_THINLTO=y/CONFIG_THINLTO=n/' "$KDEF" || true
grep -q '^CONFIG_LTO_NONE=' "$KDEF" || echo "CONFIG_LTO_NONE=y" >> "$KDEF"
fi
if [[ "${{ env.DISABLE_CC_WERROR }}" == "true" ]]; then
grep -q '^CONFIG_CC_WERROR=' "$KDEF" || echo "CONFIG_CC_WERROR=n" >> "$KDEF"
fi
echo "FINAL_DEFCONFIG_SNAPSHOT<<EOF" >> "$GITHUB_ENV"
sed 's/^/DEF: /' "$KDEF" >> "$GITHUB_ENV"
echo "EOF" >> "$GITHUB_ENV"
- name: CCache setup
if: env.ENABLE_CCACHE == 'true'
uses: hendrikmuhs/ccache-action@v1.2
with:
key: complex-${{ env.DEVICE }}-${{ matrix.target }}
max-size: 5G
- name: Add optional 'false' stripping wrapper
if: github.event.inputs.allow_false_wrapper == 'true'
shell: bash
run: |
set -euo pipefail
WRAP_DIR="$GITHUB_WORKSPACE/wrap"
mkdir -p "$WRAP_DIR"
cat > "$WRAP_DIR/clang" <<'EOF'
#!/usr/bin/env bash
# Wrapper drops literal 'false' tokens.
REAL="$(command -v clang | grep -v "$PWD")"

Check failure on line 432 in .github/workflows/build-kernel.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/build-kernel.yml

Invalid workflow file

You have an error in your yaml syntax on line 432
args=()
for a in "$@"; do
[[ "$a" == "false" ]] && continue
args+=("$a")
done
exec "$REAL" "${args[@]}"
EOF
chmod +x "$WRAP_DIR/clang"
echo "$WRAP_DIR" >> $GITHUB_PATH
echo "Wrapper installed. (Temporary workaround; fix cc-option fallback!)."
- name: Detect cc-option misuse before build
shell: bash
run: |
set -euo pipefail
cd kernel_workspace/android-kernel
# Report any suspicious lines containing ',false)' or space false) within Make/Kbuild
echo "Scanning for cc-option fallbacks using literal 'false'..."
hits=$(grep -R --include='Makefile*' --include='Kbuild*' -nE 'cc-.*\(.*false\)' . || true)
if [[ -n "$hits" ]]; then
echo "Potential offenders:"
echo "$hits"
echo "$hits" > ../cc_option_false_hits.txt
else
echo "No obvious cc-option false patterns found."
fi
- name: Build (Plan C / fallback)
shell: bash
id: buildstep
run: |
set -euo pipefail
cd "$GITHUB_WORKSPACE/kernel_workspace/android-kernel"
# Toolchain environment
if [[ "${{ env.USE_CLANG }}" == "true" ]]; then
export CC=clang
export LD=ld.lld
export AR=llvm-ar
export NM=llvm-nm
export OBJCOPY=llvm-objcopy
export OBJDUMP=llvm-objdump
export STRIP=llvm-strip
export LLVM=1
export LLVM_IAS=1
export CROSS_COMPILE=aarch64-linux-gnu-
: "${CROSS_COMPILE_ARM32:=arm-linux-gnueabihf-}"
: "${CROSS_COMPILE_COMPAT:=$CROSS_COMPILE_ARM32}"
echo "Mode: Clang primary"
else
export CC=aarch64-linux-gnu-gcc
export CROSS_COMPILE=aarch64-linux-gnu-
: "${CROSS_COMPILE_ARM32:=arm-linux-gnueabihf-}"
: "${CROSS_COMPILE_COMPAT:=$CROSS_COMPILE_ARM32}"
echo "Mode: GCC only"
fi
which $CC || true
$CC --version || true
# First pass: defconfig
make V=1 -j"$(nproc)" O=out ARCH="${{ env.KERNEL_ARCH }}" "${DEVICE}_defconfig"
# OPTIONAL: compile one trivial object to detect stray 'false'
line=$(make -n V=1 O=out ARCH=${{ env.KERNEL_ARCH }} scripts/mod/empty.o 2>&1 | grep -m1 " false " || true)
if [[ -n "$line" && "${{ env.FAIL_ON_FALSE }}" == "true" && "${{ github.event.inputs.allow_false_wrapper }}" != "true" ]]; then
echo "ERROR: Detected stray literal 'false' token in compile line BEFORE full build:"
echo "$line"
echo "Likely from a cc-option fallback using 'false'. Search & remove 'false' fallback."
exit 1
fi
# Full build
if [[ "${{ env.ENABLE_CCACHE }}" == "true" && "$CC" != "clang" ]]; then
make V=1 -j"$(nproc)" O=out ARCH="${{ env.KERNEL_ARCH }}" CC="ccache $CC" \
CROSS_COMPILE="$CROSS_COMPILE" CROSS_COMPILE_ARM32="$CROSS_COMPILE_ARM32" CROSS_COMPILE_COMPAT="$CROSS_COMPILE_COMPAT"
else
make V=1 -j"$(nproc)" O=out ARCH="${{ env.KERNEL_ARCH }}" CC="$CC" \
CROSS_COMPILE="$CROSS_COMPILE" CROSS_COMPILE_ARM32="$CROSS_COMPILE_ARM32" CROSS_COMPILE_COMPAT="$CROSS_COMPILE_COMPAT"
fi
OUT_IMG="out/arch/${{ env.KERNEL_ARCH }}/boot/${{ env.KERNEL_IMAGE_NAME }}"
if [[ -f "$OUT_IMG" ]]; then
echo "CHECK_FILE_IS_OK=true" >> "$GITHUB_ENV"
else
echo "Kernel image missing"; exit 1
fi
- name: Package AnyKernel3
if: env.CHECK_FILE_IS_OK == 'true' && env.USE_ANYKERNEL3 == 'true'
shell: bash
run: |
set -euo pipefail
cd kernel_workspace
src="${{ env.ANYKERNEL3_SOURCE }}"
if [[ "$src" == *'.git' ]]; then
git clone "$src" -b "${{ env.ANYKERNEL3_BRANCH }}" --depth=1 AnyKernel3
else
mkdir -p AnyKernel3
# Extend if you want tar/zip sources
echo "Non-git AnyKernel3 source not implemented for complex workflow yet."
fi
cp android-kernel/out/arch/${{ env.KERNEL_ARCH }}/boot/${{ env.KERNEL_IMAGE_NAME }} AnyKernel3/
[[ "${{ env.NEED_DTBO }}" == "true" && -f android-kernel/out/arch/${{ env.KERNEL_ARCH }}/boot/dtbo.img ]] && cp android-kernel/out/arch/${{ env.KERNEL_ARCH }}/boot/dtbo.img AnyKernel3/
rm -rf AnyKernel3/.git*
(cd AnyKernel3 && zip -r ../AnyKernel3-${{ matrix.target }}.zip .)
echo "ANYKERNEL_ZIP=kernel_workspace/AnyKernel3-${{ matrix.target }}.zip" >> "$GITHUB_ENV"
- name: Compute kernel localversion
shell: bash
run: |
set -euo pipefail
DEF="kernel_workspace/android-kernel/arch/${{ env.KERNEL_ARCH }}/configs/${DEVICE}_defconfig"
RAW=$(grep -oP 'CONFIG_LOCALVERSION="\K[^"]+' "$DEF" || true)
RAW="${RAW#-}"
[[ -z "$RAW" ]] && RAW="CustomKernel"
echo "KERNEL_LOCALVERSION=$RAW" >> "$GITHUB_ENV"
- name: Upload raw kernel image
if: env.CHECK_FILE_IS_OK == 'true'
uses: actions/upload-artifact@v4
with:
name: kernel-${{ matrix.target }}-${{ env.DEVICE }}-${{ env.KERNEL_LOCALVERSION }}-${{ env.BUILD_TIME }}
path: kernel_workspace/android-kernel/out/arch/${{ env.KERNEL_ARCH }}/boot/${{ env.KERNEL_IMAGE_NAME }}
retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }}
- name: Upload AnyKernel3 zip
if: env.CHECK_FILE_IS_OK == 'true' && env.USE_ANYKERNEL3 == 'true'
uses: actions/upload-artifact@v4
with:
name: AnyKernel3-${{ matrix.target }}-${{ env.DEVICE }}-${{ env.KERNEL_LOCALVERSION }}-${{ env.BUILD_TIME }}
path: ${{ env.ANYKERNEL_ZIP }}
retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }}
- name: Build summary (markdown)
id: summary
shell: bash
run: |
set -euo pipefail
OUT_PATH="kernel_workspace/android-kernel/out/arch/${{ env.KERNEL_ARCH }}/boot/${{ env.KERNEL_IMAGE_NAME }}"
SIZE=""
if [[ -f "$OUT_PATH" ]]; then SIZE=$(stat -c%s "$OUT_PATH"); fi
cat > build-summary.md <<EOF
# Kernel Build Summary
**Target:** ${{ matrix.target }}
**Device:** ${{ env.DEVICE }}
**Android Tag:** ${{ env.ANDROID_TAG }}
**LocalVersion:** ${{ env.KERNEL_LOCALVERSION }}
**Build Time (UTC):** ${{ env.BUILD_TIME }}
**Source Git Hash:** ${{ env.SOURCE_GIT_HASH }}
**Toolchain Mode:** $( [[ "${{ env.USE_CLANG }}" == "true" ]] && echo "Clang (Plan C)" || echo "GCC" )
**Kernel Image Present:** ${{ env.CHECK_FILE_IS_OK }}
**Kernel Image Size (bytes):** ${SIZE:-N/A}
**AnyKernel3:** ${{ env.USE_ANYKERNEL3 }}
**KernelSU Enabled:** ${{ env.ENABLE_KERNELSU }}
**OLD ANDROID SUPPORT:** ${{ env.OLD_ANDROID_SUPPORT }}
<details>
<summary>Defconfig tail (last 40 lines)</summary>
\`\`\`
$(tail -n 40 kernel_workspace/android-kernel/arch/${{ env.KERNEL_ARCH }}/configs/${DEVICE}_defconfig)
\`\`\`
</details>
<details>
<summary>Potential cc-option false hits (if any)</summary>
\`\`\`
$(test -f kernel_workspace/cc_option_false_hits.txt && sed -n '1,120p' kernel_workspace/cc_option_false_hits.txt || echo "None")
\`\`\`
</details>
EOF
echo "HAS_SUMMARY=true" >> "$GITHUB_ENV"
- name: Upload build summary artifact
if: env.HAS_SUMMARY == 'true'
uses: actions/upload-artifact@v4
with:
name: summary-${{ matrix.target }}-${{ env.DEVICE }}-${{ env.BUILD_TIME }}
path: build-summary.md
retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }}
- name: Append to Job Summary
if: env.HAS_SUMMARY == 'true'
shell: bash
run: |
cat build-summary.md >> $GITHUB_STEP_SUMMARY
################################################################################
# Job: Release (collect artifacts from all matrix builds)
################################################################################
release:
if: github.event.inputs.release_build == 'true'
needs: [build]
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: collected
- name: Generate release notes
id: notes
shell: bash
run: |
set -euo pipefail
echo "## Kernel Build Release" > RELEASE_NOTES.md
echo "" >> RELEASE_NOTES.md
find collected -type f -maxdepth 2 -printf '%P\n' | sort | while read -r f; do
sz=$(stat -c%s "collected/$f")
echo "- $f (${sz} bytes)" >> RELEASE_NOTES.md
done
echo "notes<<EOF" >> "$GITHUB_OUTPUT"
cat RELEASE_NOTES.md >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
- name: Create draft release
uses: softprops/action-gh-release@v2
with:
tag_name: kernel-${{ github.event.inputs.select_device }}-${{ github.run_id }}
name: "Kernel Build - ${{ github.event.inputs.select_device }} - Run ${{ github.run_number }}"
draft: true
prerelease: false
body: ${{ steps.notes.outputs.notes }}
files: |
collected/**/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}