This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Release OnePlus Kernels | ||
| permissions: | ||
| contents: write | ||
| actions: write | ||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| make_release: | ||
| description: 'Do you want to create a release?' | ||
| required: true | ||
| type: boolean | ||
| default: false | ||
| op_model: | ||
| description: 'Select the OnePlus kernels to build' | ||
| required: true | ||
| type: choice | ||
| options: | ||
| - OOS14+15+16 | ||
| - OOS15+16 | ||
| - OOS14+15 | ||
| - OOS16 | ||
| - OOS15 | ||
| - OOS14 | ||
| - android15-6.6 | ||
| - android14-6.1 | ||
| - android13-5.15 | ||
| - android12-5.10 | ||
| default: OOS15 | ||
| ksun_branch: | ||
| description: 'Enter KernelSU Next Branch or commit hash (blank for stable tag)' | ||
| required: true | ||
| type: string | ||
| default: next | ||
| optimize_level: | ||
| description: "Compiler optimization level" | ||
| required: true | ||
| type: choice | ||
| options: [O2, O3] | ||
| default: O2 | ||
| clean_build: | ||
| description: 'Clean build (no ccache)' | ||
| type: boolean | ||
| default: false | ||
| android12-5_10_susfs_branch_or_commit: | ||
| description: 'Enter SusFS Branch or commit hash for android12-5.10' | ||
| type: string | ||
| default: '' | ||
| android13-5_10_susfs_branch_or_commit: | ||
| description: 'Enter SusFS Branch or commit hash for android13-5.10' | ||
| type: string | ||
| default: '' | ||
| android13-5_15_susfs_branch_or_commit: | ||
| description: 'Enter SusFS Branch or commit hash for android13-5.15' | ||
| type: string | ||
| default: '' | ||
| android14-5_15_susfs_branch_or_commit: | ||
| description: 'Enter SusFS Branch or commit hash for android14-5.15' | ||
| type: string | ||
| default: '' | ||
| android14-6_1_susfs_branch_or_commit: | ||
| description: 'Enter SusFS Branch or commit hash for android14-6.1' | ||
| type: string | ||
| default: '' | ||
| android15-6_6_susfs_branch_or_commit: | ||
| description: 'Enter SusFS Branch or commit hash for android15-6.6' | ||
| type: string | ||
| default: '' | ||
| jobs: | ||
| set-op-model: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| matrix: ${{ steps.set-matrix.outputs.matrix }} | ||
| device_count: ${{ steps.set-matrix.outputs.count }} | ||
| steps: | ||
| - name: π₯ Checkout Code (to access configs/) | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| sparse-checkout: | | ||
| configs/ | ||
| sparse-checkout-cone-mode: false | ||
| - name: π Generate build matrix | ||
| id: set-matrix | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| echo "::group::Matrix generation" | ||
| FILTERED_FOR_ANDROID=false | ||
| input="${{ github.event.inputs.op_model }}" | ||
| echo "[" > matrix.json | ||
| mapfile -t all_json_files < <(find configs/ -name "*.json" -print0 | xargs -0 -n1) | ||
| for i in "${!all_json_files[@]}"; do | ||
| file="${all_json_files[$i]}" | ||
| if [ -f "$file" ]; then | ||
| jq -r '.' "$file" >> matrix.json | ||
| if [ $((i+1)) -lt ${#all_json_files[@]} ]; then | ||
| echo "," >> matrix.json | ||
| fi | ||
| fi | ||
| done | ||
| echo "]" >> matrix.json | ||
| jq_filter="." | ||
| case "$input" in | ||
| OOS14+15+16) | ||
| ;; | ||
| OOS15+16) | ||
| jq_filter="map(select(.os_version == \"OOS15\" or .os_version == \"OOS16\"))" | ||
| ;; | ||
| OOS14+15) | ||
| jq_filter="map(select(.os_version == \"OOS14\" or .os_version == \"OOS15\"))" | ||
| ;; | ||
| OOS16) | ||
| jq_filter="map(select(.os_version == \"OOS16\"))" | ||
| ;; | ||
| OOS15) | ||
| jq_filter="map(select(.os_version == \"OOS15\"))" | ||
| ;; | ||
| OOS14) | ||
| jq_filter="map(select(.os_version == \"OOS14\"))" | ||
| ;; | ||
| android*-*.*) | ||
| IFS='-' read -r av kv <<< "$input" | ||
| jq_filter="map(select(.android_version == \"$av\" and .kernel_version == \"$kv\"))" | ||
| FILTERED_FOR_ANDROID=true | ||
| ;; | ||
| *) | ||
| echo "::warning::Unknown input '$input'. Using empty filter." | ||
| jq_filter="map(select(false))" | ||
| ;; | ||
| esac | ||
| filtered=$(jq -c "$jq_filter" matrix.json) | ||
| count=$(jq 'length' <<<"$filtered") | ||
| if [ "$count" -eq 0 ]; then | ||
| echo "::error::No config files found for input '$input' after applying filters!" | ||
| exit 1 | ||
| fi | ||
| wrapped=$(jq -n --argjson items "$filtered" '{ include: $items }') | ||
| echo "β Found $count device(s) to build" | ||
| echo "" | ||
| echo "Devices:" | ||
| jq -r '.[] | " - \(.model) (\(.android_version)-\(.kernel_version))"' <<<"$filtered" | ||
| echo "matrix<<MATRIX_EOF" >> "$GITHUB_OUTPUT" | ||
| echo "$wrapped" >> "$GITHUB_OUTPUT" | ||
| echo "MATRIX_EOF" >> "$GITHUB_OUTPUT" | ||
| echo "count=$count" >> "$GITHUB_OUTPUT" | ||
| echo "::endgroup::" | ||
| - name: π Build plan summary | ||
| run: | | ||
| cat >> $GITHUB_STEP_SUMMARY << 'EOF' | ||
| ## π― Build Plan | ||
| **Target:** `${{ github.event.inputs.op_model }}` | ||
| **Devices:** ${{ steps.set-matrix.outputs.count }} | ||
| ### Configuration | ||
| | Setting | Value | | ||
| |---------|-------| | ||
| | KSU Branch | `${{ inputs.ksun_branch }}` | | ||
| | Optimization | `${{ inputs.optimize_level }}` | | ||
| | Clean Build | ${{ inputs.clean_build }} | | ||
| | Create Release | ${{ inputs.make_release }} | | ||
| ### SUSFS Configuration | ||
| | Kernel Version | SUSFS Branch/Commit | | ||
| |----------------|---------------------| | ||
| EOF | ||
| # Display SUSFS config for each kernel version | ||
| for key in "android12-5.10" "android13-5.10" "android13-5.15" "android14-5.15" "android14-6.1" "android15-6.6"; do | ||
| input_key=$(echo "$key" | tr '.-' '__') | ||
| input_name="android${key#android}_susfs_branch_or_commit" | ||
| case "$key" in | ||
| "android12-5.10") value="${{ inputs.android12-5_10_susfs_branch_or_commit }}" ;; | ||
| "android13-5.10") value="${{ inputs.android13-5_10_susfs_branch_or_commit }}" ;; | ||
| "android13-5.15") value="${{ inputs.android13-5_15_susfs_branch_or_commit }}" ;; | ||
| "android14-5.15") value="${{ inputs.android14-5_15_susfs_branch_or_commit }}" ;; | ||
| "android14-6.1") value="${{ inputs.android14-6_1_susfs_branch_or_commit }}" ;; | ||
| "android15-6.6") value="${{ inputs.android15-6_6_susfs_branch_or_commit }}" ;; | ||
| esac | ||
| if [ -z "$value" ]; then | ||
| echo "| $key | \`(auto: gki-$key)\` |" >> $GITHUB_STEP_SUMMARY | ||
| else | ||
| echo "| $key | \`$value\` |" >> $GITHUB_STEP_SUMMARY | ||
| fi | ||
| done | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "> **Note:** Empty values auto-map to the matching gki-androidX-Y.Z branch during build." >> $GITHUB_STEP_SUMMARY | ||
| build: | ||
| name: build (${{ matrix.model }}, ${{ matrix.soc }}, ${{ matrix.branch }}, ${{ matrix.manifest }}, ${{ matrix.android_version }}, ${{ matrix.kernel_version }}, ${{ matrix.os_version }}, ${{ inputs.ksun_branch }}) | ||
| needs: set-op-model | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: ${{ fromJSON(needs.set-op-model.outputs.matrix) }} | ||
| steps: | ||
| - name: π§Ή Emergency Disk Cleanup | ||
| run: | | ||
| echo "::group::Disk Usage Before Cleanup" | ||
| df -h | ||
| echo "::endgroup::" | ||
| echo "::group::Removing Unnecessary Software" | ||
| sudo rm -rf /usr/share/dotnet | ||
| sudo rm -rf /usr/local/lib/android | ||
| sudo rm -rf /opt/ghc | ||
| sudo rm -rf /opt/hostedtoolcache/CodeQL | ||
| sudo apt-get clean | ||
| if command -v docker >/dev/null 2>&1; then | ||
| docker rmi $(docker images -q) 2>/dev/null || true | ||
| fi | ||
| echo "::endgroup::" | ||
| echo "::group::Disk Usage After Cleanup" | ||
| df -h | ||
| AVAIL=$(df -h / | awk 'NR==2 {print $4}') | ||
| echo "β Available space: $AVAIL" | ||
| echo "::endgroup::" | ||
| - name: π Resolve SUSFS branch from inputs | ||
| id: susfs | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| key="${{ matrix.android_version }}-${{ matrix.kernel_version }}" | ||
| echo "Looking up SUSFS branch for: $key" | ||
| # Map kernel version to input value | ||
| case "$key" in | ||
| "android12-5.10") | ||
| susfs_branch="${{ inputs.android12-5_10_susfs_branch_or_commit }}" | ||
| ;; | ||
| "android13-5.10") | ||
| susfs_branch="${{ inputs.android13-5_10_susfs_branch_or_commit }}" | ||
| ;; | ||
| "android13-5.15") | ||
| susfs_branch="${{ inputs.android13-5_15_susfs_branch_or_commit }}" | ||
| ;; | ||
| "android14-5.15") | ||
| susfs_branch="${{ inputs.android14-5_15_susfs_branch_or_commit }}" | ||
| ;; | ||
| "android14-6.1") | ||
| susfs_branch="${{ inputs.android14-6_1_susfs_branch_or_commit }}" | ||
| ;; | ||
| "android15-6.6") | ||
| susfs_branch="${{ inputs.android15-6_6_susfs_branch_or_commit }}" | ||
| ;; | ||
| *) | ||
| echo "::error::Unsupported kernel version: $key" | ||
| exit 1 | ||
| ;; | ||
| esac | ||
| # If empty, it will be auto-resolved to gki-* branch in the action | ||
| if [ -z "$susfs_branch" ]; then | ||
| echo "βΉοΈ No custom SUSFS branch specified for $key" | ||
| echo " Will auto-select: gki-$key" | ||
| else | ||
| echo "β Using custom SUSFS branch for $key: '$susfs_branch'" | ||
| fi | ||
| echo "susfs_branch=$susfs_branch" >> "$GITHUB_OUTPUT" | ||
| - name: π₯ Checkout Code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 1 | ||
| - name: π¦ Disk usage (pre-build) | ||
| run: | | ||
| echo "::group::Disk usage pre-build" | ||
| df -h / | ||
| du -sh "$GITHUB_WORKSPACE" 2>/dev/null || true | ||
| sudo rm -rf /tmp/* || true | ||
| echo "::endgroup::" | ||
| - name: β»οΈ Configure ccache (bounded) | ||
| if: ${{ inputs.clean_build != true }} | ||
| run: | | ||
| if command -v ccache >/dev/null 2>&1; then | ||
| echo "::group::ccache configuration" | ||
| ccache -o max_size=2.0G | ||
| ccache -o compression=true | ||
| ccache -s | ||
| echo "::endgroup::" | ||
| fi | ||
| - name: π¨ Build Kernel | ||
| id: build | ||
| uses: ./.github/actions | ||
| with: | ||
| op_config_json: ${{ toJSON(matrix) }} | ||
| ksun_branch: ${{ inputs.ksun_branch }} | ||
| susfs_commit_hash_or_branch: ${{ steps.susfs.outputs.susfs_branch }} | ||
| optimize_level: ${{ inputs.optimize_level }} | ||
| clean: ${{ inputs.clean_build }} | ||
| - name: π Build statistics | ||
| if: always() | ||
| run: | | ||
| echo "::group::Build Statistics" | ||
| echo "Device: ${{ matrix.model }}" | ||
| echo "Kernel: ${{ matrix.android_version }}-${{ matrix.kernel_version }}" | ||
| echo "SUSFS Branch: ${{ steps.susfs.outputs.susfs_branch }}" | ||
| echo "Status: ${{ job.status }}" | ||
| if [ "${{ steps.build.outcome }}" = "success" ]; then | ||
| echo "" | ||
| echo "β Build completed successfully" | ||
| echo "" | ||
| echo "Outputs:" | ||
| echo " - Kernel: ${{ steps.build.outputs.kernel_version }}" | ||
| echo " - KSU Next: v${{ steps.build.outputs.ksu_version }}" | ||
| echo " - SUSFS: ${{ steps.build.outputs.susfs_version }}" | ||
| echo " - Build time: ${{ steps.build.outputs.build_time }}s" | ||
| if [ "${{ inputs.clean_build }}" != "true" ]; then | ||
| echo " - ccache hit rate: ${{ steps.build.outputs.ccache_hit_rate }}" | ||
| echo " - ccache direct rate: ${{ steps.build.outputs.ccache_direct_rate }}" | ||
| else | ||
| echo " - ccache: disabled (clean build)" | ||
| fi | ||
| if [ -n "${{ steps.build.outputs.warnings }}" ]; then | ||
| echo " - Warnings: ${{ steps.build.outputs.warnings }}" | ||
| fi | ||
| else | ||
| echo "β Build failed" | ||
| fi | ||
| echo "::endgroup::" | ||
| - name: π Job summary | ||
| if: always() | ||
| run: | | ||
| cat >> $GITHUB_STEP_SUMMARY << EOF | ||
| ### ${{ matrix.model }} - ${{ job.status == 'success' && 'β Success' || 'β Failed' }} | ||
| **Kernel:** ${{ matrix.android_version }}-${{ matrix.kernel_version }} | ||
| **SUSFS Branch:** \`${{ steps.susfs.outputs.susfs_branch || format('(auto: gki-{0}-{1})', matrix.android_version, matrix.kernel_version) }}\` | ||
| EOF | ||
| if [ "${{ steps.build.outcome }}" = "success" ]; then | ||
| cat >> $GITHUB_STEP_SUMMARY << EOF | ||
| | Metric | Value | | ||
| |--------|-------| | ||
| | **Kernel** | ${{ steps.build.outputs.kernel_version }} | | ||
| | **KSU Next** | v${{ steps.build.outputs.ksu_version }} | | ||
| | **SUSFS** | ${{ steps.build.outputs.susfs_version }} | | ||
| | **Build Time** | ${{ steps.build.outputs.build_time }}s | | ||
| EOF | ||
| if [ "${{ inputs.clean_build }}" != "true" ]; then | ||
| cat >> $GITHUB_STEP_SUMMARY << EOF | ||
| | **ccache Hit Rate** | ${{ steps.build.outputs.ccache_hit_rate }} | | ||
| | **ccache Direct Rate** | ${{ steps.build.outputs.ccache_direct_rate }} | | ||
| EOF | ||
| fi | ||
| if [ -n "${{ steps.build.outputs.warnings }}" ]; then | ||
| echo "| **Warnings** | ${{ steps.build.outputs.warnings }} |" >> $GITHUB_STEP_SUMMARY | ||
| fi | ||
| cat >> $GITHUB_STEP_SUMMARY << EOF | ||
| **SHA256:** \`${{ steps.build.outputs.image_sha256 }}\` | ||
| EOF | ||
| fi | ||
| - name: π§Ή Final cleanup and space report | ||
| if: always() | ||
| run: | | ||
| echo "::group::Cleanup" | ||
| # Remove build artifacts but PRESERVE ccache | ||
| sudo rm -rf "$GITHUB_WORKSPACE/out" || true | ||
| sudo rm -rf "$GITHUB_WORKSPACE/build" || true | ||
| sudo rm -rf "$GITHUB_WORKSPACE/kernel/out" || true | ||
| sudo rm -rf "$GITHUB_WORKSPACE/.repo" || true | ||
| sudo rm -rf /tmp/* || true | ||
| # Show ccache stats (don't clear it!) | ||
| if command -v ccache >/dev/null 2>&1; then | ||
| echo "" | ||
| echo "π ccache statistics after build:" | ||
| ccache -s | ||
| echo "" | ||
| echo "πΎ ccache preserved for next build" | ||
| fi | ||
| echo "" | ||
| echo "π½ Final disk usage:" | ||
| df -h / | ||
| echo "::endgroup::" | ||
| trigger-release: | ||
| needs: [build] | ||
| runs-on: ubuntu-latest | ||
| if: ${{ inputs.make_release }} | ||
| env: | ||
| REPO_OWNER: ${{ github.repository_owner }} | ||
| REPO_NAME: ${{ github.event.repository.name }} | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| RELEASE_NAME: '*TEST BUILD* OnePlus Kernels With KernelSU Next & SUSFS v1.5.12 *TEST BUILD*' | ||
| steps: | ||
| - name: π₯ Checkout code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| - name: π·οΈ Generate and Create New Tag | ||
| run: | | ||
| BASE_TAG="v1.5.12-r0" | ||
| LATEST_TAG=$(gh api repos/$REPO_OWNER/$REPO_NAME/tags --jq '.[0].name') | ||
| if [ -z "$LATEST_TAG" ]; then | ||
| LATEST_TAG="$BASE_TAG" | ||
| else | ||
| LATEST_TAG=$(printf "%s\n%s\n" "$LATEST_TAG" "$BASE_TAG" | sort -rV | head -n1) | ||
| fi | ||
| NEW_TAG=$(echo "$LATEST_TAG" | awk -F'-r' '{suffix=$2; if (!suffix) suffix=0; suffix++; printf "%s-r%d", $1, suffix}') | ||
| echo "New tag: $NEW_TAG" | ||
| echo "NEW_TAG=${NEW_TAG}" >> $GITHUB_ENV | ||
| git tag $NEW_TAG | ||
| git push origin $NEW_TAG | ||
| - name: π₯ Download Artifacts | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| path: ./downloaded-artifacts | ||
| - name: π Generate Device List and Final Release Notes | ||
| id: generate-notes | ||
| run: | | ||
| echo "=== Start building the release notes ===" | ||
| cat << EOF > release_notes.md | ||
| This release contains KernelSU Next and SUSFS v1.5.12 | ||
| Module: | ||
| -> https://github.com/sidex15/ksu_module_susfs | ||
| Official Managers: | ||
| -> https://github.com/KernelSU-Next/KernelSU-Next | ||
| Non-Official Managers: | ||
| -> https://github.com/WildKernels/Wild_KSU | ||
| ### Built Devices | ||
| | Model | OS Version | Kernel Version | | ||
| |-------|------------|----------------| | ||
| EOF | ||
| for file in $(find downloaded-artifacts -name "*.txt" -type f | sort); do | ||
| if [ -f "$file" ]; then | ||
| full_model=$(basename "$file" .txt) | ||
| model=$(echo "$full_model" | sed -E 's/_[^_]*$//') | ||
| os_version=$(sed -n '2p' "$file") | ||
| kernel_version=$(sed -n '1p' "$file") | ||
| if [ -n "$model" ] && [ -n "$os_version" ] && [ -n "$kernel_version" ]; then | ||
| printf "| %-12s | %-10s | %-16s |\n" "$model" "$os_version" "$kernel_version" >> release_notes.md | ||
| else | ||
| echo "Warning: Could not read kernel version or OS version from $file. Skipping row for $model." | ||
| fi | ||
| fi | ||
| done | ||
| cat << 'EOF' >> release_notes.md | ||
| ### Features | ||
| - [+] KernelSU-Next / WildKSU Manager Support | ||
| - [+] SUSFS v1.5.12 | ||
| - [+] Wireguard Support | ||
| - [+] Magic Mount Support | ||
| - [+] Ptrace message leak fix for kernels < 5.16 | ||
| - [+] Manual Hooks [scope_min_manual_hooks_v1.4] | ||
| - [+] CONFIG_TMPFS_XATTR Support [Mountify Support] | ||
| - [+] BBR v1 Support | ||
| - [+] HMBIRD scx support for OnePlus 13 & OnePlus Ace 5 Pro | ||
| - [+] Baseband Guard Support (BBG) | ||
| - [+] IP Set Support | ||
| - [+] ccache-accelerated builds for faster compilation | ||
| EOF | ||
| echo "--- Final Release Notes ---" | ||
| cat release_notes.md | ||
| - name: π Create GitHub Release | ||
| run: | | ||
| gh release create "${{ env.NEW_TAG }}" \ | ||
| --repo "${{ env.REPO_OWNER }}/${{ env.REPO_NAME }}" \ | ||
| --title "${{ env.RELEASE_NAME }}" \ | ||
| --notes-file release_notes.md \ | ||
| --prerelease | ||
| - name: π€ Upload Release Assets Dynamically | ||
| run: | | ||
| for file in ./downloaded-artifacts/*/*.zip; do | ||
| if [ -f "$file" ]; then | ||
| echo "Uploading $file..." | ||
| gh release upload "${{ env.NEW_TAG }}" "$file" --clobber | ||
| fi | ||
| done | ||
| - name: π Release summary | ||
| if: success() | ||
| run: | | ||
| cat >> $GITHUB_STEP_SUMMARY << EOF | ||
| --- | ||
| ## π Release Created Successfully | ||
| **Tag:** [\`${{ env.NEW_TAG }}\`](${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ env.NEW_TAG }}) | ||
| **Kernels:** $(find ./downloaded-artifacts -name "*.zip" | wc -l) | ||
| ### π¦ Assets | ||
| EOF | ||
| for zip in ./downloaded-artifacts/*/*.zip; do | ||
| if [ -f "$zip" ]; then | ||
| name=$(basename "$zip") | ||
| size=$(stat -c%s "$zip") | ||
| size_mb=$(echo "scale=2; $size / 1024 / 1024" | bc) | ||
| echo "- \`$name\` (${size_mb} MB)" >> $GITHUB_STEP_SUMMARY | ||
| fi | ||
| done | ||