Skip to content

OP13 KSUN

OP13 KSUN #28

Workflow file for this run

name: OP13 KSUN
permissions:
contents: read
actions: read
on:
workflow_dispatch:
inputs:
feature_profile:
description: 'Build profile'
required: true
type: choice
options:
- release_match
- battery_daily
- advanced_daily
- minimal_debug
default: battery_daily
ksun_ref:
description: 'KernelSU-Next ref. Default is the proven OP13 KSUN 33129 commit.'
required: true
default: '551ad80473f60e052917aec08abf5323b6ab2f7c'
susfs:
description: 'Enable SUSFS'
required: true
type: choice
options: ['On', 'Off']
default: 'On'
susfs_ref:
description: 'CCTV18 susfs4oki ref. Default is oki-android15-6.6.'
required: false
default: 'oki-android15-6.6'
optimize_level:
description: 'Compiler optimisation level'
required: true
type: choice
options: ['O2', 'O3']
default: 'O2'
hmbird:
description: 'HMBIRD/SCX scheduler'
required: true
type: choice
options: ['Auto', 'On', 'Off']
default: 'Auto'
droidspaces:
description: 'Droidspaces support'
required: true
type: choice
options: ['Auto', 'On', 'Off']
default: 'Auto'
bbr:
description: 'Enable BBR'
required: true
type: choice
options: ['On', 'Off']
default: 'On'
bbg:
description: 'Enable Baseband Guard'
required: true
type: choice
options: ['On', 'Off']
default: 'On'
ttl_ipset:
description: 'Enable TTL + IP_SET'
required: true
type: choice
options: ['On', 'Off']
default: 'On'
unicode_fix:
description: 'Enable Unicode fix'
required: true
type: choice
options: ['On', 'Off']
default: 'On'
ntsync:
description: 'Enable NTSync'
required: true
type: choice
options: ['On', 'Off']
default: 'On'
stock_mimic:
description: 'Use stock-like OP13 UTS suffix'
required: true
type: choice
options: ['On', 'Off']
default: 'On'
BUILD_TIME:
description: 'Kernel build timestamp. Use F for current UTC time.'
required: false
default: 'F'
clean_build:
description: 'Clean build without ccache'
required: true
type: boolean
default: false
debug_artifacts:
description: 'Upload debug artifacts when available'
required: true
type: boolean
default: true
concurrency:
group: ox-op13-ksun-cctv18-susfs-v61-${{ github.ref }}
cancel-in-progress: false
env:
DEVICE_MODEL: OP13
DEVICE_CODENAME: sun
TARGET_OS: OOS16
ANDROID_VERSION: android15
KERNEL_VERSION: '6.6'
EXPECTED_UTS: '6.6.89-android15-8-g7e1f3c083cc6-abogki467167594-4k'
STOCK_UNAME_SUFFIX: '8-g7e1f3c083cc6-abogki467167594-4k'
ENGINE_REPO: WildKernels/OnePlus_KernelSU_SUSFS
ENGINE_REF: '14d04c1ed0753280330ccabd773e903f76c9a038'
# This is the missing part from previous broken wrappers:
# old build action clones kernel_patches live from main, which drifted after v2.1.0-r2.
# Pinning this restores the patchset used for KSUN 33129 + SUSFS v2.1.0.
ENGINE_KERNEL_PATCHES_REF: '6ac23b65150f5f505018403361779fa7a8a728b0'
DEFAULT_KSUN_REF: '551ad80473f60e052917aec08abf5323b6ab2f7c'
DEFAULT_SUSFS_REF: 'oki-android15-6.6'
jobs:
build:
name: OX OP13 KSUN CCTV18 SUSFS experimental
runs-on: ubuntu-latest
timeout-minutes: 360
steps:
- name: 01 Checkout pinned KSUN build engine
uses: actions/checkout@v4
with:
repository: ${{ env.ENGINE_REPO }}
ref: ${{ env.ENGINE_REF }}
fetch-depth: 1
- name: 02 Preflight and explain pinned stack
shell: bash
run: |
set -euo pipefail
echo "Workspace: $GITHUB_WORKSPACE"
echo "Build engine commit: $(git rev-parse HEAD)"
echo "Pinned patchset ref: $ENGINE_KERNEL_PATCHES_REF"
test -f .github/actions/action.yml
test -f configs/oos16/OP13.json
test -f manifests/oos16/oneplus_13_w.xml
echo "== Top level =="
find . -maxdepth 2 -type d | sort | sed 's#^./# #' | head -80
- name: 03 Patch build engine to use the matching v2.1.0-r2 kernel_patches tree
shell: bash
run: |
set -euo pipefail
ACTION_FILE='.github/actions/action.yml'
echo "Before patch, kernel_patches clone lines:"
grep -nE 'kernel_patches|TheWildJames/kernel_patches|WildKernels/kernel_patches' "$ACTION_FILE" || true
python3 - <<'PY'
from pathlib import Path
p = Path('.github/actions/action.yml')
text = p.read_text()
def replace_shell_line(text: str, needle: str, replacement_lines: list[str], label: str) -> str:
out = []
count = 0
for line in text.splitlines():
if needle in line:
indent = line[:len(line) - len(line.lstrip())]
out.extend(indent + repl for repl in replacement_lines)
count += 1
else:
out.append(line)
if count != 1:
raise SystemExit(f'Expected to replace exactly one {label} line, replaced {count}. Action layout changed.')
return '\n'.join(out) + '\n'
text = replace_shell_line(
text,
'retry_clone "https://github.com/TheWildJames/kernel_patches.git"',
[
'echo "Pinning matching kernel_patches tree for KSUN 33129 + SUSFS v2.1.0"',
'rm -rf kernel_patches',
'git clone --no-tags --depth 1 https://github.com/WildKernels/kernel_patches.git kernel_patches',
'( cd kernel_patches && git fetch --no-tags --depth=1 origin "$ENGINE_KERNEL_PATCHES_REF" && git checkout --force "$ENGINE_KERNEL_PATCHES_REF" )',
'echo "✅ kernel_patches pinned to $(git -C kernel_patches rev-parse HEAD)"',
],
'kernel_patches clone',
)
p.write_text(text)
PY
echo "After patch, kernel_patches clone lines:"
grep -nE 'kernel_patches|TheWildJames/kernel_patches|WildKernels/kernel_patches|6ac23b6' "$ACTION_FILE" || true
echo "Patching SUSFS source to CCTV18 susfs4oki for experimental KSUN test..."
python3 - <<'INNERPY'
from pathlib import Path
p = Path('.github/actions/action.yml')
text = p.read_text()
def replace_shell_line(text: str, needle: str, replacement_lines: list[str], label: str) -> str:
out = []
count = 0
for line in text.splitlines():
if needle in line:
indent = line[:len(line) - len(line.lstrip())]
out.extend(indent + repl for repl in replacement_lines)
count += 1
else:
out.append(line)
if count != 1:
raise SystemExit(f'Expected to replace exactly one {label} line, replaced {count}. Action layout changed.')
return '\n'.join(out) + '\n'
text = replace_shell_line(
text,
'retry_clone "https://gitlab.com/simonpunk/susfs4ksu.git" "master" 0',
[
'echo "Using CCTV18 susfs4oki source for SUSFS"',
'rm -rf susfs4ksu',
'if git ls-remote --heads https://github.com/cctv18/susfs4oki.git "$SUSFS_BRANCH" | grep -q .; then',
' git clone --depth 1 --branch "$SUSFS_BRANCH" https://github.com/cctv18/susfs4oki.git susfs4ksu',
'else',
' git clone https://github.com/cctv18/susfs4oki.git susfs4ksu',
' ( cd susfs4ksu && git checkout --force "$SUSFS_BRANCH" )',
'fi',
'echo "✅ CCTV18 SUSFS source: $(git -C susfs4ksu rev-parse --short HEAD)"',
],
'SUSFS clone',
)
p.write_text(text)
INNERPY
grep -nE 'susfs4oki|susfs4ksu.git|Using CCTV18' "$ACTION_FILE" || true
- name: 04 Install host tools
shell: bash
run: |
set -euo pipefail
sudo apt-get -o Acquire::Retries=3 update -qq
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
git curl ca-certificates build-essential clang lld flex bison \
libelf-dev libssl-dev libncurses-dev zlib1g-dev liblz4-tool \
libxml2-utils rsync unzip zip dwarves file python3 ccache jq bc dos2unix kmod libdw-dev
sudo apt-get clean
- name: 05 Resolve build timestamp
id: time
shell: bash
run: |
set -euo pipefail
IN='${{ inputs.BUILD_TIME }}'
if [ -z "$IN" ]; then
OUT=''
elif [ "$IN" = 'F' ]; then
OUT="$(date -u '+%a %b %d %H:%M:%S UTC %Y')"
else
OUT="$IN"
fi
echo "build_time=$OUT" >> "$GITHUB_OUTPUT"
echo "Resolved BUILD_TIME: ${OUT:-<engine default>}"
- name: 06 Prepare OP13 config JSON
id: config
shell: bash
env:
PROFILE: ${{ inputs.feature_profile }}
SUSFS_IN: ${{ inputs.susfs }}
HMBIRD_IN: ${{ inputs.hmbird }}
DS_IN: ${{ inputs.droidspaces }}
BBR_IN: ${{ inputs.bbr }}
BBG_IN: ${{ inputs.bbg }}
TTL_IN: ${{ inputs.ttl_ipset }}
UNICODE_IN: ${{ inputs.unicode_fix }}
NTSYNC_IN: ${{ inputs.ntsync }}
STOCK_IN: ${{ inputs.stock_mimic }}
run: |
set -euo pipefail
base='configs/oos16/OP13.json'
test -f "$base"
profile_hmbird=false
profile_ds=false
case "$PROFILE" in
release_match|advanced_daily) profile_hmbird=true; profile_ds=true ;;
battery_daily|minimal_debug) profile_hmbird=false; profile_ds=false ;;
*) echo "::error::Unknown profile: $PROFILE"; exit 1 ;;
esac
choose_bool() {
local value="$1"
local auto_default="$2"
case "$value" in
On) echo true ;;
Off) echo false ;;
Auto) echo "$auto_default" ;;
*) echo "::error::Bad boolean choice: $value"; exit 1 ;;
esac
}
hmbird_bool="$(choose_bool "$HMBIRD_IN" "$profile_hmbird")"
ds_bool="$(choose_bool "$DS_IN" "$profile_ds")"
susfs_bool="$(choose_bool "$SUSFS_IN" true)"
bbr_bool="$(choose_bool "$BBR_IN" true)"
bbg_bool="$(choose_bool "$BBG_IN" true)"
ttl_bool="$(choose_bool "$TTL_IN" true)"
unicode_bool="$(choose_bool "$UNICODE_IN" true)"
ntsync_bool="$(choose_bool "$NTSYNC_IN" true)"
if [ "$STOCK_IN" = 'On' ]; then
uname_suffix="$STOCK_UNAME_SUFFIX"
else
uname_suffix='ox1d3x3-ksun'
fi
jq -c \
--argjson hmbird "$hmbird_bool" \
--argjson ds "$ds_bool" \
--argjson susfs "$susfs_bool" \
--argjson bbr "$bbr_bool" \
--argjson bbg "$bbg_bool" \
--argjson ttl "$ttl_bool" \
--argjson ipset "$ttl_bool" \
--argjson unicode "$unicode_bool" \
--argjson ntsync "$ntsync_bool" \
--arg uname "$uname_suffix" \
'.hmbird=$hmbird | .ds=$ds | .susfs=$susfs | .bbr=$bbr | .bbg=$bbg | .ttl=$ttl | .ip_set=$ipset | .unicode=$unicode | .ntsync=$ntsync | .uname=$uname' \
"$base" > /tmp/op13_config.json
echo "Prepared config:"
jq '.' /tmp/op13_config.json
echo "config_json=$(cat /tmp/op13_config.json)" >> "$GITHUB_OUTPUT"
- name: 07 Build OP13 KSUN + SUSFS
id: build
uses: ./.github/actions
with:
op_config_json: ${{ steps.config.outputs.config_json }}
ksu_type: KSUN
ksu_branch_or_hash: ${{ inputs.ksun_ref }}
susfs_commit_hash_or_branch: ${{ inputs.susfs_ref }}
optimize_level: ${{ inputs.optimize_level }}
build_timestamp: ${{ steps.time.outputs.build_time }}
clean: ${{ inputs.clean_build }}
- name: 08 Inject OX installer branding
if: ${{ steps.build.outcome == 'success' }}
shell: bash
run: |
set -euo pipefail
zip_path="$(find OP13/artifacts -maxdepth 1 -type f -name '*.zip' -print -quit 2>/dev/null || true)"
if [ -z "$zip_path" ]; then
echo "::error::No AK3 zip found for branding injection."
exit 1
fi
echo "Branding AK3 zip: $zip_path"
work="$(mktemp -d)"
unzip -q "$zip_path" -d "$work"
cat > "$work/banner" <<'EOF'
____ __ _____ ______ ____
/ __ \_ __ / / |__ /____/ / __ \ / __ \
/ / / / |/_// / /_ </ __ / /_/ / / / / /
/ /_/ /> < / / ___/ / /_/ / _, _/ / /_/ /
\____/_/|_/_/ /____/\__,_/_/ |_| \____/
OX1D3X3 OP13 KSUN + SUSFS Daily Driver
EOF
cat > "$work/INSTALL_INFO.txt" <<EOF
OX1D3X3 OP13 KSUN + SUSFS Daily Driver
Device : OnePlus 13 / OP13 / sun / OOS16 / android15-6.6
Root backend : KernelSU Next / KSUN
SUSFS stack : CCTV18 susfs4oki experimental SUSFS
KSU ref : ${{ inputs.ksun_ref }}
SUSFS ref : ${{ inputs.susfs_ref }}
Profile : ${{ inputs.feature_profile }}
Optimisation : ${{ inputs.optimize_level }}
Stock mimic : ${{ inputs.stock_mimic }}
Build time : ${{ steps.time.outputs.build_time }}
Daily-driver notes:
- battery_daily keeps HMBIRD and Droidspaces off through Auto defaults.
- release_match mirrors the proven KSUN/SUSFS release feature set.
- Keep a stock boot image ready before testing any custom kernel.
- Test LSPosed, susfs4ksu, Microsoft Authenticator, camera, Play Store, calls, Wi-Fi, mobile data and overnight drain.
EOF
if [ -f "$work/anykernel.sh" ] && ! grep -q 'OX1D3X3 OP13 KSUN' "$work/anykernel.sh"; then
awk '
{ print }
$0 == ". tools/ak3-core.sh" {
print "";
print "# OX installer branding";
print "ui_print \" \"";
print "ui_print \"╔══════════════════════════════════════╗\"";
print "ui_print \"║ OX1D3X3 OP13 KSUN + CCTV18 SUSFS ║\"";
print "ui_print \"║ Experimental SUSFS compatibility build ║\"";
print "ui_print \"╚══════════════════════════════════════╝\"";
print "ui_print \" \"";
print "ui_print \"Device : OnePlus 13 / OP13 / OOS16\"";
print "ui_print \"Root : KernelSU Next\"";
print "ui_print \"SUSFS : CCTV18 susfs4oki experimental\"";
print "ui_print \" \"";
}
' "$work/anykernel.sh" > "$work/anykernel.sh.ox"
mv "$work/anykernel.sh.ox" "$work/anykernel.sh"
chmod 0755 "$work/anykernel.sh" || true
fi
tmpzip="${zip_path}.new"
rm -f "$tmpzip"
(cd "$work" && zip -r9 "$tmpzip" . >/dev/null)
mv "$tmpzip" "$zip_path"
rm -rf "$work"
sha256sum "$zip_path" | tee "${zip_path}.sha256"
echo "✅ OX installer branding injected"
- name: 09 Verify output and collect artifact list
if: always()
shell: bash
run: |
set -euo pipefail
echo "Build outcome: ${{ steps.build.outcome }}"
echo "Engine kernel_version output: ${{ steps.build.outputs.kernel_version }}"
echo "KSU version output: ${{ steps.build.outputs.ksu_version }}"
echo "SUSFS version output: ${{ steps.build.outputs.susfs_version }}"
echo "ZIP name output: ${{ steps.build.outputs.zip_name }}"
echo "\nArtifact tree preview:"
find . -maxdepth 7 \( -name '*.zip' -o -name 'Image' -o -name '*.log' -o -name '*.txt' -o -name 'utsrelease.h' \) -printf '%p %s bytes\n' | sort | tail -160 || true
# IMPORTANT:
# The composite build action output named `kernel_version` is the source family
# string such as android15-6.6.89. It is NOT the final Linux UTS_RELEASE.
# Previous v57 incorrectly compared that output with EXPECTED_UTS and failed
# even though the kernel and AK3 zip were created successfully.
actual_uts=""
uts_file=""
candidates=(
"OP13/kernel_platform/common/out/include/generated/utsrelease.h"
"OP13/kernel_platform/common/out/include/generated/compile.h"
"OP13/kernel_platform/common/include/generated/utsrelease.h"
)
for candidate in "${candidates[@]}"; do
if [ -f "$candidate" ]; then
uts_file="$candidate"
break
fi
done
if [ -z "$uts_file" ]; then
uts_file="$(find OP13/kernel_platform/common -path '*/include/generated/utsrelease.h' -print -quit 2>/dev/null || true)"
fi
if [ -n "$uts_file" ] && [ -f "$uts_file" ]; then
echo "Found UTS file: $uts_file"
cat "$uts_file" || true
actual_uts="$(sed -n 's/^#define UTS_RELEASE "\(.*\)"/\1/p' "$uts_file" | head -n1)"
fi
echo "Actual UTS_RELEASE: ${actual_uts:-<not found>}"
echo "Expected stock UTS: $EXPECTED_UTS"
if [ '${{ inputs.stock_mimic }}' = 'On' ] && [ '${{ steps.build.outcome }}' = 'success' ]; then
if [ -n "$actual_uts" ]; then
if [ "$actual_uts" != "$EXPECTED_UTS" ]; then
echo "::warning::Actual UTS_RELEASE differs from expected stock mimic. Expected $EXPECTED_UTS but got $actual_uts"
else
echo "✅ UTS_RELEASE matches stock mimic target."
fi
else
echo "::warning::Could not locate generated utsrelease.h. Not failing because the build action kernel_version output is not UTS_RELEASE."
fi
fi
if [ '${{ steps.build.outcome }}' = 'success' ]; then
zip_path="$(find OP13/artifacts -maxdepth 1 -type f -name '*.zip' -print -quit 2>/dev/null || true)"
if [ -z "$zip_path" ]; then
echo "::error::Build succeeded but no AK3 zip was found under OP13/artifacts."
exit 1
fi
echo "✅ Flashable AK3 zip found: $zip_path"
sha256sum "$zip_path" | tee "${zip_path}.sha256"
fi
- name: 10 Upload kernel artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: OX_OP13_KSUN_CCTV18_SUSFS_EXPERIMENTAL_v61_${{ github.run_number }}
path: |
OP13/artifacts/**
**/*.zip
**/kernel_build_full.log
**/*.rej
if-no-files-found: warn
retention-days: 14
- name: 11 Final build summary
if: always()
shell: bash
run: |
{
echo '## OX OP13 KSUN + CCTV18 SUSFS Experimental v61'
echo ''
echo '| Item | Value |'
echo '|---|---|'
echo "| Status | ${{ job.status }} |"
echo "| Profile | ${{ inputs.feature_profile }} |"
echo "| KSUN ref | ${{ inputs.ksun_ref }} |"
echo "| SUSFS ref | ${{ inputs.susfs_ref }} |"
echo "| Build engine | pinned matched engine |"
echo "| Patchset | pinned KSUN patchset + CCTV18 SUSFS source experiment |"
echo "| Engine kernel_version output | ${{ steps.build.outputs.kernel_version }} |"
echo "| Expected UTS | $EXPECTED_UTS |"
echo "| KSUN version | ${{ steps.build.outputs.ksu_version }} |"
echo "| SUSFS version | ${{ steps.build.outputs.susfs_version }} |"
echo "| ZIP | ${{ steps.build.outputs.zip_name }} |"
} >> "$GITHUB_STEP_SUMMARY"