├── configs ├── oos16 │ ├── OP13.json │ ├── OP11.json │ ├── OP13S.json │ ├── OP13T.json │ ├── OP15.json │ ├── OP-ACE-6.json │ ├── OP-PAD-3.json │ ├── OP12.json │ ├── OP12r.json │ ├── OP13r.json │ ├── OP-ACE-3.json │ ├── OP-OPEN.json │ ├── OP-ACE-3V.json │ ├── OP-ACE-5.json │ ├── OP-NORD-4.json │ ├── OP-NORD-5.json │ ├── OP-PAD-2.json │ ├── OP-ACE-5-PRO.json │ ├── OP-PAD-2-PRO.json │ ├── OP-PAD-PRO.json │ └── OP-ACE-3-PRO.json ├── oos14 │ ├── OP11.json │ ├── OP12.json │ ├── OP11r.json │ ├── OP10pro.json │ ├── OP-PAD-PRO.json │ └── OP-ACE-3-PRO.json └── oos15 │ ├── OP11.json │ ├── OP13S.json │ ├── OP13T.json │ ├── OP-PAD-3.json │ ├── OP10t.json │ ├── OP11r.json │ ├── OP12.json │ ├── OP12r.json │ ├── OP13-PJZ.json │ ├── OP13r.json │ ├── OP-ACE-2.json │ ├── OP-ACE-3.json │ ├── OP-OPEN.json │ ├── OP10pro.json │ ├── OP13-CPH.json │ ├── OP-ACE-3V.json │ ├── OP-ACE-5.json │ ├── OP-NORD-4.json │ ├── OP-NORD-5.json │ ├── OP-PAD-2.json │ ├── OP-ACE-5-PRO.json │ ├── OP-NORD-4-CE.json │ ├── OP-PAD-2-PRO.json │ ├── OP-PAD-PRO.json │ ├── OP-ACE-2-PRO.json │ ├── OP-ACE-3-PRO.json │ └── OP-NORD-CE4-LITE.json ├── manifests ├── oos14 │ ├── oneplus_11r_u.xml │ ├── oneplus_11_u.xml │ ├── oneplus_12_u.xml │ ├── oneplus_ace3_pro_u.xml │ ├── oneplus_pad_pro_u.xml │ └── oneplus_10_pro_u.xml ├── oos15 │ ├── oneplus_10_pro_v.xml │ ├── oneplus_ace2_v.xml │ ├── oneplus_10t_v.xml │ ├── oneplus_11r_v.xml │ ├── oneplus_11_v.xml │ ├── oneplus_ace3_v.xml │ ├── oneplus_12r_v.xml │ ├── oneplus_ace2_pro_v.xml │ ├── oneplus_nord_ce4_v.xml │ ├── oneplus_open_v.xml │ ├── oneplus_ace_3v_v.xml │ ├── oneplus_nord_4_v.xml │ ├── oneplus_nord_5_v.xml │ ├── oneplus_ace3_pro_v.xml │ ├── oneplus_pad2_v.xml │ ├── oneplus_13r_v.xml │ ├── oneplus_ace5_v.xml │ ├── oneplus_nord_ce4_lite_5g_v.xml │ ├── oneplus_pad_pro_v.xml │ ├── oneplus_12_v.xml │ ├── oneplus_pad_3_v.xml │ ├── oneplus_13_v.xml │ ├── oneplus_13s_v.xml │ ├── oneplus_13t_v.xml │ ├── oneplus_pad_2_pro_v.xml │ ├── oneplus_ace5_pro_v.xml │ └── oneplus_13_global_v.xml └── oos16 │ ├── oneplus_11_w.xml │ ├── oneplus_ace3_w.xml │ ├── oneplus_12r_w.xml │ ├── oneplus_open_w.xml │ ├── oneplus_ace_3v_w.xml │ ├── oneplus_nord_4_w.xml │ ├── oneplus_nord_5_w.xml │ ├── oneplus_pad2_w.xml │ ├── oneplus_ace5_w.xml │ ├── oneplus_pad_pro_w.xml │ ├── oneplus_13r_w.xml │ ├── oneplus_ace3_pro_w.xml │ ├── oneplus_12_w.xml │ ├── oneplus_ace_6_w.xml │ ├── oneplus_pad_3_w.xml │ ├── oneplus_13_w.xml │ ├── oneplus_13s_w.xml │ ├── oneplus_13t_w.xml │ ├── oneplus_pad_2_pro_w.xml │ ├── oneplus_ace5_pro_w.xml │ └── oneplus_15_w.xml ├── compatibility.md ├── README.md └── .github └── workflows ├── build-kernel-release.yml └── clean-up.yml /configs/oos16/OP13.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP13", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_13_w.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos14/OP11.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP11", 3 | "soc": "kalama", 4 | "branch": "wild/sm8550", 5 | "manifest": "oneplus_11_u.xml", 6 | "android_version": "android13", 7 | "kernel_version": "5.15", 8 | "os_version": "OOS14", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": true, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos14/OP12.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP12", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_12_u.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS14", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": true, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP11.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP11", 3 | "soc": "kalama", 4 | "branch": "wild/sm8550", 5 | "manifest": "oneplus_11_v.xml", 6 | "android_version": "android13", 7 | "kernel_version": "5.15", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP13S.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP13S", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_13s_v.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP13T.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP13T", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_13t_v.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP11.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP11", 3 | "soc": "kalama", 4 | "branch": "wild/sm8550", 5 | "manifest": "oneplus_11_w.xml", 6 | "android_version": "android13", 7 | "kernel_version": "5.15", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP13S.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP13S", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_13s_w.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP13T.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP13T", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_13t_w.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP15.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP15", 3 | "soc": "canoe", 4 | "branch": "wild/sm8850", 5 | "manifest": "oneplus_15_w.xml", 6 | "android_version": "android16", 7 | "kernel_version": "6.12", 8 | "os_version": "OOS16", 9 | "lto": "none", 10 | "rust_build": true, 11 | "disk_cleanup": true, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos14/OP11r.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP11r", 3 | "soc": "waipio", 4 | "branch": "wild/sm8475", 5 | "manifest": "oneplus_11r_u.xml", 6 | "android_version": "android12", 7 | "kernel_version": "5.10", 8 | "os_version": "OOS14", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": true, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-PAD-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-PAD-3", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_pad_3_v.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP10t.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP10t", 3 | "soc": "waipio", 4 | "branch": "wild/sm8475", 5 | "manifest": "oneplus_10t_v.xml", 6 | "android_version": "android12", 7 | "kernel_version": "5.10", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP11r.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP11r", 3 | "soc": "waipio", 4 | "branch": "wild/sm8475", 5 | "manifest": "oneplus_11r_v.xml", 6 | "android_version": "android12", 7 | "kernel_version": "5.10", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP12.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP12", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_12_v.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP12r.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP12r", 3 | "soc": "kalama", 4 | "branch": "wild/sm8550", 5 | "manifest": "oneplus_12r_v.xml", 6 | "android_version": "android13", 7 | "kernel_version": "5.15", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP13-PJZ.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP13-PJZ", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_13_v.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP13r.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP13r", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_13r_v.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-ACE-6.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-6", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_ace_6_w.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-PAD-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-PAD-3", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_pad_3_w.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP12.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP12", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_12_w.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP12r.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP12r", 3 | "soc": "kalama", 4 | "branch": "wild/sm8550", 5 | "manifest": "oneplus_12r_w.xml", 6 | "android_version": "android13", 7 | "kernel_version": "5.15", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP13r.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP13r", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_13r_w.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos14/OP10pro.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP10pro", 3 | "soc": "waipio", 4 | "branch": "wild/sm8450", 5 | "manifest": "oneplus_10_pro_u.xml", 6 | "android_version": "android12", 7 | "kernel_version": "5.10", 8 | "os_version": "OOS14", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": true, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-ACE-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-2", 3 | "soc": "waipio", 4 | "branch": "wild/sm8475", 5 | "manifest": "oneplus_ace2_v.xml", 6 | "android_version": "android12", 7 | "kernel_version": "5.10", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-ACE-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-3", 3 | "soc": "kalama", 4 | "branch": "wild/sm8550", 5 | "manifest": "oneplus_ace3_v.xml", 6 | "android_version": "android13", 7 | "kernel_version": "5.15", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-OPEN.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-OPEN", 3 | "soc": "kalama", 4 | "branch": "wild/sm8550", 5 | "manifest": "oneplus_open_v.xml", 6 | "android_version": "android13", 7 | "kernel_version": "5.15", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP10pro.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP10pro", 3 | "soc": "waipio", 4 | "branch": "wild/sm8450", 5 | "manifest": "oneplus_10_pro_v.xml", 6 | "android_version": "android12", 7 | "kernel_version": "5.10", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP13-CPH.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP13-CPH", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_13_global_v.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-ACE-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-3", 3 | "soc": "kalama", 4 | "branch": "wild/sm8550", 5 | "manifest": "oneplus_ace3_w.xml", 6 | "android_version": "android13", 7 | "kernel_version": "5.15", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-OPEN.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-OPEN", 3 | "soc": "kalama", 4 | "branch": "wild/sm8550", 5 | "manifest": "oneplus_open_w.xml", 6 | "android_version": "android13", 7 | "kernel_version": "5.15", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-ACE-3V.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-3V", 3 | "soc": "pineapple", 4 | "branch": "wild/sm7675", 5 | "manifest": "oneplus_ace_3v_v.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-ACE-5.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-5", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_ace5_v.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-NORD-4.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-NORD-4", 3 | "soc": "pineapple", 4 | "branch": "wild/sm7675", 5 | "manifest": "oneplus_nord_4_v.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-NORD-5.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-NORD-5", 3 | "soc": "cliffs", 4 | "branch": "wild/sm8635", 5 | "manifest": "oneplus_nord_5_v.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-PAD-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-PAD-2", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_pad2_v.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-ACE-3V.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-3V", 3 | "soc": "pineapple", 4 | "branch": "wild/sm7675", 5 | "manifest": "oneplus_ace_3v_w.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-ACE-5.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-5", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_ace5_w.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-NORD-4.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-NORD-4", 3 | "soc": "pineapple", 4 | "branch": "wild/sm7675", 5 | "manifest": "oneplus_nord_4_w.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-NORD-5.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-NORD-5", 3 | "soc": "cliffs", 4 | "branch": "wild/sm8635", 5 | "manifest": "oneplus_nord_5_w.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-PAD-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-PAD-2", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_pad2_w.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos14/OP-PAD-PRO.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-PAD-PRO", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_pad_pro_u.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS14", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": true, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-ACE-5-PRO.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-5-PRO", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_ace5_pro_v.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-NORD-4-CE.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-NORD-4-CE", 3 | "soc": "crow", 4 | "branch": "wild/sm7550", 5 | "manifest": "oneplus_nord_ce4_v.xml", 6 | "android_version": "android13", 7 | "kernel_version": "5.15", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-PAD-2-PRO.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-PAD-2-PRO", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_pad_2_pro_v.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-PAD-PRO.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-PAD-PRO", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_pad_pro_v.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-ACE-5-PRO.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-5-PRO", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_ace5_pro_w.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-PAD-2-PRO.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-PAD-2-PRO", 3 | "soc": "sun", 4 | "branch": "wild/sm8750", 5 | "manifest": "oneplus_pad_2_pro_w.xml", 6 | "android_version": "android15", 7 | "kernel_version": "6.6", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": true, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-PAD-PRO.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-PAD-PRO", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_pad_pro_w.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos14/OP-ACE-3-PRO.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-3-PRO", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_ace3_pro_u.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS14", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": true, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-ACE-2-PRO.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-2-PRO", 3 | "soc": "kalama", 4 | "branch": "wild/sm8550", 5 | "manifest": "oneplus_ace2_pro_v.xml", 6 | "android_version": "android13", 7 | "kernel_version": "5.15", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-ACE-3-PRO.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-3-PRO", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_ace3_pro_v.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos16/OP-ACE-3-PRO.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-ACE-3-PRO", 3 | "soc": "pineapple", 4 | "branch": "wild/sm8650", 5 | "manifest": "oneplus_ace3_pro_w.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS16", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /configs/oos15/OP-NORD-CE4-LITE.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": "OP-NORD-CE4-LITE", 3 | "soc": "blair", 4 | "branch": "wild/sm6375", 5 | "manifest": "oneplus_nord_ce4_lite_5g_v.xml", 6 | "android_version": "android14", 7 | "kernel_version": "6.1", 8 | "os_version": "OOS15", 9 | "lto": "thin", 10 | "rust_build": false, 11 | "disk_cleanup": false, 12 | "hmbird": false, 13 | "susfs": true, 14 | "bbg": true, 15 | "bbr": true, 16 | "ttl": true, 17 | "ip_set": true 18 | } 19 | -------------------------------------------------------------------------------- /manifests/oos14/oneplus_11r_u.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /manifests/oos14/oneplus_11_u.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /manifests/oos14/oneplus_12_u.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /manifests/oos14/oneplus_ace3_pro_u.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /manifests/oos14/oneplus_pad_pro_u.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /manifests/oos14/oneplus_10_pro_u.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_10_pro_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_ace2_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_10t_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_11r_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_11_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_ace3_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_11_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_ace3_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_12r_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_ace2_pro_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_nord_ce4_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_open_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_12r_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_open_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_ace_3v_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_nord_4_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_nord_5_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_ace_3v_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_nord_4_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_nord_5_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_pad2_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_ace5_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_ace3_pro_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_pad2_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_pad_pro_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_13r_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_13r_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_ace3_pro_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_ace5_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_nord_ce4_lite_5g_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_pad_pro_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_12_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_12_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_pad_3_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_ace_6_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_pad_3_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_13_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_13s_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_13_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_13t_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_pad_2_pro_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_13s_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_13t_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_pad_2_pro_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_ace5_pro_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_ace5_pro_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos15/oneplus_13_global_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifests/oos16/oneplus_15_w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /compatibility.md: -------------------------------------------------------------------------------- 1 | # Compatibility of OnePlus Kernels 2 | ## 1. OnePlus Devices 3 | 4 | 5 | 6 | 7 | 8 | 9 |
:warning: All the Kernels are built on OnePlus Official Source and are expected to work only on Stock roms!!!
10 | 11 | - Currently All the kernels are built from Android 15 Manifest. 12 | - Do not use the zips after Major Android OTA (a15 -> a16) unless its verified in Wild_Kernels Telegram group or other sources like XDA. 13 | 14 | ## 2. Non-OnePlus Devices 15 | ### List of verified devices 16 | 17 | 18 | 19 | 20 | 21 |
:warning: We expect all users who wants to test OnePlus Kernels on Non-OnePlus Phones to first disable dm-verity and verification using fastboot or other means.
22 | 23 | - If your device is not in list, please select the device which is most similar and matches the kernel version (androidXX-YY.ZZ.AAA). AAA must be atleast same or greater. XX-YY.ZZ must match exactly. More Information on this can be read @KernelSU.org. 24 | - Thanks to our community users at Wild_Kernels for helping us compile the list. 25 | - We request more users come forward help us keep the list updated. 26 | - I'm sure more devices from other brands are also supported. 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
Device Name Working Kernel Device Name Current Kernel Version
Poco X7 Pro
Realme GT 7 Pro
OnePlus 13
OnePlus Ace 5 Pro
android15-6.6.89
android15-6.6.89
Realme GT Neo 5SE
Realme GT Neo 5
OnePlus 10T
OnePlus 10 Pro
OnePlus Ace 2
OnePlus 11r (Partially)
android12-5.10.226
android12-5.10.226
android12-5.10.226
android12-5.10.209
Realme GT 5 OnePlus 11 android13-5.15.167
Realme GT Neo 6SE
Realme GT Neo 6T
OnePlus Nord 4 android14-6.1.118
Realme GT 2 Pro OnePlus 10 Pro android12-5.10.226
59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Wild Kernels for Android 2 | 3 | ## Your warranty is no longer valid! 4 | 5 | I am **not responsible** for bricked devices, damaged hardware, or any issues that arise from using this kernel. 6 | 7 | **Please** do thorough research and fully understand the features included in this kernel before flashing it! 8 | 9 | By flashing this kernel, **YOU** are choosing to make these modifications. If something goes wrong, **do not blame me**! 10 | 11 | --- 12 | 13 | ### Proceed at your own risk! 14 | 15 | 16 | 17 | 18 | 19 | 20 |
:warning: Verify Compatibility of kernels before flashing.
21 | 22 | --- 23 | 24 | # Kernels: 25 | 26 | [GKI](https://github.com/WildKernels/GKI_KernelSU_SUSFS) 27 | [Sultan](https://github.com/WildKernels/Sultan_KernelSU_SUSFS) 28 | [OnePlus](https://github.com/WildKernels/OnePlus_KernelSU_SUSFS) 29 | [Legacy Pixels](https://github.com/WildKernels/Pixel_KernelSU_SUSFS) 30 | 31 | --- 32 | 33 | # Other Links: 34 | 35 | [Kernel Patches](https://github.com/WildKernels/kernel_patches) 36 | [Old Build Scripts](https://github.com/TheWildJames/kernel_build_scripts) 37 | [Kernel Flasher - fatalcoder524 fork](https://github.com/fatalcoder524/KernelFlasher) 38 | [Horizon Kernel Flasher](https://github.com/libxzr/HorizonKernelFlasher) 39 | 40 | --- 41 | 42 | # Installation instructions: 43 | 44 | Follow the steps for GKI: 45 | [Installation](https://kernelsu.org/guide/installation.html) 46 | 47 | To get boot.img format: 48 | [Get My Kernel Format](https://github.com/TheWildJames/Get_My_Kernel_Format) 49 | 50 | --- 51 | 52 | # Features 53 | 54 | - **KernelSU**: KernelSU is a root solution for Android GKI devices, it works in kernel mode and grants root permission to userspace applications directly in kernel space. 55 | - **SUSFS**: An addon root hiding kernel patches and userspace module for KernelSU. 56 | 57 | --- 58 | 59 | # Credits 60 | 61 | - **KernelSU**: Developed by [tiann](https://github.com/tiann/KernelSU). 62 | - **KernelSU-Next**: Developed by [rifsxd](https://github.com/KernelSU-Next/KernelSU-Next). 63 | - **Magic-KSU**: Developed by [5ec1cff](https://github.com/5ec1cff/KernelSU). 64 | - **SUSFS**: Developed by [simonpunk](https://gitlab.com/simonpunk/susfs4ksu.git). 65 | - **SUSFS Module**: Developed by [sidex15](https://github.com/sidex15). 66 | - **Sultan Kernels**: Developed by [kerneltoast](https://github.com/kerneltoast). 67 | 68 | Special thanks to the open-source community for their contributions! 69 | 70 | --- 71 | 72 | # Support 73 | 74 | If you encounter any issues or need help, feel free to open an issue in this repository or reach out to me. 75 | 76 | --- 77 | 78 | # Disclaimer 79 | 80 | Flashing this kernel will void your warranty, and there is always a risk of bricking your device. Please make sure to back up your data and ensure you understand the risks before proceeding. 81 | 82 | **Proceed at your own risk!** 83 | 84 | --- 85 | 86 | [Telegram](https://t.me/TheWildJames) 87 | [Telegram Group](https://t.me/WildKernels) 88 | 89 | # Special thanks to the following people for their contributions! 90 | This helps me alot! <3 91 | 92 | [simonpunk](https://gitlab.com/simonpunk/susfs4ksu.git) - Created SUSFS! 93 | [sidex15](https://github.com/sidex15) - Created module! 94 | [backslashxx](https://github.com/backslashxx) - Helped with patches! 95 | [Teemo](https://github.com/liqideqq) - Helped with patches! 96 | [幕落](https://github.com/MuLuo688) - Donation! 97 | 98 | If you have contributed and are not here please remind me! 99 | -------------------------------------------------------------------------------- /.github/workflows/build-kernel-release.yml: -------------------------------------------------------------------------------- 1 | name: Build and Release OnePlus Kernels 2 | 3 | permissions: 4 | contents: write 5 | actions: write 6 | 7 | on: 8 | workflow_dispatch: 9 | inputs: 10 | make_release: 11 | description: 'Do you want to create a release?' 12 | required: true 13 | type: boolean 14 | default: false 15 | op_model: 16 | description: 'Select the OnePlus kernels to build' 17 | required: true 18 | type: choice 19 | options: 20 | - OOS14+15+16 21 | - OOS15+16 22 | - OOS14+15 23 | - OOS16 24 | - OOS15 25 | - OOS14 26 | - android16-6.12 27 | - android15-6.6 28 | - android14-6.1 29 | - android13-5.15 30 | - android12-5.10 31 | default: OOS14+15+16 32 | ksu_options: 33 | description: 'Enter KernelSU build json' 34 | required: true 35 | type: string 36 | default: '[{"type":"ksun","hash":"dev"}]' 37 | optimize_level: 38 | description: "Compiler optimization level" 39 | required: true 40 | type: choice 41 | options: [O2, O3] 42 | default: O2 43 | clean_build: 44 | description: 'Clean build (no ccache)' 45 | type: boolean 46 | default: false 47 | android12-5_10_susfs_branch_or_commit: 48 | description: 'Enter SusFS Branch or commit hash for android12-5.10' 49 | type: string 50 | default: '' 51 | android13-5_15_susfs_branch_or_commit: 52 | description: 'Enter SusFS Branch or commit hash for android13-5.15' 53 | type: string 54 | default: '' 55 | android14-6_1_susfs_branch_or_commit: 56 | description: 'Enter SusFS Branch or commit hash for android14-6.1' 57 | type: string 58 | default: '' 59 | android15-6_6_susfs_branch_or_commit: 60 | description: 'Enter SusFS Branch or commit hash for android15-6.6' 61 | type: string 62 | default: '' 63 | android16-6_12_susfs_branch_or_commit: 64 | description: 'Enter SusFS Branch or commit hash for android16-6.12' 65 | type: string 66 | default: '' 67 | 68 | jobs: 69 | set-op-model: 70 | runs-on: ubuntu-latest 71 | outputs: 72 | matrix: ${{ steps.set-matrix.outputs.matrix }} 73 | device_count: ${{ steps.set-matrix.outputs.count }} 74 | steps: 75 | - name: 📥 Checkout Code (to access configs/) 76 | uses: actions/checkout@v4 77 | with: 78 | sparse-checkout: | 79 | configs/ 80 | sparse-checkout-cone-mode: false 81 | 82 | - name: 🔍 Generate build matrix 83 | id: set-matrix 84 | shell: bash 85 | run: | 86 | set -euo pipefail 87 | echo "::group::Matrix generation" 88 | 89 | input="${{ github.event.inputs.op_model }}" 90 | ksu_options_raw='${{ github.event.inputs.ksu_options }}' 91 | if ! ksu_options_normalized=$(echo "$ksu_options_raw" | jq -c 'map(if .type then .type |= ascii_upcase | if .hash == null then if .type == "KSUN" then .hash = "dev" elif .type == "KSU" then .hash = "main" else .hash end else . end else error("No type found") end)' 2>&1); then 92 | echo "::error::ksu_options validation failed: $ksu_options_normalized" 93 | exit 1 94 | fi 95 | 96 | echo "[" > matrix.json 97 | mapfile -t all_json_files < <(find configs/ -name "*.json" -print0 | xargs -0 -n1) 98 | for i in "${!all_json_files[@]}"; do 99 | file="${all_json_files[$i]}" 100 | if [ -f "$file" ]; then 101 | jq -r '.' "$file" >> matrix.json 102 | if [ $((i+1)) -lt ${#all_json_files[@]} ]; then 103 | echo "," >> matrix.json 104 | fi 105 | fi 106 | done 107 | echo "]" >> matrix.json 108 | 109 | jq_filter="." 110 | 111 | case "$input" in 112 | OOS14+15+16) 113 | ;; 114 | OOS15+16) 115 | jq_filter="map(select(.os_version == \"OOS15\" or .os_version == \"OOS16\"))" 116 | ;; 117 | OOS14+15) 118 | jq_filter="map(select(.os_version == \"OOS14\" or .os_version == \"OOS15\"))" 119 | ;; 120 | OOS16) 121 | jq_filter="map(select(.os_version == \"OOS16\"))" 122 | ;; 123 | OOS15) 124 | jq_filter="map(select(.os_version == \"OOS15\"))" 125 | ;; 126 | OOS14) 127 | jq_filter="map(select(.os_version == \"OOS14\"))" 128 | ;; 129 | android*-*.*) 130 | # Extract android version and kernel version 131 | IFS='-' read -r av kv <<< "$input" 132 | 133 | # Build android*-* only for OOS15 and OOS16 134 | jq_filter="map(select(.os_version == \"OOS15\" or .os_version == \"OOS16\")) | map(select(.android_version == \"$av\" and .kernel_version == \"$kv\"))" 135 | 136 | echo "ℹ️ Android-Kernel filter applied: $av-$kv" 137 | echo " Restricted to: OOS15 and OOS16 only" 138 | ;; 139 | *) 140 | echo "::warning::Unknown input '$input'. Using empty filter." 141 | jq_filter="map(select(false))" 142 | ;; 143 | esac 144 | 145 | filtered=$(jq -c "$jq_filter" matrix.json) 146 | count=$(jq 'length' <<<"$filtered") 147 | 148 | if [ "$count" -eq 0 ]; then 149 | echo "::error::No config files found for input '$input' after applying filters!" 150 | echo "" 151 | echo "Available configurations:" 152 | jq -r '.[] | " - \(.model) (\(.os_version), \(.android_version)-\(.kernel_version))"' matrix.json 153 | exit 1 154 | fi 155 | 156 | # For each device + each ksu option → one combined entry 157 | merged_matrix=$(jq -n --argjson devices "$filtered" --argjson ksu_list "$ksu_options_normalized" '[ $devices[] as $dev | $ksu_list[] as $ksu | ($dev + {ksu_type: $ksu.type, ksu_hash: $ksu.hash}) ]') 158 | 159 | final_count=$(echo "$merged_matrix" | jq -s length) 160 | 161 | wrapped=$(jq -n --argjson items "$merged_matrix" '{ include: $items }') 162 | 163 | echo "✅ Found $final_count device(s) to build" 164 | echo "" 165 | echo "Selected devices:" 166 | jq -r '.[] | " - \(.model) (\(.os_version), \(.android_version)-\(.kernel_version), \(.ksu_type) - \(.ksu_hash))"' <<<"$merged_matrix" 167 | 168 | echo "matrix=$(jq -c . <<< "$wrapped")" >> "$GITHUB_OUTPUT" 169 | echo "count=$count" >> "$GITHUB_OUTPUT" 170 | 171 | echo "::endgroup::" 172 | 173 | - name: Upload build matrix 174 | uses: actions/upload-artifact@v4 175 | with: 176 | name: build-matrix 177 | path: matrix.json 178 | retention-days: 1 179 | 180 | - name: 📊 Build plan summary 181 | run: | 182 | ksu_options_raw='${{ github.event.inputs.ksu_options }}' 183 | ksu_options_normalized=$(echo "$ksu_options_raw" | jq -c 'map(if .type then .type |= ascii_upcase | if .hash == null then if .type == "KSUN" then .hash = "dev" elif .type == "KSU" then .hash = "main" else .hash end else . end else error("No type found") end)' 2>&1) 184 | 185 | # export KSU_OPTIONS="$ksu_options_normalized" 186 | 187 | # cat >> $GITHUB_STEP_SUMMARY << 'EOF' 188 | # ## 🎯 Build Plan 189 | 190 | # **Target:** `${{ inputs.op_model }}` 191 | # **Devices:** ${{ steps.set-matrix.outputs.count }} 192 | 193 | # **Configuration:** 194 | # - KSU Config: `"$KSU_OPTIONS"` 195 | # - Optimization: `${{ inputs.optimize_level }}` 196 | # - Clean Build/No Ccache: ${{ inputs.clean_build && '✅ Yes' || '❌ No' }} 197 | # - Create Release: ${{ inputs.make_release && '✅ Yes' || '❌ No' }} 198 | 199 | # **SUSFS Configuration:** 200 | # EOF 201 | 202 | { 203 | cat << 'EOF' 204 | ## 🎯 Build Plan 205 | 206 | **Target:** ${{ inputs.op_model }} 207 | **Devices:** ${{ steps.set-matrix.outputs.count }} 208 | 209 | **Configuration:** 210 | - KSU Config: ` 211 | EOF 212 | 213 | # Inject the shell variable 214 | printf '%s' "$ksu_options_normalized" 215 | 216 | cat << 'EOF' 217 | ` 218 | - Optimization: ${{ inputs.optimize_level }} 219 | - Clean Build/No Ccache: ${{ inputs.clean_build && '✅ Yes' || '❌ No' }} 220 | - Create Release: ${{ inputs.make_release && '✅ Yes' || '❌ No' }} 221 | 222 | **SUSFS Configuration:** 223 | EOF 224 | } >> "$GITHUB_STEP_SUMMARY" 225 | 226 | # Display SUSFS config for each kernel version 227 | declare -A susfs_inputs=( 228 | ["android12-5.10"]="${{ inputs.android12-5_10_susfs_branch_or_commit }}" 229 | ["android13-5.15"]="${{ inputs.android13-5_15_susfs_branch_or_commit }}" 230 | ["android14-6.1"]="${{ inputs.android14-6_1_susfs_branch_or_commit }}" 231 | ["android15-6.6"]="${{ inputs.android15-6_6_susfs_branch_or_commit }}" 232 | ["android16-6.12"]="${{ inputs.android16-6_12_susfs_branch_or_commit }}" 233 | ) 234 | 235 | for key in "android12-5.10" "android13-5.15" "android14-6.1" "android15-6.6" "android16-6.12"; do 236 | value="${susfs_inputs[$key]}" 237 | 238 | if [ -z "$value" ]; then 239 | echo "- $key: 🔄 auto (\`gki-$key\`)" >> $GITHUB_STEP_SUMMARY 240 | else 241 | echo "- $key: 📌 \`$value\`" >> $GITHUB_STEP_SUMMARY 242 | fi 243 | done 244 | 245 | echo "" >> $GITHUB_STEP_SUMMARY 246 | echo "> **💡 Note:** Empty values auto-map to matching \`gki-androidX-Y.Z\` branches." >> $GITHUB_STEP_SUMMARY 247 | 248 | # Add OOS restriction note for android-kernel filters 249 | if [[ "${{ inputs.op_model }}" == android*-*.* ]]; then 250 | echo "" >> $GITHUB_STEP_SUMMARY 251 | echo "> **⚠️ Android-Kernel Filter:** Only OOS15 and OOS16 devices will be built for \`${{ inputs.op_model }}\`" >> $GITHUB_STEP_SUMMARY 252 | fi 253 | 254 | build: 255 | name: build (${{ matrix.model }}, ${{ matrix.soc }}, ${{ matrix.branch }}, ${{ matrix.manifest }}, ${{ matrix.android_version }}, ${{ matrix.kernel_version }}, ${{ matrix.os_version }}, ${{ matrix.ksu_type }}) 256 | needs: set-op-model 257 | runs-on: ubuntu-latest 258 | strategy: 259 | fail-fast: false 260 | matrix: ${{ fromJSON(needs.set-op-model.outputs.matrix) }} 261 | outputs: 262 | ksun_ver: ${{ steps.build-stat.outputs.ksu_version }} 263 | ksu_ver: ${{ steps.build-stat.outputs.ksu_version }} 264 | steps: 265 | - name: 🧹 Emergency Disk Cleanup 266 | if: ${{ matrix.disk_cleanup }} 267 | run: | 268 | echo "::group::Disk Usage Before Cleanup" 269 | df -h 270 | echo "::endgroup::" 271 | 272 | echo "::group::Removing Unnecessary Software" 273 | sudo rm -rf /usr/share/dotnet 274 | sudo rm -rf /usr/local/lib/android 275 | sudo rm -rf /opt/ghc 276 | sudo rm -rf /opt/hostedtoolcache/CodeQL 277 | sudo apt-get clean 278 | if command -v docker >/dev/null 2>&1; then 279 | docker rmi $(docker images -q) 2>/dev/null || true 280 | fi 281 | echo "::endgroup::" 282 | 283 | echo "::group::Disk Usage After Cleanup" 284 | df -h 285 | AVAIL=$(df -h / | awk 'NR==2 {print $4}') 286 | echo "✅ Available space: $AVAIL" 287 | echo "::endgroup::" 288 | 289 | - name: Download Apache Arrow's util_free_space.sh 290 | if: ${{ matrix.disk_cleanup }} 291 | run: | 292 | curl -L -o util_free_space.sh https://raw.githubusercontent.com/apache/arrow/main/ci/scripts/util_free_space.sh 293 | chmod +x util_free_space.sh 294 | ./util_free_space.sh 295 | 296 | - name: 🔍 Resolve SUSFS branch from inputs 297 | id: susfs 298 | shell: bash 299 | if: ${{ matrix.susfs }} 300 | run: | 301 | set -euo pipefail 302 | 303 | key="${{ matrix.android_version }}-${{ matrix.kernel_version }}" 304 | 305 | echo "Looking up SUSFS branch for: $key" 306 | 307 | # Map kernel version to input value 308 | case "$key" in 309 | "android12-5.10") 310 | susfs_branch="${{ inputs.android12-5_10_susfs_branch_or_commit }}" 311 | ;; 312 | "android13-5.15") 313 | susfs_branch="${{ inputs.android13-5_15_susfs_branch_or_commit }}" 314 | ;; 315 | "android14-6.1") 316 | susfs_branch="${{ inputs.android14-6_1_susfs_branch_or_commit }}" 317 | ;; 318 | "android15-6.6") 319 | susfs_branch="${{ inputs.android15-6_6_susfs_branch_or_commit }}" 320 | ;; 321 | "android16-6.12") 322 | susfs_branch="${{ inputs.android16-6_12_susfs_branch_or_commit }}" 323 | ;; 324 | *) 325 | echo "::error::Unsupported kernel version: $key" 326 | exit 1 327 | ;; 328 | esac 329 | 330 | # If empty, it will be auto-resolved to gki-* branch in the action 331 | if [ -z "$susfs_branch" ]; then 332 | echo "ℹ️ No custom SUSFS branch specified for $key" 333 | echo " Will auto-select: gki-$key" 334 | else 335 | echo "✅ Using custom SUSFS branch for $key: '$susfs_branch'" 336 | fi 337 | 338 | echo "susfs_branch=$susfs_branch" >> "$GITHUB_OUTPUT" 339 | 340 | - name: 📥 Checkout Code 341 | uses: actions/checkout@v4 342 | with: 343 | fetch-depth: 1 344 | 345 | - name: 📦 Disk usage (pre-build) 346 | run: | 347 | echo "::group::Disk usage pre-build" 348 | df -h / 349 | du -sh "$GITHUB_WORKSPACE" 2>/dev/null || true 350 | sudo rm -rf /tmp/* || true 351 | echo "::endgroup::" 352 | 353 | - name: ♻️ Configure ccache (bounded) 354 | if: ${{ inputs.clean_build != true }} 355 | run: | 356 | if command -v ccache >/dev/null 2>&1; then 357 | echo "::group::ccache configuration" 358 | ccache -o max_size=1.0G 359 | ccache -o compression=true 360 | ccache -o compression_level=3 361 | ccache -s 362 | echo "::endgroup::" 363 | fi 364 | 365 | - name: 🧹 Prepare op_config_json (without KSU fields) 366 | id: prepare_config 367 | shell: bash 368 | run: | 369 | echo "config_json=$(jq -nc --argjson m '${{ toJSON(matrix) }}' '$m | del(.ksu_type, .ksu_hash)')" >> "$GITHUB_OUTPUT" 370 | 371 | - name: 🔨 Build Kernel 372 | id: build 373 | uses: ./.github/actions 374 | with: 375 | op_config_json: ${{ steps.prepare_config.outputs.config_json }} 376 | ksu_type: ${{ matrix.ksu_type }} 377 | ksu_branch_or_hash: ${{ matrix.ksu_hash }} 378 | susfs_commit_hash_or_branch: ${{ steps.susfs.outputs.susfs_branch }} 379 | optimize_level: ${{ inputs.optimize_level }} 380 | clean: ${{ inputs.clean_build }} 381 | 382 | - name: 📊 Build statistics 383 | id: build-stat 384 | if: always() 385 | run: | 386 | echo "::group::Build Statistics" 387 | 388 | echo "Device: ${{ matrix.model }}" 389 | echo "OS Version: ${{ matrix.os_version }}" 390 | echo "Kernel: ${{ matrix.android_version }}-${{ matrix.kernel_version }}" 391 | if [ "${{ matrix.susfs }}" = true ]; then 392 | echo "SUSFS Branch: ${{ steps.susfs.outputs.susfs_branch }}" 393 | fi 394 | echo "Status: ${{ job.status }}" 395 | 396 | if [ "${{ steps.build.outcome }}" = "success" ]; then 397 | echo "" 398 | echo "✅ Build completed successfully" 399 | echo "" 400 | echo "Outputs:" 401 | echo " - Kernel: ${{ steps.build.outputs.kernel_version }}" 402 | if [ "${{ matrix.ksu_type }}" = "KSUN" ]; then 403 | echo " - KSU Next: v${{ steps.build.outputs.ksu_version }}" 404 | echo "ksun_ver=${{ steps.build.outputs.ksu_version }}" >> "$GITHUB_OUTPUT" 405 | echo "ksu_ver=" >> "$GITHUB_OUTPUT" 406 | else 407 | echo " - KSU: v${{ steps.build.outputs.ksu_version }}" 408 | echo "ksun_ver=" >> "$GITHUB_OUTPUT" 409 | echo "ksu_ver=${{ steps.build.outputs.ksu_version }}" >> "$GITHUB_OUTPUT" 410 | fi 411 | if [ "${{ matrix.susfs }}" = true ]; then 412 | echo " - SUSFS: ${{ steps.build.outputs.susfs_version }}" 413 | fi 414 | echo " - Build time: ${{ steps.build.outputs.build_time }}s" 415 | 416 | if [ "${{ inputs.clean_build }}" != "true" ]; then 417 | echo " - ccache hit rate: ${{ steps.build.outputs.ccache_hit_rate }}" 418 | echo " - ccache direct rate: ${{ steps.build.outputs.ccache_direct_rate }}" 419 | else 420 | echo " - ccache: disabled (clean build)" 421 | fi 422 | 423 | if [ -n "${{ steps.build.outputs.warnings }}" ]; then 424 | echo " - Warnings: ${{ steps.build.outputs.warnings }}" 425 | fi 426 | else 427 | echo "❌ Build failed" 428 | fi 429 | 430 | echo "::endgroup::" 431 | 432 | - name: 📝 Job summary 433 | if: always() 434 | run: | 435 | cat >> $GITHUB_STEP_SUMMARY << EOF 436 | 437 | ### ${{ matrix.model }} (${{ matrix.os_version }}) - ${{ job.status == 'success' && '✅ Success' || '❌ Failed' }} 438 | 439 | **Kernel:** ${{ matrix.android_version }}-${{ matrix.kernel_version }} 440 | EOF 441 | 442 | if [ "${{ matrix.susfs }}" = true ]; then 443 | cat >> $GITHUB_STEP_SUMMARY << EOF 444 | **SUSFS Branch:** \`${{ steps.susfs.outputs.susfs_branch || format('(auto: gki-{0}-{1})', matrix.android_version, matrix.kernel_version) }}\` 445 | EOF 446 | fi 447 | 448 | if [ "${{ steps.build.outcome }}" = "success" ]; then 449 | cat >> $GITHUB_STEP_SUMMARY << EOF 450 | | Metric | Value | 451 | |--------|-------| 452 | | **Kernel** | ${{ steps.build.outputs.kernel_version }} | 453 | EOF 454 | if [ "${{ matrix.ksu_type }}" = "KSUN" ]; then 455 | cat >> $GITHUB_STEP_SUMMARY << EOF 456 | | **KSU Next** | v${{ steps.build.outputs.ksu_version }} | 457 | EOF 458 | else 459 | cat >> $GITHUB_STEP_SUMMARY << EOF 460 | | **KSU** | v${{ steps.build.outputs.ksu_version }} | 461 | EOF 462 | fi 463 | 464 | if [ "${{ matrix.susfs }}" = true ]; then 465 | cat >> $GITHUB_STEP_SUMMARY << EOF 466 | | **SUSFS** | ${{ steps.build.outputs.susfs_version }} | 467 | EOF 468 | fi 469 | cat >> $GITHUB_STEP_SUMMARY << EOF 470 | | **Build Time** | ${{ steps.build.outputs.build_time }}s | 471 | EOF 472 | 473 | if [ "${{ inputs.clean_build }}" != "true" ]; then 474 | cat >> $GITHUB_STEP_SUMMARY << EOF 475 | | **ccache Hit Rate** | ${{ steps.build.outputs.ccache_hit_rate }} | 476 | | **ccache Direct Rate** | ${{ steps.build.outputs.ccache_direct_rate }} | 477 | EOF 478 | fi 479 | 480 | if [ -n "${{ steps.build.outputs.warnings }}" ]; then 481 | echo "| **Warnings** | ${{ steps.build.outputs.warnings }} |" >> $GITHUB_STEP_SUMMARY 482 | fi 483 | 484 | cat >> $GITHUB_STEP_SUMMARY << EOF 485 | 486 | **SHA256:** \`${{ steps.build.outputs.image_sha256 }}\` 487 | EOF 488 | fi 489 | 490 | - name: 🧹 Final cleanup and space report 491 | if: always() 492 | run: | 493 | echo "::group::Cleanup" 494 | 495 | # Remove build artifacts but PRESERVE ccache 496 | sudo rm -rf "$GITHUB_WORKSPACE/out" || true 497 | sudo rm -rf "$GITHUB_WORKSPACE/build" || true 498 | sudo rm -rf "$GITHUB_WORKSPACE/kernel/out" || true 499 | sudo rm -rf "$GITHUB_WORKSPACE/.repo" || true 500 | sudo rm -rf /tmp/* || true 501 | 502 | # Show ccache stats (don't clear it!) 503 | if command -v ccache >/dev/null 2>&1; then 504 | echo "" 505 | echo "📊 ccache statistics after build:" 506 | ccache -s 507 | echo "" 508 | echo "💾 ccache preserved for next build" 509 | fi 510 | 511 | echo "" 512 | echo "💽 Final disk usage:" 513 | df -h / 514 | 515 | echo "::endgroup::" 516 | 517 | trigger-release: 518 | needs: [build] 519 | runs-on: ubuntu-latest 520 | if: ${{ inputs.make_release }} 521 | env: 522 | REPO_OWNER: ${{ github.repository_owner }} 523 | REPO_NAME: ${{ github.event.repository.name }} 524 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 525 | RELEASE_NAME: '*TEST BUILD* OnePlus Kernels With KernelSU Next & SUSFS v1.5.12 *TEST BUILD*' 526 | SUSFS_BASE_VERSION: 'v2.0.0' 527 | steps: 528 | - name: 📥 Checkout code 529 | uses: actions/checkout@v4 530 | with: 531 | fetch-depth: 0 532 | 533 | - name: 🏷️ Generate and Create New Tag 534 | run: | 535 | BASE_TAG="$SUSFS_BASE_VERSION-r0" 536 | LATEST_TAG=$(gh api repos/$REPO_OWNER/$REPO_NAME/tags --jq '.[0].name') 537 | if [ -z "$LATEST_TAG" ]; then 538 | LATEST_TAG="$BASE_TAG" 539 | else 540 | LATEST_TAG=$(printf "%s\n%s\n" "$LATEST_TAG" "$BASE_TAG" | sort -rV | head -n1) 541 | fi 542 | NEW_TAG=$(echo "$LATEST_TAG" | awk -F'-r' '{suffix=$2; if (!suffix) suffix=0; suffix++; printf "%s-r%d", $1, suffix}') 543 | echo "New tag: $NEW_TAG" 544 | echo "NEW_TAG=${NEW_TAG}" >> $GITHUB_ENV 545 | git tag $NEW_TAG 546 | git push origin $NEW_TAG 547 | 548 | - name: 📥 Download Artifacts 549 | uses: actions/download-artifact@v4 550 | with: 551 | path: ./downloaded-artifacts 552 | 553 | - name: 📝 Generate Device List and Final Release Notes 554 | id: generate-notes 555 | run: | 556 | echo "=== Start building the release notes ===" 557 | 558 | # Collect build metadata 559 | declare -A device_info 560 | 561 | JSON_BUILD_DATA=$(jq -c '.' ./downloaded-artifacts/build-matrix/matrix.json) 562 | 563 | for file in $(find downloaded-artifacts -name "*.txt" -type f | sort); do 564 | if [ -f "$file" ]; then 565 | full_model=$(basename "$file" .txt) 566 | model=$(echo "$full_model" | sed -E 's/_[^_]*$//') 567 | os_version=$(sed -n '2p' "$file") 568 | kernel_version=$(sed -n '1p' "$file") 569 | device_info["$full_model"]="$model|$os_version|$kernel_version" 570 | fi 571 | done 572 | 573 | ksu_options_raw='${{ github.event.inputs.ksu_options }}' 574 | ksu_options_normalized=$(echo "$ksu_options_raw" | jq -c 'map(if .type then .type |= ascii_upcase | if .hash == null then if .type == "KSUN" then .hash = "dev" elif .type == "KSU" then .hash = "main" else .hash end else . end else error("No type found") end)' 2>&1) 575 | 576 | ksun_hash=$(echo "$ksu_options_normalized" | jq -r 'map(select(.type == "KSUN")) | first | .hash // empty') 577 | ksu_hash=$(echo "$ksu_options_normalized" | jq -r 'map(select(.type == "KSU")) | first | .hash // empty') 578 | 579 | # Get workflow inputs for reference 580 | KSUN_BRANCH="$ksun_hash" 581 | KSU_BRANCH="$ksu_hash" 582 | 583 | OPTIMIZE_LEVEL="${{ inputs.optimize_level }}" 584 | CLEAN_BUILD="${{ inputs.clean_build }}" 585 | 586 | # Determine SUSFS branches used 587 | SUSFS_A12="${{ inputs.android12-5_10_susfs_branch_or_commit }}" 588 | SUSFS_A13="${{ inputs.android13-5_15_susfs_branch_or_commit }}" 589 | SUSFS_A14="${{ inputs.android14-6_1_susfs_branch_or_commit }}" 590 | SUSFS_A15="${{ inputs.android15-6_6_susfs_branch_or_commit }}" 591 | SUSFS_A16="${{ inputs.android16-6_12_susfs_branch_or_commit }}" 592 | 593 | [ -z "$SUSFS_A12" ] && SUSFS_A12="gki-android12-5.10 (auto)" 594 | [ -z "$SUSFS_A13" ] && SUSFS_A13="gki-android13-5.15 (auto)" 595 | [ -z "$SUSFS_A14" ] && SUSFS_A14="gki-android14-6.1 (auto)" 596 | [ -z "$SUSFS_A15" ] && SUSFS_A15="gki-android15-6.6 (auto)" 597 | [ -z "$SUSFS_A16" ] && SUSFS_A16="gki-android16-6.12 (auto)" 598 | 599 | cat << EOF > release_notes.md 600 | # 🎯 OnePlus Kernels with KernelSU Next & SUSFS $SUSFS_BASE_VERSION 601 | 602 | > **Build Date:** $(date -u '+%Y-%m-%d %H:%M:%S UTC') 603 | > **Build ID:** \`${{ github.run_id }}\` 604 | > **Workflow:** [\`${{ github.workflow }}\`](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) 605 | 606 | --- 607 | 608 | ## 📦 Built Devices (${#device_info[@]} total) 609 | 610 | | Model | OS Version | Kernel Version | Features | 611 | |-------|------------|----------------|----------| 612 | EOF 613 | 614 | for full_key in $(printf '%s\n' "${!device_info[@]}" | sort); do 615 | IFS='|' read -r model os_ver kernel_ver <<< "${device_info[$full_key]}" 616 | 617 | # Use jq to extract feature flags for this model from the JSON matrix 618 | feature_flags=$(jq -r --arg MODEL "$model" ' 619 | .[] | 620 | select(.model == $MODEL) | 621 | "\(.hmbird // false)\t\(.susfs // false)\t\(.bbr // false)\t\(.bbg // false)\t\(.ttl // false)\t\(.ip_set // false)" 622 | ' <<< "$JSON_BUILD_DATA") 623 | 624 | features="" 625 | # If no match found, skip or handle error 626 | if [[ -z "$feature_flags" ]]; then 627 | echo "Warning: No JSON entry found for model: $model" >&2 628 | else 629 | IFS=$'\t' read -r hmbird susfs bbr bbg ttl ip_set <<< "$feature_flags" 630 | 631 | # Build features string based on boolean values 632 | [[ "$hmbird" == "true" ]] && features+="🐦 HMBIRD " 633 | [[ "$susfs" == "true" ]] && features+="ඞ SusFS " 634 | [[ "$bbr" == "true" ]] && features+="🚀 BBR " 635 | [[ "$bbg" == "true" ]] && features+="🛡️ BBG " 636 | [[ "$ttl" == "true" ]] && features+="⏱️ TTL " 637 | [[ "$ip_set" == "true" ]] && features+="🔧 IP_SET" 638 | fi 639 | 640 | printf "| %-13s | %-10s | %-16s | %-30s |\n" \ 641 | "$model" "$os_ver" "$kernel_ver" "$features" >> release_notes.md 642 | done 643 | 644 | cat << EOF >> release_notes.md 645 | 646 | --- 647 | 648 | ## 🔧 Build Configuration 649 | 650 | | Component | Version/Setting | 651 | |-----------|----------------| 652 | EOF 653 | if [ -n ${{ needs.build.outputs.ksun_ver }}]; then 654 | cat << EOF >> release_notes.md 655 | | **KernelSU Next Branch** | \`$KSUN_BRANCH\` | 656 | | **KernelSU Next Version** | \`${{ needs.build.outputs.ksun_ver }}\` | 657 | EOF 658 | fi 659 | if [ -n ${{ needs.build.outputs.ksu_ver }}]; then 660 | cat << EOF >> release_notes.md 661 | | **KernelSU Branch** | \`$KSU_BRANCH\` | 662 | | **KernelSU Version** | \`${{ needs.build.outputs.ksu_ver }}\` | 663 | EOF 664 | fi 665 | cat << EOF >> release_notes.md 666 | | **SUSFS Version** | \`$SUSFS_BASE_VERSION\` | 667 | | **Optimization Level** | \`$OPTIMIZE_LEVEL\` | 668 | | **Clean Build** | $( [ "$CLEAN_BUILD" = "true" ] && echo "✅ Yes (no ccache)" || echo "❌ No (ccache enabled)" ) | 669 | | **Compiler** | Clang (version varies by device) | 670 | 671 | ### 📌 SUSFS Branch Mapping 672 | 673 | | Kernel Version | SUSFS Branch/Commit | 674 | |----------------|---------------------| 675 | | android12-5.10 | \`$SUSFS_A12\` | 676 | | android13-5.15 | \`$SUSFS_A13\` | 677 | | android14-6.1 | \`$SUSFS_A14\` | 678 | | android15-6.6 | \`$SUSFS_A15\` | 679 | | android16-6.12 | \`$SUSFS_A16\` | 680 | 681 | --- 682 | 683 | ## ✨ Features & Capabilities 684 | 685 | ### 🔐 Root Management 686 | EOF 687 | if [ -n ${{ needs.build.outputs.ksun_ver }}]; then 688 | cat << EOF >> release_notes.md 689 | - **KernelSU Next** - Next-generation kernel-level root solution 690 | EOF 691 | fi 692 | if [ -n ${{ needs.build.outputs.ksu_ver }}]; then 693 | cat << EOF >> release_notes.md 694 | - **KernelSU** - Kernel-level root solution 695 | EOF 696 | fi 697 | cat << EOF >> release_notes.md 698 | - **SUSFS $SUSFS_BASE_VERSION** - Advanced hiding and security features 699 | - **Magic Mount Support** - Seamless file system modifications 700 | - **Manual Hooks** - scope_min_manual_hooks_v1.4 for better compatibility 701 | 702 | ### 🛡️ Security & Privacy 703 | - **Baseband Guard (BBG)** - LSM-based baseband security 704 | - **SUSFS Hide Features**: 705 | - ✅ SUS_PATH - Hide suspicious paths 706 | - ✅ SUS_MOUNT - Hide mount points 707 | - ✅ SUS_KSTAT - Spoof kernel statistics 708 | - ✅ TRY_UMOUNT - Auto-unmount detection 709 | - ✅ SPOOF_UNAME - Kernel version spoofing 710 | - ✅ SPOOF_CMDLINE - Boot parameters spoofing 711 | - ✅ OPEN_REDIRECT - File access redirection 712 | - ✅ SUS_MAP - Memory mapping protection 713 | - **Ptrace Leak Fix** - For kernels < 5.16 714 | 715 | ### 🚀 Performance & Networking 716 | - **BBR** - Improved TCP congestion control 717 | - **Wireguard** - Built-in VPN support 718 | - **IP Set Support** - Advanced firewall capabilities 719 | - **TTL Target Support** - Network packet manipulation 720 | - **LTO (Link Time Optimization)** - Optimized binary size and performance 721 | - **ccache-accelerated builds** - Faster compilation times 722 | 723 | ### 🔧 System Features 724 | - **TMPFS_XATTR** - Extended attributes for tmpfs (Mountify support) 725 | - **TMPFS_POSIX_ACL** - POSIX ACLs for tmpfs 726 | - **HMBIRD SCX** - Scheduler extensions for all sm8750 devices 727 | 728 | --- 729 | 730 | ## 📱 Manager Applications 731 | 732 | ### Official Manager 733 | EOF 734 | if [ -n ${{ needs.build.outputs.ksun_ver }}]; then 735 | cat << EOF >> release_notes.md 736 | - **KernelSU Next Manager** 737 | → [GitHub Release](https://github.com/KernelSU-Next/KernelSU-Next/releases) 738 | EOF 739 | fi 740 | if [ -n ${{ needs.build.outputs.ksu_ver }}]; then 741 | cat << EOF >> release_notes.md 742 | - **KernelSU Next Manager** 743 | → [GitHub Release](https://github.com/KernelSU-Next/KernelSU-Next/releases) 744 | EOF 745 | fi 746 | cat << EOF >> release_notes.md 747 | ### Community Managers 748 | - **WildKSU Manager** (Recommended for additional features) 749 | → [GitHub Release](https://github.com/WildKernels/Wild_KSU/releases) 750 | 751 | ### Required Module 752 | - **KSU SUSFS Module** (Required for SUSFS features) 753 | → [GitHub Release](https://github.com/sidex15/ksu_module_susfs/releases) 754 | 755 | ### Recomended Flasher 756 | - **Kernel Flasher** (Required for flashing AnyKernel3 zips and backups and OTA) 757 | → [GitHub Release](https://github.com/fatalcoder524/KernelFlasher/releases) 758 | 759 | --- 760 | 761 | ## 📥 Installation Instructions 762 | 763 | ### Prerequisites 764 | - Unlocked bootloader 765 | - Backup your current boot image 766 | - Have root access using Magisk / KernelSU (Any forks) / Apatch 767 | 768 | ### Via Kernel Flasher 769 | 1. Download the appropriate ZIP for your device 770 | 2. Flash the ZIP file using Kernel Flasher 771 | 3. Reboot system 772 | 4. Install KernelSU-Next/WildSU Manager 773 | 5. Install SUSFS module from manager 774 | 775 | --- 776 | 777 | ## 📜 Changelog 778 | 779 | ### This Release 780 | - Updated SUSFS to v2.0.0 781 | - Added HMBIRD support for all sm8750 devices. 782 | - Improved ccache build system 783 | - Enhanced SUSFS hiding capabilities 784 | - Added IP_SET and TTL support 785 | - Added TMPFS_XATTR and TMPFS_POSIX_ACL support for Mountify 786 | - Added Ptrace leak fix for kernels < 5.16 787 | - Compiler optimizations (${{ inputs.optimize_level }}) 788 | 789 | ### Previous Releases 790 | See [Releases Page](${{ github.server_url }}/${{ github.repository }}/releases) 791 | 792 | --- 793 | 794 | ## 🙏 Credits 795 | 796 | - **KernelSU Next Team** - Root solution 797 | - **KernelSU Team** - Root solution 798 | - **simonpunk** - SUSFS development 799 | - **OnePlus** - Kernel source code 800 | - **Community Contributors** - Testing and feedback 801 | 802 | --- 803 | 804 | **⚡ Built with ❤️ by the community** 805 | 806 | EOF 807 | 808 | echo "--- Final Release Notes ---" 809 | cat release_notes.md 810 | 811 | - name: 🚀 Create GitHub Release 812 | run: | 813 | gh release create "${{ env.NEW_TAG }}" \ 814 | --repo "${{ env.REPO_OWNER }}/${{ env.REPO_NAME }}" \ 815 | --title "${{ env.RELEASE_NAME }}" \ 816 | --notes-file release_notes.md \ 817 | --prerelease 818 | 819 | - name: 📤 Upload Release Assets Dynamically 820 | run: | 821 | for file in ./downloaded-artifacts/*/*.zip; do 822 | if [ -f "$file" ]; then 823 | echo "Uploading $file..." 824 | gh release upload "${{ env.NEW_TAG }}" "$file" --clobber 825 | fi 826 | done 827 | 828 | - name: 📊 Release summary 829 | if: success() 830 | run: | 831 | cat >> $GITHUB_STEP_SUMMARY << EOF 832 | 833 | --- 834 | 835 | ## 🎉 Release Created Successfully 836 | 837 | **Tag:** [\`${{ env.NEW_TAG }}\`](${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ env.NEW_TAG }}) 838 | **Kernels:** $(find ./downloaded-artifacts -name "*.zip" | wc -l) 839 | 840 | ### 📦 Assets 841 | EOF 842 | 843 | for zip in ./downloaded-artifacts/*/*.zip; do 844 | if [ -f "$zip" ]; then 845 | name=$(basename "$zip") 846 | size=$(stat -c%s "$zip") 847 | size_mb=$(echo "scale=2; $size / 1024 / 1024" | bc) 848 | echo "- \`$name\` (${size_mb} MB)" >> $GITHUB_STEP_SUMMARY 849 | fi 850 | done 851 | -------------------------------------------------------------------------------- /.github/workflows/clean-up.yml: -------------------------------------------------------------------------------- 1 | name: Cleanup CCache 🧹 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | cleanup_type: 7 | type: choice 8 | description: 'Cleanup target' 9 | required: true 10 | default: 'cache_only' 11 | options: 12 | - cache_only # Only clean caches 13 | - runs_only # Only clean workflow runs 14 | - full_cleanup # Both caches and runs 15 | - analyze_only # Just analyze, don't delete 16 | 17 | device_filter: 18 | type: choice 19 | description: 'Device cache to clean' 20 | required: false 21 | default: 'ALL' 22 | options: 23 | - ALL 24 | # Kernel Versions 25 | - android15-6.6 26 | - android14-6.1 27 | - android14-5.15 28 | - android13-5.15 29 | - android13-5.10 30 | - android12-5.10 31 | # OnePlus Phones 32 | - OP15 33 | - OP13 34 | - OP13-CPH 35 | - OP13-PJZ 36 | - OP13r 37 | - OP13S 38 | - OP13T 39 | - OP12 40 | - OP12r 41 | - OP11 42 | - OP11r 43 | - OP10pro 44 | - OP10t 45 | # OnePlus Nord Series 46 | - OP-Nord-5 47 | - OP-NORD-4 48 | - OP-NORD-4-CE 49 | - OP-NORD-CE4-LITE 50 | # OnePlus Ace Series 51 | - OP-ACE-6 52 | - OP-ACE-5-PRO 53 | - OP-ACE-5 54 | - OP-ACE-3-PRO 55 | - OP-ACE-3V 56 | - OP-ACE-3 57 | - OP-ACE-2-PRO 58 | - OP-ACE-2 59 | # OnePlus Tablets & Others 60 | - OP-OPEN 61 | - OP-PAD-3 62 | - OP-PAD-2-PRO 63 | - OP-PAD-2 64 | - OP-PAD-PRO 65 | 66 | cache_pattern: 67 | type: choice 68 | description: 'Cache type to clean' 69 | required: false 70 | default: 'all_caches' 71 | options: 72 | - all_caches # All cache types 73 | - ccache_only # Only ccache (kernel builds) 74 | - ccache_stale # Only stale ccache (>14 days) 75 | - apt_only # Only apt packages 76 | - kernel_only # Only kernel-related caches 77 | - old_only # Only caches older than 7 days 78 | 79 | cache_age_days: 80 | description: 'Delete caches older than N days' 81 | required: false 82 | default: '7' 83 | 84 | keep_recent_runs: 85 | description: 'Keep N most recent successful runs' 86 | required: false 87 | default: '3' 88 | 89 | days_to_keep: 90 | description: 'Keep runs from last N days' 91 | required: false 92 | default: '7' 93 | 94 | dry_run: 95 | description: 'Dry run (show what would be deleted)' 96 | required: false 97 | type: boolean 98 | default: false 99 | 100 | force_cleanup: 101 | description: 'Force cleanup even if usage is low' 102 | required: false 103 | type: boolean 104 | default: false 105 | 106 | permissions: 107 | actions: write 108 | contents: read 109 | 110 | jobs: 111 | analyze: 112 | runs-on: ubuntu-latest 113 | outputs: 114 | should_cleanup: ${{ steps.analysis.outputs.should_cleanup }} 115 | total_cache_size: ${{ steps.analysis.outputs.total_size }} 116 | cache_count: ${{ steps.analysis.outputs.cache_count }} 117 | usage_percent: ${{ steps.analysis.outputs.usage_percent }} 118 | ccache_count: ${{ steps.analysis.outputs.ccache_count }} 119 | ccache_size: ${{ steps.analysis.outputs.ccache_size }} 120 | steps: 121 | - name: 📊 Analyze Repository Health 122 | id: analysis 123 | uses: actions/github-script@v7 124 | with: 125 | script: | 126 | const { owner, repo } = context.repo; 127 | const forceCleanup = '${{ inputs.force_cleanup }}' === 'true'; 128 | 129 | console.log('🔍 Analyzing repository cache health...\n'); 130 | 131 | let page = 1; 132 | let totalCacheSize = 0; 133 | let cacheCount = 0; 134 | let oldestCache = null; 135 | let newestCache = null; 136 | 137 | const cachesByType = { 138 | ccache: { size: 0, count: 0 }, 139 | apt: { size: 0, count: 0 }, 140 | kernel: { size: 0, count: 0 }, 141 | other: { size: 0, count: 0 } 142 | }; 143 | 144 | const cachesByDevice = new Map(); 145 | const cacheAgeDistribution = { 146 | fresh: 0, // < 7 days 147 | recent: 0, // 7-14 days 148 | old: 0, // 14-30 days 149 | stale: 0 // > 30 days 150 | }; 151 | 152 | // Collect all cache data 153 | while (true) { 154 | const res = await github.rest.actions.getActionsCacheList({ 155 | owner, 156 | repo, 157 | per_page: 100, 158 | page: page 159 | }); 160 | 161 | const caches = res.data.actions_caches; 162 | if (!caches || caches.length === 0) break; 163 | 164 | for (const cache of caches) { 165 | totalCacheSize += cache.size_in_bytes; 166 | cacheCount++; 167 | 168 | const cacheDate = new Date(cache.created_at); 169 | const ageDays = Math.floor((new Date() - cacheDate) / (1000 * 60 * 60 * 24)); 170 | 171 | // Age distribution 172 | if (ageDays < 7) cacheAgeDistribution.fresh++; 173 | else if (ageDays < 14) cacheAgeDistribution.recent++; 174 | else if (ageDays < 30) cacheAgeDistribution.old++; 175 | else cacheAgeDistribution.stale++; 176 | 177 | if (!oldestCache || cacheDate < new Date(oldestCache.created_at)) { 178 | oldestCache = cache; 179 | } 180 | if (!newestCache || cacheDate > new Date(newestCache.created_at)) { 181 | newestCache = cache; 182 | } 183 | 184 | // Categorize by type 185 | if (cache.key.startsWith('ccache-')) { 186 | cachesByType.ccache.size += cache.size_in_bytes; 187 | cachesByType.ccache.count++; 188 | 189 | // Extract device name from ccache key 190 | const match = cache.key.match(/ccache-([^-]+)-/); 191 | if (match) { 192 | const device = match[1]; 193 | if (!cachesByDevice.has(device)) { 194 | cachesByDevice.set(device, { 195 | size: 0, 196 | count: 0, 197 | lastAccessed: cache.last_accessed_at, 198 | oldestCache: ageDays, 199 | newestCache: ageDays 200 | }); 201 | } 202 | const deviceData = cachesByDevice.get(device); 203 | deviceData.size += cache.size_in_bytes; 204 | deviceData.count++; 205 | deviceData.oldestCache = Math.max(deviceData.oldestCache, ageDays); 206 | deviceData.newestCache = Math.min(deviceData.newestCache, ageDays); 207 | if (new Date(cache.last_accessed_at) > new Date(deviceData.lastAccessed)) { 208 | deviceData.lastAccessed = cache.last_accessed_at; 209 | } 210 | } 211 | } else if (cache.key.includes('apt')) { 212 | cachesByType.apt.size += cache.size_in_bytes; 213 | cachesByType.apt.count++; 214 | } else if (cache.key.includes('kernel') || cache.key.includes('android')) { 215 | cachesByType.kernel.size += cache.size_in_bytes; 216 | cachesByType.kernel.count++; 217 | } else { 218 | cachesByType.other.size += cache.size_in_bytes; 219 | cachesByType.other.count++; 220 | } 221 | } 222 | 223 | if (caches.length < 100) break; 224 | page++; 225 | } 226 | 227 | // Calculate metrics 228 | const totalGB = (totalCacheSize / 1024 / 1024 / 1024).toFixed(2); 229 | const limit = 10; // 10 GB GitHub limit 230 | const usagePercent = ((totalCacheSize / (limit * 1024 * 1024 * 1024)) * 100).toFixed(1); 231 | 232 | // Determine if cleanup is needed 233 | const shouldCleanup = forceCleanup || parseFloat(usagePercent) > 75; 234 | 235 | // Health status 236 | let healthEmoji = '🟢'; 237 | let healthStatus = 'Healthy'; 238 | if (usagePercent > 90) { 239 | healthEmoji = '🔴'; 240 | healthStatus = 'Critical'; 241 | } else if (usagePercent > 75) { 242 | healthEmoji = '🟡'; 243 | healthStatus = 'Warning'; 244 | } 245 | 246 | // Output for next jobs 247 | core.setOutput('should_cleanup', shouldCleanup.toString()); 248 | core.setOutput('total_size', totalCacheSize.toString()); 249 | core.setOutput('cache_count', cacheCount.toString()); 250 | core.setOutput('usage_percent', usagePercent); 251 | core.setOutput('ccache_count', cachesByType.ccache.count.toString()); 252 | core.setOutput('ccache_size', cachesByType.ccache.size.toString()); 253 | 254 | // Generate detailed summary 255 | let summary = core.summary 256 | .addHeading(`${healthEmoji} Cache Health Analysis - ${healthStatus}`) 257 | .addRaw(`\n### 📊 Overall Statistics\n\n`) 258 | .addTable([ 259 | [{data: 'Metric', header: true}, {data: 'Value', header: true}], 260 | ['Total Caches', cacheCount.toString()], 261 | ['Total Size', `${totalGB} GB`], 262 | ['Limit', `${limit} GB`], 263 | ['Usage', `${usagePercent}%`], 264 | ['Available', `${(limit - parseFloat(totalGB)).toFixed(2)} GB`], 265 | ['Status', healthStatus] 266 | ]); 267 | 268 | // Cache breakdown by type 269 | summary.addRaw(`\n### 🗂️ Cache Breakdown by Type\n\n`) 270 | .addTable([ 271 | [{data: 'Type', header: true}, {data: 'Count', header: true}, {data: 'Size (GB)', header: true}, {data: 'Percentage', header: true}], 272 | ['ccache (Kernel Builds)', 273 | cachesByType.ccache.count.toString(), 274 | (cachesByType.ccache.size / 1024 / 1024 / 1024).toFixed(2), 275 | `${((cachesByType.ccache.size / totalCacheSize) * 100).toFixed(1)}%` 276 | ], 277 | ['Kernel-related', 278 | cachesByType.kernel.count.toString(), 279 | (cachesByType.kernel.size / 1024 / 1024 / 1024).toFixed(2), 280 | `${((cachesByType.kernel.size / totalCacheSize) * 100).toFixed(1)}%` 281 | ], 282 | ['APT Packages', 283 | cachesByType.apt.count.toString(), 284 | (cachesByType.apt.size / 1024 / 1024 / 1024).toFixed(2), 285 | `${((cachesByType.apt.size / totalCacheSize) * 100).toFixed(1)}%` 286 | ], 287 | ['Other', 288 | cachesByType.other.count.toString(), 289 | (cachesByType.other.size / 1024 / 1024 / 1024).toFixed(2), 290 | `${((cachesByType.other.size / totalCacheSize) * 100).toFixed(1)}%` 291 | ] 292 | ]); 293 | 294 | // ccache-specific statistics 295 | if (cachesByType.ccache.count > 0) { 296 | const avgCcacheSize = cachesByType.ccache.size / cachesByType.ccache.count; 297 | const avgCcacheSizeMB = (avgCcacheSize / 1024 / 1024).toFixed(2); 298 | const ccachePercent = ((cachesByType.ccache.size / totalCacheSize) * 100).toFixed(1); 299 | 300 | summary.addRaw(`\n### ⚡ ccache Statistics\n\n`) 301 | .addTable([ 302 | [{data: 'Metric', header: true}, {data: 'Value', header: true}], 303 | ['Total ccache Entries', cachesByType.ccache.count.toString()], 304 | ['Total ccache Size', `${(cachesByType.ccache.size / 1024 / 1024 / 1024).toFixed(2)} GB`], 305 | ['Average Cache Size', `${avgCcacheSizeMB} MB`], 306 | ['Percentage of Total', `${ccachePercent}%`], 307 | ['Unique Devices', cachesByDevice.size.toString()] 308 | ]); 309 | 310 | // ccache recommendations 311 | if (parseFloat(ccachePercent) > 80) { 312 | summary.addRaw(`\n⚠️ **ccache dominates storage** (${ccachePercent}%)\n`) 313 | .addRaw(`- Consider reducing \`CCACHE_MAXSIZE\` in build workflow\n`) 314 | .addRaw(`- Clean stale device caches not actively built\n`) 315 | .addRaw(`- Use \`clean_build\` option occasionally to verify builds\n`); 316 | } 317 | } 318 | 319 | // Age distribution 320 | summary.addRaw(`\n### 📅 Cache Age Distribution\n\n`) 321 | .addTable([ 322 | [{data: 'Age Range', header: true}, {data: 'Count', header: true}, {data: 'Percentage', header: true}], 323 | ['Fresh (< 7 days)', cacheAgeDistribution.fresh.toString(), `${((cacheAgeDistribution.fresh / cacheCount) * 100).toFixed(1)}%`], 324 | ['Recent (7-14 days)', cacheAgeDistribution.recent.toString(), `${((cacheAgeDistribution.recent / cacheCount) * 100).toFixed(1)}%`], 325 | ['Old (14-30 days)', cacheAgeDistribution.old.toString(), `${((cacheAgeDistribution.old / cacheCount) * 100).toFixed(1)}%`], 326 | ['Stale (> 30 days)', cacheAgeDistribution.stale.toString(), `${((cacheAgeDistribution.stale / cacheCount) * 100).toFixed(1)}%`] 327 | ]); 328 | 329 | // Top devices by cache size 330 | if (cachesByDevice.size > 0) { 331 | const topDevices = Array.from(cachesByDevice.entries()) 332 | .sort((a, b) => b[1].size - a[1].size) 333 | .slice(0, 15); 334 | 335 | summary.addRaw(`\n### 📱 Top 15 Devices by Cache Size\n\n`) 336 | .addTable([ 337 | [{data: 'Device', header: true}, {data: 'Caches', header: true}, {data: 'Size (GB)', header: true}, {data: 'Age Range (days)', header: true}], 338 | ...topDevices.map(([device, data]) => [ 339 | device, 340 | data.count.toString(), 341 | (data.size / 1024 / 1024 / 1024).toFixed(2), 342 | `${data.newestCache}-${data.oldestCache}` 343 | ]) 344 | ]); 345 | 346 | // Identify inactive devices 347 | const now = new Date(); 348 | const inactiveThreshold = 30; // days 349 | const inactiveDevices = Array.from(cachesByDevice.entries()) 350 | .filter(([_, data]) => { 351 | const daysSinceAccess = Math.floor((now - new Date(data.lastAccessed)) / (1000 * 60 * 60 * 24)); 352 | return daysSinceAccess > inactiveThreshold; 353 | }) 354 | .sort((a, b) => b[1].size - a[1].size); 355 | 356 | if (inactiveDevices.length > 0) { 357 | summary.addRaw(`\n### 🚫 Inactive Devices (Not accessed in ${inactiveThreshold}+ days)\n\n`) 358 | .addTable([ 359 | [{data: 'Device', header: true}, {data: 'Size (GB)', header: true}, {data: 'Days Since Access', header: true}], 360 | ...inactiveDevices.slice(0, 10).map(([device, data]) => [ 361 | device, 362 | (data.size / 1024 / 1024 / 1024).toFixed(2), 363 | Math.floor((now - new Date(data.lastAccessed)) / (1000 * 60 * 60 * 24)).toString() 364 | ]) 365 | ]); 366 | 367 | const inactiveSizeGB = inactiveDevices.reduce((sum, [_, data]) => sum + data.size, 0) / 1024 / 1024 / 1024; 368 | summary.addRaw(`\n💡 **Potential savings:** ${inactiveSizeGB.toFixed(2)} GB by cleaning inactive devices\n`); 369 | } 370 | } 371 | 372 | // Age information 373 | if (oldestCache && newestCache) { 374 | const oldestDate = new Date(oldestCache.created_at); 375 | const newestDate = new Date(newestCache.created_at); 376 | const daysDiff = Math.floor((newestDate - oldestDate) / (1000 * 60 * 60 * 24)); 377 | 378 | summary.addRaw(`\n### 📅 Cache Age Information\n\n`) 379 | .addTable([ 380 | [{data: 'Metric', header: true}, {data: 'Value', header: true}], 381 | ['Oldest Cache', oldestDate.toISOString().split('T')[0]], 382 | ['Newest Cache', newestDate.toISOString().split('T')[0]], 383 | ['Age Range', `${daysDiff} days`] 384 | ]); 385 | } 386 | 387 | // Recommendations 388 | summary.addRaw(`\n### 💡 Recommendations\n\n`); 389 | 390 | if (parseFloat(usagePercent) > 90) { 391 | summary.addRaw(`- 🔴 **URGENT:** Cache usage is critical (${usagePercent}%)\n`) 392 | .addRaw(`- Run cleanup immediately with \`device_filter: ALL\`\n`) 393 | .addRaw(`- Consider cleaning old device caches\n`) 394 | .addRaw(`- Review ccache size limits in build workflows\n`); 395 | } else if (parseFloat(usagePercent) > 75) { 396 | summary.addRaw(`- 🟡 **WARNING:** Cache usage is high (${usagePercent}%)\n`) 397 | .addRaw(`- Schedule cleanup soon\n`) 398 | .addRaw(`- Consider targeting specific devices\n`); 399 | } else { 400 | summary.addRaw(`- 🟢 Cache usage is healthy (${usagePercent}%)\n`) 401 | .addRaw(`- Regular weekly cleanup recommended\n`) 402 | .addRaw(`- No immediate action required\n`); 403 | } 404 | 405 | // Stale cache recommendations 406 | if (cacheAgeDistribution.stale > 0) { 407 | const staleSizeEstimate = (cacheAgeDistribution.stale / cacheCount) * totalCacheSize; 408 | const staleSizeGB = (staleSizeEstimate / 1024 / 1024 / 1024).toFixed(2); 409 | summary.addRaw(`\n- 📦 **${cacheAgeDistribution.stale} stale caches** (>30 days old)\n`) 410 | .addRaw(`- Estimated size: ~${staleSizeGB} GB\n`) 411 | .addRaw(`- Run with \`cache_pattern: ccache_stale\` to clean\n`); 412 | } 413 | 414 | if (shouldCleanup && !forceCleanup) { 415 | summary.addRaw(`\n⚠️ **Automatic cleanup will proceed** (usage > 75%)\n`); 416 | } else if (forceCleanup) { 417 | summary.addRaw(`\n⚡ **Force cleanup enabled** - proceeding regardless of usage\n`); 418 | } 419 | 420 | summary.write(); 421 | 422 | console.log(`\n✅ Analysis complete:`); 423 | console.log(` - Total: ${totalGB} GB (${usagePercent}%)`); 424 | console.log(` - Caches: ${cacheCount}`); 425 | console.log(` - ccache: ${cachesByType.ccache.count} (${(cachesByType.ccache.size / 1024 / 1024 / 1024).toFixed(2)} GB)`); 426 | console.log(` - Devices: ${cachesByDevice.size}`); 427 | console.log(` - Cleanup needed: ${shouldCleanup}`); 428 | 429 | cleanup-caches: 430 | runs-on: ubuntu-latest 431 | needs: analyze 432 | if: | 433 | always() && 434 | (inputs.cleanup_type == 'cache_only' || inputs.cleanup_type == 'full_cleanup') && 435 | (inputs.cleanup_type != 'analyze_only') 436 | 437 | steps: 438 | - name: 🗑️ Smart Cache Cleanup 439 | uses: actions/github-script@v7 440 | with: 441 | script: | 442 | const { owner, repo } = context.repo; 443 | const deviceFilter = '${{ inputs.device_filter }}'; 444 | const cachePattern = '${{ inputs.cache_pattern }}'; 445 | const dryRun = '${{ inputs.dry_run }}' === 'true'; 446 | const cacheAgeDays = parseInt('${{ inputs.cache_age_days }}'); 447 | const shouldCleanup = '${{ needs.analyze.outputs.should_cleanup }}' === 'true'; 448 | const forceCleanup = '${{ inputs.force_cleanup }}' === 'true'; 449 | 450 | console.log(`🎯 Configuration:`); 451 | console.log(` - Device Filter: ${deviceFilter}`); 452 | console.log(` - Cache Pattern: ${cachePattern}`); 453 | console.log(` - Age Threshold: ${cacheAgeDays} days`); 454 | console.log(` - Dry Run: ${dryRun}`); 455 | console.log(` - Should Cleanup: ${shouldCleanup}`); 456 | console.log(` - Force Cleanup: ${forceCleanup}\n`); 457 | 458 | // Check if we should proceed 459 | if (!shouldCleanup && !forceCleanup && !dryRun) { 460 | console.log('ℹ️ Cache usage is healthy, skipping cleanup'); 461 | console.log('💡 Use force_cleanup=true to cleanup anyway'); 462 | core.summary 463 | .addHeading('ℹ️ Cleanup Skipped') 464 | .addRaw(`Cache usage is healthy (${${{ needs.analyze.outputs.usage_percent }}}%)\n\n`) 465 | .addRaw('No cleanup needed at this time.\n') 466 | .write(); 467 | return; 468 | } 469 | 470 | const cutoffDate = new Date(); 471 | cutoffDate.setDate(cutoffDate.getDate() - cacheAgeDays); 472 | 473 | // For stale ccache pattern, use 14 days 474 | const staleCutoffDate = new Date(); 475 | staleCutoffDate.setDate(staleCutoffDate.getDate() - 14); 476 | 477 | let totalDeleted = 0; 478 | let totalSize = 0; 479 | let page = 1; 480 | const deletedCaches = []; 481 | const skippedCaches = []; 482 | 483 | // Track statistics by category 484 | const deletionStats = { 485 | ccache: { count: 0, size: 0 }, 486 | apt: { count: 0, size: 0 }, 487 | kernel: { count: 0, size: 0 }, 488 | other: { count: 0, size: 0 } 489 | }; 490 | 491 | // Helper function to check if cache should be deleted 492 | function shouldDeleteCache(cache) { 493 | const cacheKey = cache.key; 494 | const cacheDate = new Date(cache.created_at); 495 | const ageDays = Math.floor((new Date() - cacheDate) / (1000 * 60 * 60 * 24)); 496 | 497 | // Device filter logic 498 | const deviceMatch = 499 | deviceFilter === 'ALL' || 500 | cacheKey.includes(deviceFilter) || 501 | cacheKey.includes(`-${deviceFilter}-`) || 502 | cacheKey.startsWith(`${deviceFilter}-`); 503 | 504 | if (!deviceMatch) { 505 | return { delete: false, reason: 'device_filter' }; 506 | } 507 | 508 | // Age filter for 'old_only' pattern 509 | if (cachePattern === 'old_only' && cacheDate >= cutoffDate) { 510 | return { delete: false, reason: 'too_new' }; 511 | } 512 | 513 | // Cache pattern logic 514 | let patternMatch = false; 515 | let category = 'other'; 516 | 517 | switch (cachePattern) { 518 | case 'ccache_only': 519 | patternMatch = cacheKey.startsWith('ccache-'); 520 | category = 'ccache'; 521 | break; 522 | 523 | case 'ccache_stale': 524 | patternMatch = cacheKey.startsWith('ccache-') && cacheDate < staleCutoffDate; 525 | category = 'ccache'; 526 | break; 527 | 528 | case 'apt_only': 529 | patternMatch = cacheKey.includes('apt-cache') || cacheKey.includes('apt-'); 530 | category = 'apt'; 531 | break; 532 | 533 | case 'kernel_only': 534 | patternMatch = cacheKey.includes('kernel-') || 535 | cacheKey.includes('android') || 536 | cacheKey.startsWith('ccache-'); 537 | if (cacheKey.startsWith('ccache-')) category = 'ccache'; 538 | else category = 'kernel'; 539 | break; 540 | 541 | case 'old_only': 542 | patternMatch = cacheDate < cutoffDate; 543 | if (cacheKey.startsWith('ccache-')) category = 'ccache'; 544 | else if (cacheKey.includes('apt')) category = 'apt'; 545 | else if (cacheKey.includes('kernel')) category = 'kernel'; 546 | break; 547 | 548 | case 'all_caches': 549 | default: 550 | patternMatch = true; 551 | if (cacheKey.startsWith('ccache-')) category = 'ccache'; 552 | else if (cacheKey.includes('apt')) category = 'apt'; 553 | else if (cacheKey.includes('kernel')) category = 'kernel'; 554 | } 555 | 556 | return { 557 | delete: patternMatch, 558 | reason: patternMatch ? 'match' : 'pattern_mismatch', 559 | category: category 560 | }; 561 | } 562 | 563 | // Fetch and process caches 564 | console.log('🔍 Scanning caches...\n'); 565 | 566 | while (true) { 567 | const res = await github.rest.actions.getActionsCacheList({ 568 | owner, 569 | repo, 570 | per_page: 100, 571 | page: page 572 | }); 573 | 574 | const caches = res.data.actions_caches; 575 | if (!caches || caches.length === 0) break; 576 | 577 | for (const cache of caches) { 578 | const decision = shouldDeleteCache(cache); 579 | const sizeMB = (cache.size_in_bytes / 1024 / 1024).toFixed(2); 580 | const agedays = Math.floor((new Date() - new Date(cache.created_at)) / (1000 * 60 * 60 * 24)); 581 | 582 | if (decision.delete) { 583 | deletedCaches.push({ 584 | key: cache.key, 585 | size: sizeMB, 586 | sizeBytes: cache.size_in_bytes, 587 | age: agedays, 588 | created: cache.created_at, 589 | id: cache.id, 590 | category: decision.category 591 | }); 592 | 593 | if (dryRun) { 594 | console.log(`🔍 Would delete: ${cache.key}`); 595 | console.log(` Size: ${sizeMB} MB | Age: ${agedays} days | Type: ${decision.category}`); 596 | } else { 597 | console.log(`🗑️ Deleting: ${cache.key}`); 598 | console.log(` Size: ${sizeMB} MB | Age: ${agedays} days | Type: ${decision.category}`); 599 | 600 | try { 601 | await github.rest.actions.deleteActionsCacheById({ 602 | owner, 603 | repo, 604 | cache_id: cache.id 605 | }); 606 | totalDeleted++; 607 | totalSize += cache.size_in_bytes; 608 | 609 | // Update category stats 610 | deletionStats[decision.category].count++; 611 | deletionStats[decision.category].size += cache.size_in_bytes; 612 | } catch (error) { 613 | console.log(` ⚠️ Failed: ${error.message}`); 614 | skippedCaches.push({ 615 | key: cache.key, 616 | reason: error.message 617 | }); 618 | } 619 | } 620 | } else if (decision.reason !== 'device_filter') { 621 | // Only log non-device-filter skips in verbose mode 622 | // console.log(`⏭️ Skipping: ${cache.key} (${decision.reason})`); 623 | } 624 | } 625 | 626 | if (caches.length < 100) break; 627 | page++; 628 | } 629 | 630 | const sizeMB = (totalSize / 1024 / 1024).toFixed(2); 631 | const sizeGB = (totalSize / 1024 / 1024 / 1024).toFixed(2); 632 | 633 | console.log(`\n✅ ${dryRun ? 'Would delete' : 'Deleted'} ${totalDeleted} caches`); 634 | console.log(`📊 Space ${dryRun ? 'would be' : ''} freed: ${sizeMB} MB (${sizeGB} GB)`); 635 | 636 | // Generate detailed summary 637 | let summary = core.summary 638 | .addHeading(`🧹 Cache Cleanup ${dryRun ? 'Preview' : 'Summary'}`) 639 | .addTable([ 640 | [{data: 'Metric', header: true}, {data: 'Value', header: true}], 641 | ['Caches ' + (dryRun ? 'to Delete' : 'Deleted'), totalDeleted.toString()], 642 | ['Space ' + (dryRun ? 'to Free' : 'Freed'), `${sizeMB} MB (${sizeGB} GB)`], 643 | ['Device Filter', deviceFilter], 644 | ['Cache Pattern', cachePattern], 645 | ['Age Threshold', `${cacheAgeDays} days`] 646 | ]); 647 | 648 | // Deletion breakdown by type 649 | if (totalDeleted > 0 || dryRun) { 650 | summary.addHeading('📊 Deletion Breakdown by Type', 3) 651 | .addTable([ 652 | [{data: 'Type', header: true}, {data: 'Count', header: true}, {data: 'Size (GB)', header: true}, {data: 'Percentage', header: true}], 653 | ['ccache', 654 | deletionStats.ccache.count.toString(), 655 | (deletionStats.ccache.size / 1024 / 1024 / 1024).toFixed(2), 656 | totalSize > 0 ? `${((deletionStats.ccache.size / totalSize) * 100).toFixed(1)}%` : '0%' 657 | ], 658 | ['Kernel-related', 659 | deletionStats.kernel.count.toString(), 660 | (deletionStats.kernel.size / 1024 / 1024 / 1024).toFixed(2), 661 | totalSize > 0 ? `${((deletionStats.kernel.size / totalSize) * 100).toFixed(1)}%` : '0%' 662 | ], 663 | ['APT Packages', 664 | deletionStats.apt.count.toString(), 665 | (deletionStats.apt.size / 1024 / 1024 / 1024).toFixed(2), 666 | totalSize > 0 ? `${((deletionStats.apt.size / totalSize) * 100).toFixed(1)}%` : '0%' 667 | ], 668 | ['Other', 669 | deletionStats.other.count.toString(), 670 | (deletionStats.other.size / 1024 / 1024 / 1024).toFixed(2), 671 | totalSize > 0 ? `${((deletionStats.other.size / totalSize) * 100).toFixed(1)}%` : '0%' 672 | ] 673 | ]); 674 | } 675 | 676 | // Add top 20 largest caches 677 | if (deletedCaches.length > 0) { 678 | const topCaches = deletedCaches 679 | .sort((a, b) => parseFloat(b.size) - parseFloat(a.size)) 680 | .slice(0, 20); 681 | 682 | summary.addHeading('📦 Top 20 Largest Caches ' + (dryRun ? 'to Delete' : 'Deleted'), 3) 683 | .addTable([ 684 | [{data: 'Cache Key', header: true}, {data: 'Size (MB)', header: true}, {data: 'Age (days)', header: true}, {data: 'Type', header: true}], 685 | ...topCaches.map(c => [c.key, c.size, c.age.toString(), c.category]) 686 | ]); 687 | } 688 | 689 | // Add oldest caches 690 | if (deletedCaches.length > 0) { 691 | const oldestCaches = deletedCaches 692 | .sort((a, b) => b.age - a.age) 693 | .slice(0, 10); 694 | 695 | summary.addHeading('📅 Top 10 Oldest Caches ' + (dryRun ? 'to Delete' : 'Deleted'), 3) 696 | .addTable([ 697 | [{data: 'Cache Key', header: true}, {data: 'Age (days)', header: true}, {data: 'Size (MB)', header: true}, {data: 'Type', header: true}], 698 | ...oldestCaches.map(c => [c.key, c.age.toString(), c.size, c.category]) 699 | ]); 700 | } 701 | 702 | // Device breakdown for ccache deletions 703 | if (deletionStats.ccache.count > 0) { 704 | const deviceDeletions = new Map(); 705 | for (const cache of deletedCaches) { 706 | if (cache.category === 'ccache') { 707 | const match = cache.key.match(/ccache-([^-]+)-/); 708 | if (match) { 709 | const device = match[1]; 710 | if (!deviceDeletions.has(device)) { 711 | deviceDeletions.set(device, { count: 0, size: 0 }); 712 | } 713 | const data = deviceDeletions.get(device); 714 | data.count++; 715 | data.size += cache.sizeBytes; 716 | } 717 | } 718 | } 719 | 720 | if (deviceDeletions.size > 0) { 721 | const topDevices = Array.from(deviceDeletions.entries()) 722 | .sort((a, b) => b[1].size - a[1].size) 723 | .slice(0, 10); 724 | 725 | summary.addHeading('📱 Top 10 Devices by Deleted ccache', 3) 726 | .addTable([ 727 | [{data: 'Device', header: true}, {data: 'Caches', header: true}, {data: 'Size (GB)', header: true}], 728 | ...topDevices.map(([device, data]) => [ 729 | device, 730 | data.count.toString(), 731 | (data.size / 1024 / 1024 / 1024).toFixed(2) 732 | ]) 733 | ]); 734 | } 735 | } 736 | 737 | // Add failures if any 738 | if (skippedCaches.length > 0) { 739 | summary.addHeading('⚠️ Failed Deletions', 3) 740 | .addTable([ 741 | [{data: 'Cache Key', header: true}, {data: 'Reason', header: true}], 742 | ...skippedCaches.map(c => [c.key, c.reason]) 743 | ]); 744 | } 745 | 746 | summary.write(); 747 | 748 | cleanup-runs: 749 | runs-on: ubuntu-latest 750 | needs: analyze 751 | if: | 752 | always() && 753 | (inputs.cleanup_type == 'runs_only' || inputs.cleanup_type == 'full_cleanup') && 754 | (inputs.cleanup_type != 'analyze_only') 755 | 756 | steps: 757 | - name: 🗑️ Clean old workflow runs 758 | uses: actions/github-script@v7 759 | with: 760 | script: | 761 | const { owner, repo } = context.repo; 762 | const keepRecent = parseInt('${{ inputs.keep_recent_runs }}'); 763 | const daysToKeep = parseInt('${{ inputs.days_to_keep }}'); 764 | const dryRun = '${{ inputs.dry_run }}' === 'true'; 765 | const cutoffDate = new Date(); 766 | cutoffDate.setDate(cutoffDate.getDate() - daysToKeep); 767 | 768 | console.log(`📅 Configuration:`); 769 | console.log(` - Keeping runs from: ${cutoffDate.toISOString()}`); 770 | console.log(` - Keeping ${keepRecent} most recent successful runs per workflow`); 771 | console.log(` - Dry Run: ${dryRun}\n`); 772 | 773 | const workflows = await github.rest.actions.listRepoWorkflows({ 774 | owner, 775 | repo 776 | }); 777 | 778 | let totalDeleted = 0; 779 | let totalFailed = 0; 780 | const workflowStats = []; 781 | 782 | for (const workflow of workflows.data.workflows) { 783 | console.log(`\n📋 Processing: ${workflow.name}`); 784 | 785 | let page = 1; 786 | let successfulRuns = []; 787 | let deletedInWorkflow = 0; 788 | let failedInWorkflow = 0; 789 | 790 | const runsByStatus = { 791 | success: 0, 792 | failure: 0, 793 | cancelled: 0, 794 | skipped: 0, 795 | other: 0 796 | }; 797 | 798 | while (true) { 799 | const runs = await github.rest.actions.listWorkflowRuns({ 800 | owner, 801 | repo, 802 | workflow_id: workflow.id, 803 | per_page: 100, 804 | page: page 805 | }); 806 | 807 | if (runs.data.workflow_runs.length === 0) break; 808 | 809 | for (const run of runs.data.workflow_runs) { 810 | const runDate = new Date(run.created_at); 811 | const ageDays = Math.floor((new Date() - runDate) / (1000 * 60 * 60 * 24)); 812 | 813 | // Count by status 814 | runsByStatus[run.conclusion || 'other']++; 815 | 816 | // Track successful runs 817 | if (run.conclusion === 'success') { 818 | successfulRuns.push(run); 819 | } 820 | 821 | // Determine if should delete 822 | const isOld = runDate < cutoffDate; 823 | const isFailed = run.conclusion === 'failure'; 824 | const isCancelled = run.conclusion === 'cancelled'; 825 | const isSkipped = run.conclusion === 'skipped'; 826 | const tooManySuccessful = run.conclusion === 'success' && 827 | successfulRuns.length > keepRecent; 828 | 829 | const shouldDelete = 830 | (isFailed && isOld) || 831 | (isCancelled && isOld) || 832 | (isSkipped && isOld) || 833 | (tooManySuccessful && isOld); 834 | 835 | if (shouldDelete) { 836 | if (dryRun) { 837 | console.log(`🔍 Would delete: #${run.run_number} (${run.conclusion}, ${ageDays}d old)`); 838 | } else { 839 | console.log(`🗑️ Deleting: #${run.run_number} (${run.conclusion}, ${ageDays}d old)`); 840 | 841 | try { 842 | await github.rest.actions.deleteWorkflowRun({ 843 | owner, 844 | repo, 845 | run_id: run.id 846 | }); 847 | deletedInWorkflow++; 848 | totalDeleted++; 849 | } catch (error) { 850 | console.log(` ⚠️ Failed: ${error.message}`); 851 | failedInWorkflow++; 852 | totalFailed++; 853 | } 854 | } 855 | } 856 | } 857 | 858 | if (runs.data.workflow_runs.length < 100) break; 859 | page++; 860 | } 861 | 862 | if (deletedInWorkflow > 0 || Object.values(runsByStatus).some(v => v > 0)) { 863 | workflowStats.push({ 864 | name: workflow.name, 865 | deleted: deletedInWorkflow, 866 | failed: failedInWorkflow, 867 | stats: runsByStatus 868 | }); 869 | } 870 | } 871 | 872 | console.log(`\n✅ Total runs ${dryRun ? 'to delete' : 'deleted'}: ${totalDeleted}`); 873 | if (totalFailed > 0) { 874 | console.log(`⚠️ Failed deletions: ${totalFailed}`); 875 | } 876 | 877 | // Generate summary 878 | let summary = core.summary 879 | .addHeading(`🧹 Workflow Runs ${dryRun ? 'Preview' : 'Summary'}`) 880 | .addTable([ 881 | [{data: 'Metric', header: true}, {data: 'Value', header: true}], 882 | ['Runs ' + (dryRun ? 'to Delete' : 'Deleted'), totalDeleted.toString()], 883 | ['Failed Deletions', totalFailed.toString()], 884 | ['Kept Recent Successful', keepRecent.toString()], 885 | ['Days Kept', daysToKeep.toString()] 886 | ]); 887 | 888 | if (workflowStats.length > 0) { 889 | summary.addHeading('📊 Per-Workflow Breakdown', 3) 890 | .addTable([ 891 | [ 892 | {data: 'Workflow', header: true}, 893 | {data: 'Deleted', header: true}, 894 | {data: 'Success', header: true}, 895 | {data: 'Failure', header: true}, 896 | {data: 'Cancelled', header: true} 897 | ], 898 | ...workflowStats.map(w => [ 899 | w.name, 900 | w.deleted.toString(), 901 | w.stats.success.toString(), 902 | w.stats.failure.toString(), 903 | w.stats.cancelled.toString() 904 | ]) 905 | ]); 906 | } 907 | 908 | summary.write(); 909 | 910 | final-report: 911 | runs-on: ubuntu-latest 912 | needs: [analyze, cleanup-caches, cleanup-runs] 913 | if: always() 914 | 915 | steps: 916 | - name: 📊 Final Repository Health Report 917 | uses: actions/github-script@v7 918 | with: 919 | script: | 920 | const { owner, repo } = context.repo; 921 | const dryRun = '${{ inputs.dry_run }}' === 'true'; 922 | 923 | console.log('📊 Generating final health report...\n'); 924 | 925 | // Get current cache usage (after cleanup) 926 | let page = 1; 927 | let totalCacheSize = 0; 928 | let cachesByType = { 929 | ccache: 0, 930 | apt: 0, 931 | kernel: 0, 932 | other: 0 933 | }; 934 | let cacheCount = 0; 935 | const buildFrequency = new Map(); 936 | const recentCutoff = new Date(); 937 | recentCutoff.setDate(recentCutoff.getDate() - 30); 938 | 939 | while (true) { 940 | const res = await github.rest.actions.getActionsCacheList({ 941 | owner, 942 | repo, 943 | per_page: 100, 944 | page: page 945 | }); 946 | 947 | const caches = res.data.actions_caches; 948 | if (!caches || caches.length === 0) break; 949 | 950 | for (const cache of caches) { 951 | totalCacheSize += cache.size_in_bytes; 952 | cacheCount++; 953 | 954 | if (cache.key.startsWith('ccache-')) { 955 | cachesByType.ccache += cache.size_in_bytes; 956 | 957 | // Track build frequency 958 | const match = cache.key.match(/ccache-([^-]+)-/); 959 | if (match && new Date(cache.last_accessed_at) > recentCutoff) { 960 | const device = match[1]; 961 | buildFrequency.set(device, (buildFrequency.get(device) || 0) + 1); 962 | } 963 | } else if (cache.key.includes('apt')) { 964 | cachesByType.apt += cache.size_in_bytes; 965 | } else if (cache.key.includes('kernel') || cache.key.includes('android')) { 966 | cachesByType.kernel += cache.size_in_bytes; 967 | } else { 968 | cachesByType.other += cache.size_in_bytes; 969 | } 970 | } 971 | 972 | if (caches.length < 100) break; 973 | page++; 974 | } 975 | 976 | const totalGB = (totalCacheSize / 1024 / 1024 / 1024).toFixed(2); 977 | const ccacheGB = (cachesByType.ccache / 1024 / 1024 / 1024).toFixed(2); 978 | const aptGB = (cachesByType.apt / 1024 / 1024 / 1024).toFixed(2); 979 | const kernelGB = (cachesByType.kernel / 1024 / 1024 / 1024).toFixed(2); 980 | const otherGB = (cachesByType.other / 1024 / 1024 / 1024).toFixed(2); 981 | 982 | const limit = 10; // 10 GB 983 | const usagePercent = ((totalCacheSize / (limit * 1024 * 1024 * 1024)) * 100).toFixed(1); 984 | 985 | // Calculate change if we have before data 986 | const beforeSize = parseFloat('${{ needs.analyze.outputs.total_cache_size }}'); 987 | const beforeCount = parseInt('${{ needs.analyze.outputs.cache_count }}'); 988 | const beforePercent = parseFloat('${{ needs.analyze.outputs.usage_percent }}'); 989 | 990 | let changeInfo = ''; 991 | if (beforeSize > 0 && !dryRun) { 992 | const sizeChange = beforeSize - totalCacheSize; 993 | const countChange = beforeCount - cacheCount; 994 | const percentChange = beforePercent - parseFloat(usagePercent); 995 | 996 | const changeGB = (sizeChange / 1024 / 1024 / 1024).toFixed(2); 997 | 998 | changeInfo = `\n### 📈 Cleanup Impact\n\n` + 999 | `- **Space Freed:** ${changeGB} GB\n` + 1000 | `- **Caches Removed:** ${countChange}\n` + 1001 | `- **Usage Reduced:** ${percentChange.toFixed(1)}%\n`; 1002 | } 1003 | 1004 | // Determine health status 1005 | let healthEmoji = '🟢'; 1006 | let healthStatus = 'Healthy'; 1007 | if (usagePercent > 90) { 1008 | healthEmoji = '🔴'; 1009 | healthStatus = 'Critical - Immediate Cleanup Needed!'; 1010 | } else if (usagePercent > 75) { 1011 | healthEmoji = '🟡'; 1012 | healthStatus = 'Warning - Consider Cleanup Soon'; 1013 | } 1014 | 1015 | let summary = core.summary 1016 | .addHeading(`${healthEmoji} Final Repository Health Report`) 1017 | .addRaw(dryRun ? '\n**⚠️ This was a DRY RUN - No changes were made**\n\n' : '\n') 1018 | .addTable([ 1019 | [{data: 'Cache Type', header: true}, {data: 'Size (GB)', header: true}, {data: 'Percentage', header: true}], 1020 | ['ccache (Kernel Builds)', ccacheGB, totalCacheSize > 0 ? `${((cachesByType.ccache / totalCacheSize) * 100).toFixed(1)}%` : '0%'], 1021 | ['Kernel-related', kernelGB, totalCacheSize > 0 ? `${((cachesByType.kernel / totalCacheSize) * 100).toFixed(1)}%` : '0%'], 1022 | ['APT Packages', aptGB, totalCacheSize > 0 ? `${((cachesByType.apt / totalCacheSize) * 100).toFixed(1)}%` : '0%'], 1023 | ['Other', otherGB, totalCacheSize > 0 ? `${((cachesByType.other / totalCacheSize) * 100).toFixed(1)}%` : '0%'], 1024 | ['**Total**', `**${totalGB}**`, '**100%**'] 1025 | ]) 1026 | .addRaw(`\n### 📊 Current Usage Statistics\n\n`) 1027 | .addRaw(`- **Total Caches:** ${cacheCount}\n`) 1028 | .addRaw(`- **Limit:** ${limit} GB\n`) 1029 | .addRaw(`- **Current Usage:** ${totalGB} GB (${usagePercent}%)\n`) 1030 | .addRaw(`- **Available:** ${(limit - parseFloat(totalGB)).toFixed(2)} GB\n`) 1031 | .addRaw(`- **Status:** ${healthStatus}\n`) 1032 | .addRaw(changeInfo); 1033 | 1034 | // Build activity analysis 1035 | if (buildFrequency.size > 0) { 1036 | const activeDevices = Array.from(buildFrequency.entries()) 1037 | .filter(([_, count]) => count >= 3) 1038 | .sort((a, b) => b[1] - a[1]); 1039 | 1040 | summary.addRaw(`\n### 📱 Build Activity Analysis (Last 30 Days)\n\n`) 1041 | .addRaw(`- **Active Devices:** ${activeDevices.length}\n`) 1042 | .addRaw(`- **Total Build Events:** ${Array.from(buildFrequency.values()).reduce((a, b) => a + b, 0)}\n`); 1043 | 1044 | if (activeDevices.length > 0) { 1045 | const topActive = activeDevices.slice(0, 10); 1046 | summary.addRaw(`\n**Top 10 Most Active Devices:**\n`) 1047 | .addTable([ 1048 | [{data: 'Device', header: true}, {data: 'Build Events', header: true}], 1049 | ...topActive.map(([device, count]) => [device, count.toString()]) 1050 | ]); 1051 | } 1052 | } 1053 | 1054 | summary.addRaw(`\n### 💡 Next Steps\n\n`); 1055 | 1056 | if (dryRun) { 1057 | summary.addRaw(`- ℹ️ This was a dry run - run again with \`dry_run: false\` to apply changes\n`); 1058 | } else if (parseFloat(usagePercent) > 75) { 1059 | summary.addRaw(`- ⚠️ **Action Required:** Usage still high, consider additional cleanup\n`) 1060 | .addRaw(`- Target specific devices or cache types\n`) 1061 | .addRaw(`- Review ccache size limits\n`); 1062 | } else { 1063 | summary.addRaw(`- ✅ Cache usage is now healthy\n`) 1064 | .addRaw(`- Schedule regular cleanup (weekly recommended)\n`) 1065 | .addRaw(`- Monitor usage trends\n`); 1066 | } 1067 | 1068 | summary.addRaw(`\n### 🔄 Cleanup Schedule Recommendations\n\n`) 1069 | .addRaw(`- **Daily:** If building > 10 devices regularly\n`) 1070 | .addRaw(`- **Weekly:** For moderate usage (5-10 devices)\n`) 1071 | .addRaw(`- **Monthly:** For light usage (< 5 devices)\n`) 1072 | .addRaw(`- **On-demand:** When usage exceeds 75%\n`); 1073 | 1074 | summary.write(); 1075 | 1076 | console.log(`\n✅ Final report generated`); 1077 | console.log(` - Current usage: ${totalGB} GB (${usagePercent}%)`); 1078 | console.log(` - Status: ${healthStatus}`); 1079 | 1080 | - name: 💡 Quick Action Commands 1081 | if: always() 1082 | run: | 1083 | cat >> $GITHUB_STEP_SUMMARY << 'EOF' 1084 | 1085 | --- 1086 | 1087 | ## 🚀 Quick Action Commands 1088 | 1089 | ### High Usage Cleanup (>75%) 1090 | ```bash 1091 | # Clean all old caches (>7 days) 1092 | gh workflow run cleanup.yml \ 1093 | -f cleanup_type=cache_only \ 1094 | -f cache_pattern=old_only \ 1095 | -f cache_age_days=7 1096 | 1097 | # Clean stale ccache (>14 days) 1098 | gh workflow run cleanup.yml \ 1099 | -f cleanup_type=cache_only \ 1100 | -f cache_pattern=ccache_stale 1101 | 1102 | # Clean specific device 1103 | gh workflow run cleanup.yml \ 1104 | -f cleanup_type=cache_only \ 1105 | -f device_filter=OP13 \ 1106 | -f cache_pattern=ccache_only 1107 | ``` 1108 | 1109 | ### Regular Maintenance 1110 | ```bash 1111 | # Weekly cleanup (recommended) 1112 | gh workflow run cleanup.yml \ 1113 | -f cleanup_type=full_cleanup \ 1114 | -f cache_age_days=14 1115 | 1116 | # Analyze only (no changes) 1117 | gh workflow run cleanup.yml \ 1118 | -f cleanup_type=analyze_only 1119 | 1120 | # Dry run preview 1121 | gh workflow run cleanup.yml \ 1122 | -f cleanup_type=cache_only \ 1123 | -f dry_run=true 1124 | ``` 1125 | 1126 | ### Emergency Cleanup 1127 | ```bash 1128 | # Force cleanup everything old 1129 | gh workflow run cleanup.yml \ 1130 | -f cleanup_type=full_cleanup \ 1131 | -f force_cleanup=true \ 1132 | -f cache_age_days=3 1133 | 1134 | # Clean all ccache immediately 1135 | gh workflow run cleanup.yml \ 1136 | -f cleanup_type=cache_only \ 1137 | -f cache_pattern=ccache_only \ 1138 | -f force_cleanup=true 1139 | ``` 1140 | 1141 | ### Device-Specific Cleanup 1142 | ```bash 1143 | # Clean by kernel version 1144 | gh workflow run cleanup.yml \ 1145 | -f cleanup_type=cache_only \ 1146 | -f device_filter=android15-6.6 \ 1147 | -f cache_pattern=ccache_only 1148 | 1149 | # Clean specific phone model 1150 | gh workflow run cleanup.yml \ 1151 | -f cleanup_type=cache_only \ 1152 | -f device_filter=OP13 \ 1153 | -f cache_pattern=all_caches 1154 | ``` 1155 | 1156 | ### Workflow Runs Cleanup 1157 | ```bash 1158 | # Clean old workflow runs 1159 | gh workflow run cleanup.yml \ 1160 | -f cleanup_type=runs_only \ 1161 | -f days_to_keep=7 \ 1162 | -f keep_recent_runs=3 1163 | ``` 1164 | 1165 | --- 1166 | 1167 | **💡 Tip:** Use `dry_run=true` first to preview what will be deleted! 1168 | 1169 | EOF 1170 | --------------------------------------------------------------------------------