Sfoglia il codice sorgente

dev: port multi-root matrix from GKI (root-setup, pinned commits, per-version SUSFS)

TheWildJames 1 settimana fa
parent
commit
3e89e9d653

+ 24 - 10
.github/actions/file-name/action.yml

@@ -1,9 +1,18 @@
 name: set file name for ak3zip
 description: set file name for ak3 zip
 inputs:
+ root_flavor:
+  description: 'root flavor'
+  required: false
+  default: ""
+ variant:
+  description: 'variant'
+  required: false
+  default: ""
  ksun:
-  description: 'ksun'
-  required: true
+  description: 'ksun (deprecated)'
+  required: false
+  default: "true"
  susfs:
   description: 'susfs'
   required: true
@@ -36,16 +45,22 @@ inputs:
   required: true
 
 runs:
- using: composite
- steps:
+  using: composite
+  steps:
   - name: set file name for ak3zip
     shell: bash
     run: |
      ARTIFACT_BASE="$BRANCH"
-          
-     # This gives dynamic file name depending on which features are enabled
-     FILE_NAME="${ARTIFACT_BASE}"
-     [[ "${{ inputs.ksun }}" == "true" ]] && FILE_NAME="${FILE_NAME}-KSUN${KSU_VERSION}"
+     VARIANT_LABEL="${{ inputs.variant }}"
+     if [ -z "$VARIANT_LABEL" ]; then
+       case "${{ inputs.root_flavor }}" in
+         next) VARIANT_LABEL="KSUN" ;;
+         kernelsu) VARIANT_LABEL="KSU" ;;
+         resukisu) VARIANT_LABEL="RESUKISU" ;;
+         *) VARIANT_LABEL="KSUN" ;;
+       esac
+     fi
+     FILE_NAME="${ARTIFACT_BASE}-${VARIANT_LABEL}"
      [[ "${{ inputs.susfs }}" == "true" ]] && FILE_NAME="${FILE_NAME}-SUSFS"
      [[ "${{ inputs.zeromount }}" == "true" ]] && FILE_NAME="${FILE_NAME}-ZM"
      [[ "${{ inputs.nomount }}" == "true" ]] && FILE_NAME="${FILE_NAME}-NM"
@@ -57,8 +72,7 @@ runs:
      [[ "${{ inputs.ttl }}" == "true" ]] && FILE_NAME="${FILE_NAME}-TTL"
      [[ "${{ inputs.unicodefix }}" == "true" ]] && FILE_NAME="${FILE_NAME}-UF"
      
-      
      echo "ARTIFACT_BASE=$ARTIFACT_BASE" >> $GITHUB_ENV
      echo "FILE_NAME=$FILE_NAME" >> $GITHUB_ENV
           
-     echo "Final artifact name: $FILE_NAME"
+     echo "Final artifact name: $FILE_NAME"

+ 13 - 3
.github/actions/nomount/action.yml

@@ -1,6 +1,10 @@
 name: add nomount
 description: add and configure nomount
-
+inputs:
+  commit:
+    description: 'pinned nomount commit'
+    required: false
+    default: ""
 runs:
   using: composite
   steps:
@@ -8,8 +12,14 @@ runs:
      shell: bash
      run: |
       cd "$COMMON"
-      curl https://raw.githubusercontent.com/maxsteeel/nomount/refs/heads/dev/kernel/setup.sh | bash -
-
+      if [ -n "${{ inputs.commit }}" ]; then
+        git clone --no-checkout https://github.com/maxsteeel/nomount.git /tmp/nomount
+        git -C /tmp/nomount fetch --depth=1 origin "${{ inputs.commit }}"
+        git -C /tmp/nomount checkout "${{ inputs.commit }}"
+        bash /tmp/nomount/kernel/setup.sh || bash -c "curl -fsSL https://raw.githubusercontent.com/maxsteeel/nomount/${{ inputs.commit }}/kernel/setup.sh | bash -"
+      else
+        curl https://raw.githubusercontent.com/maxsteeel/nomount/refs/heads/dev/kernel/setup.sh | bash -
+      fi
    - name: add to defconfig
      shell: bash
      run: |

+ 117 - 0
.github/actions/root-setup/action.yml

@@ -0,0 +1,117 @@
+name: Setup pinned root implementation
+description: 'Clone exactly one supported root implementation at a verified commit for Samsung'
+inputs:
+  flavor:
+    description: 'kernelsu, next, or resukisu'
+    required: true
+  commit:
+    description: 'Full immutable commit SHA'
+    required: true
+
+runs:
+  using: composite
+  steps:
+    - name: Clone and integrate selected root
+      shell: bash
+      run: |
+        set -euo pipefail
+
+        flavor="${{ inputs.flavor }}"
+        expected_commit="${{ inputs.commit }}"
+        case "$flavor" in
+          kernelsu)
+            repo="https://github.com/tiann/KernelSU.git"
+            directory="KernelSU"
+            manager="KernelSU Manager"
+            ;;
+          next)
+            repo="https://github.com/KernelSU-Next/KernelSU-Next.git"
+            directory="KernelSU-Next"
+            manager="KernelSU Next Manager"
+            ;;
+          resukisu)
+            repo="https://github.com/ReSukiSU/ReSukiSU.git"
+            directory="ReSukiSU"
+            manager="ReSukiSU Manager"
+            ;;
+          *)
+            echo "Unsupported root flavor: $flavor" >&2
+            exit 2
+            ;;
+        esac
+
+        if ! [[ "$expected_commit" =~ ^[0-9a-f]{40}$ ]]; then
+          echo "Root commit must be a full 40-character SHA." >&2
+          exit 2
+        fi
+
+        if [ -n "${COMMON:-}" ] && [ -d "$COMMON" ]; then
+          KROOT="$COMMON"
+          CLONE_BASE="$CONFIG"
+        elif [ -n "${CONFIG:-}" ] && [ -d "$CONFIG" ]; then
+          if [ -d "$CONFIG/kernel_platform/common" ]; then KROOT="$CONFIG/kernel_platform/common"
+          elif [ -d "$CONFIG/common" ]; then KROOT="$CONFIG/common"
+          elif [ -d "$CONFIG/kernel-6.6" ]; then KROOT="$CONFIG/kernel-6.6"
+          elif [ -d "$CONFIG/kernel-6.1" ]; then KROOT="$CONFIG/kernel-6.1"
+          elif [ -d "$CONFIG/kernel-5.10" ]; then KROOT="$CONFIG/kernel-5.10"
+          elif [ -d "$CONFIG/kernel" ]; then KROOT="$CONFIG/kernel"
+          else KROOT="$CONFIG"
+          fi
+          CLONE_BASE="$CONFIG"
+        else
+          echo "Cannot resolve kernel root (COMMON/CONFIG not set)." >&2
+          exit 1
+        fi
+
+        echo "KROOT=$KROOT CLONE_BASE=$CLONE_BASE flavor=$flavor"
+
+        for candidate in KernelSU KernelSU-Next ReSukiSU; do
+          if [ "$candidate" != "$directory" ] && [ -e "$CLONE_BASE/$candidate" ]; then
+            echo "Refusing mixed root implementations: found $candidate." >&2
+            exit 1
+          fi
+        done
+
+        drivers_dir="$KROOT/drivers"
+        if [ ! -d "$drivers_dir" ]; then
+          echo "Kernel drivers directory not found at $drivers_dir" >&2
+          exit 1
+        fi
+
+        if [ -e "$drivers_dir/kernelsu" ] || [ -L "$drivers_dir/kernelsu" ]; then
+          echo "Refusing to replace an existing kernelsu integration." >&2
+          exit 1
+        fi
+        if [ -e "$CLONE_BASE/$directory" ]; then
+          echo "Refusing to reuse an existing root checkout: $directory." >&2
+          exit 1
+        fi
+
+        git clone --no-checkout "$repo" "$CLONE_BASE/$directory"
+        git -C "$CLONE_BASE/$directory" fetch --depth=1 origin "$expected_commit"
+        git -C "$CLONE_BASE/$directory" checkout --detach "$expected_commit"
+        actual_commit="$(git -C "$CLONE_BASE/$directory" rev-parse HEAD)"
+        if [ "$actual_commit" != "$expected_commit" ]; then
+          echo "Root commit mismatch: expected $expected_commit, got $actual_commit." >&2
+          exit 1
+        fi
+        if [ ! -f "$CLONE_BASE/$directory/kernel/Kconfig" ] || [ ! -f "$CLONE_BASE/$directory/kernel/Makefile" ]; then
+          echo "Selected root checkout does not contain a kernel integration." >&2
+          exit 1
+        fi
+        root_version="$(git -C "$CLONE_BASE/$directory" describe --tags --always --dirty)"
+        relative_kernel="$(realpath --relative-to="$drivers_dir" "$CLONE_BASE/$directory/kernel" 2>/dev/null || echo "$CLONE_BASE/$directory/kernel")"
+        ln -s "$relative_kernel" "$drivers_dir/kernelsu"
+        grep -q 'obj-$(CONFIG_KSU) += kernelsu/' "$drivers_dir/Makefile" || printf '\nobj-$(CONFIG_KSU) += kernelsu/\n' >> "$drivers_dir/Makefile"
+        grep -q 'source "drivers/kernelsu/Kconfig"' "$drivers_dir/Kconfig" || sed -i '/endmenu/i source "drivers/kernelsu/Kconfig"' "$drivers_dir/Kconfig"
+        ln -sf "$CLONE_BASE/$directory" "$COMMON/KernelSU-Next" 2>/dev/null || true
+        echo "ROOT_IMPLEMENTATION=$flavor" >> "$GITHUB_ENV"
+        echo "ROOT_MANAGER=$manager" >> "$GITHUB_ENV"
+        echo "ROOT_VERSION=$root_version" >> "$GITHUB_ENV"
+        echo "ROOT_COMMIT=$actual_commit" >> "$GITHUB_ENV"
+        echo "ROOT_DIR=$CLONE_BASE/$directory" >> "$GITHUB_ENV"
+
+    - name: Enable root configuration
+      shell: bash
+      run: |
+        "$COMMON/scripts/config" --file "$GKI_DEFCONFIG" --enable CONFIG_KSU

+ 15 - 50
.github/actions/susfs-patches/action.yml

@@ -4,6 +4,10 @@ inputs:
  nomount:
   description: 'nomount'
   required: true
+ susfs_commit:
+  description: 'pinned SUSFS commit (empty = latest tip)'
+  required: false
+  default: ""
 
 runs:
   using: composite
@@ -13,52 +17,31 @@ runs:
      run: |
       SUSFS_BRANCH="gki-$ANDROID_VER-$KERNEL_VER"
       git clone https://gitlab.com/simonpunk/susfs4ksu.git -b "$SUSFS_BRANCH"
+      if [ -n "${{ inputs.susfs_commit }}" ]; then
+        echo "Checking out pinned SUSFS ${{ inputs.susfs_commit }}"
+        git -C susfs4ksu fetch --depth 1 origin "${{ inputs.susfs_commit }}" || git -C susfs4ksu fetch origin "${{ inputs.susfs_commit }}"
+        git -C susfs4ksu checkout "${{ inputs.susfs_commit }}"
+      fi
 
       git config --global user.name "github-actions[bot]"
       git config --global user.email "41898282+github-actions[bot]@://github.com"
       
       cd susfs4ksu
-      git fetch https://gitlab.com/pershoot/susfs4ksu.git gki-android14-6.1-dev
-      git log ..FETCH_HEAD --oneline -n 2 | awk '{print $1}' | tac | xargs git cherry-pick
+      git fetch https://gitlab.com/pershoot/susfs4ksu.git gki-android14-6.1-dev || true
+      git log ..FETCH_HEAD --oneline -n 2 | awk '{print $1}' | tac | xargs git cherry-pick 2>/dev/null || true
       
-      #cd susfs4ksu
-      #if [[ "$ANDROID_VER-$KERNEL_VER" == "android12-5.10" ]]; then
-        #COMMIT=ce2c2b2dea28c89d33f61af898cc18a93bf65ae9
-      #elif [[ "$ANDROID_VER-$KERNEL_VER" == "android13-5.15" ]]; then
-       # COMMIT=529919fbc9f8aee6ee70eb3a8890ef33af0a109c
-      #elif [[ "$ANDROID_VER-$KERNEL_VER" == "android14-6.1" ]]; then
-        #COMMIT=d1327b62e0854603cfc26e2226e0a993ec9b0656
-      #elif [[ "$ANDROID_VER-$KERNEL_VER" == "android15-6.6" ]]; then
-        #COMMIT=676d202ed2cc322a2f90bcb2b56bc4f6a864acb8
-      #fi
-      #git checkout "$COMMIT"
-
       SUSFS4KSU="$ROOT/susfs4ksu"
       echo "SUSFS4KSU=$SUSFS4KSU" >> $GITHUB_ENV
+      echo "SUSFS_COMMIT=$(git -C "$ROOT/susfs4ksu" rev-parse HEAD)" >> $GITHUB_ENV
       
    - name: Apply to KSUN
      shell: bash
      run: |
-       #cd "$COMMON/KernelSU-Next"
-       #SUSFS_VERSION="v2.1.0"
-          
-       # Apply SUSFS to KernelSU-Next
-       #cp "$SUSFS4KSU/kernel_patches/KernelSU/10_enable_susfs_for_ksu.patch" .
-       #patch -p1 < 10_enable_susfs_for_ksu.patch || true
-       #rm -rf 10_enable_susfs_for_ksu.patch
-
-       #Fix rejects from adding susfs to KSUN
-       #cp "$KERNEL_PATCHES/next/susfs_fix_patches/$SUSFS_VERSION/"*.patch .
-       #rm -rf multi_manager.patch
-       #for p in *.patch; do
-       #    patch -p1 < "$p"
-       #    rm -f "$p"
-       #done
+       echo "SUSFS prepared at $SUSFS4KSU"
        
    - name: Copy required files
      shell: bash
      run: |
-      # Apply SUSFS to kernel
       cd "$COMMON"
       cp "$SUSFS4KSU/kernel_patches/fs/"* ./fs/
       cp "$SUSFS4KSU/kernel_patches/include/linux/"* ./include/linux/
@@ -68,10 +51,7 @@ runs:
      shell: bash
      run: |
       cd "$COMMON"
-      #Prepare open.c for susfs patching
       sed -i '/#ifdef CONFIG_SECURITY_DEFEX/,/^#endif/d' fs/open.c
-
-      #Prepare namespace.c for susfs patching
       sed -i '/copy_flags = CL_COPY_UNBINDABLE | CL_EXPIRE;/,/#endif/ {
         /#ifdef CONFIG_KDP_NS/,/#endif/ {
            /#else/,/#endif/!d
@@ -84,18 +64,13 @@ runs:
      shell: bash
      run: |
       cd "$COMMON"
-      # Apply SUSFS core patch
       patch -p1 < 50_add_susfs_in_gki-$ANDROID_VER-$KERNEL_VER.patch || true
       rm -rf 50_add_susfs_in_gki-$ANDROID_VER-$KERNEL_VER.patch
-
       shopt -s nullglob
       patches=("$KERNEL_PATCHES/samsung/$BRANCH"/*.patch)
-      
       if [ ${#patches[@]} -gt 0 ]; then
        echo "Patches found, applying..."
        cp "${patches[@]}" ./
-       
-       # Fix SUSFS rejects
         for p in *.patch; do
           patch -p1 < "$p"
           rm -f "$p"
@@ -104,23 +79,13 @@ runs:
       else
         echo "No patch file found, skipping"
       fi
-
-        # SUSFS's OPEN_REDIRECT code unconditionally calls VMA_PAD_START(), which
-        # only exists on GKI branches that carry Google's page-size-migration
-        # feature (added to each android version's kernel/common branch at a
-        # different, sometime later, os_patch_level). Older os_patch_levels in
-        # our build matrix predate it, so fall back to a no-padding definition
-        # when the real header/macro isn't present. This is version-agnostic and
-        # a no-op wherever the real header already provides it.
         if grep -q 'VMA_PAD_START(' fs/proc/task_mmu.c && ! grep -qE '#include <linux/pgsize_migration(_inline)?\.h>|define VMA_PAD_START' fs/proc/task_mmu.c; then
           sed -i '1a #ifndef VMA_PAD_START\n#define VMA_PAD_START(vma) ((vma)->vm_end)\n#endif' fs/proc/task_mmu.c
-          echo "Added VMA_PAD_START fallback definition to fs/proc/task_mmu.c"
+          echo "Added VMA_PAD_START fallback"
         fi
-
-        # Same story for __fold_filemap_fixup_entry(), declared in page_size_compat.h.
         if grep -q '__fold_filemap_fixup_entry' fs/proc/task_mmu.c && ! grep -q '#include <linux/page_size_compat.h>' fs/proc/task_mmu.c; then
           sed -i '/#include <linux\/pkeys.h>/a #include <linux/page_size_compat.h>' fs/proc/task_mmu.c
-          echo "Added page_size_compat.h include to fs/proc/task_mmu.c"
+          echo "Added page_size_compat.h include"
         fi
        
    - name: add ksu-susfs to config

+ 142 - 113
.github/workflows/build.yml

@@ -12,6 +12,55 @@ on:
       build_type:
         required: false
         type: string
+      root_flavor:
+        description: "next / kernelsu / resukisu"
+        required: false
+        type: string
+        default: "next"
+      root_commit:
+        required: false
+        type: string
+        default: ""
+      variant:
+        required: false
+        type: string
+        default: ""
+      susfs_commit:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android12_5_10:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android13_5_10:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android13_5_15:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android14_5_15:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android14_6_1:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android15_6_6:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android16_6_12:
+        required: false
+        type: string
+        default: ""
+      nomount_commit:
+        required: false
+        type: string
+        default: ""
       susfs:
         required: true
         type: string
@@ -27,9 +76,6 @@ on:
       nomount:
         required: true
         type: string
-      ksun:
-        required: true
-        type: string
       droidspace:
         required: true
         type: string
@@ -57,7 +103,7 @@ on:
 
 jobs:
   build-samsung-gki:
-    name: "${{ inputs.branch }}"
+    name: "${{ inputs.branch }} (${{ inputs.variant || inputs.root_flavor }})"
     runs-on: ubuntu-latest
     strategy:
       fail-fast: false
@@ -82,7 +128,7 @@ jobs:
         
       - name: Free Disk Space
         if: true
-        uses: endersonmenezes/free-disk-space@v3  # Use @main for latest, @v3 for stable
+        uses: endersonmenezes/free-disk-space@v3
         with:
           remove_android: true
           remove_dotnet: true
@@ -92,36 +138,19 @@ jobs:
           remove_packages: "azure-cli google-cloud-cli microsoft-edge-stable google-chrome-stable firefox postgresql* temurin-* *llvm* mysql* dotnet-sdk-*"
           remove_packages_one_command: true
           remove_folders: "/usr/share/swift /usr/share/miniconda /usr/share/az* /usr/local/lib/node_modules /usr/local/share/chromium /usr/local/share/powershell /usr/local/julia /usr/local/aws-cli /usr/local/aws-sam-cli /usr/share/gradle"
-          rm_cmd: "rmz"  # Use 'rmz' for faster deletion (default: 'rm')
-          rmz_version: "3.1.1"  # Required when rm_cmd is 'rmz'
+          rm_cmd: "rmz"
+          rmz_version: "3.1.1"
           testing: false
 
       - name: Setup more Swap (for LTO)
-        uses: pierotofy/set-swap-space@master # or thejerrybao/setup-swap-space@v1
+        uses: pierotofy/set-swap-space@master
         with:
-          swap-size-gb: 25          # 10-24 GB is common for heavy LTO
-        # swap-space-path: /mnt/swapfile   # optional
+          swap-size-gb: 25
 
       - name: Parse branch for cache keys
         if: inputs.cache == 'true' && inputs.build_type == 'make'
         uses: ./.github/actions/parse-branch
 
-#      - name: set up bazel cache dir
-#        if: inputs.build_type == 'Bazel' && inputs.cache == 'true'
-#        run: |
-#          BCACHE_DIR="${{ github.workspace }}/.cache/bazel-disk-kernel"
-#          mkdir -p "$BCACHE_DIR"
-#          echo "BCACHE_DIR=$BCACHE_DIR" >> $GITHUB_ENV
-
- #     - name: set up bazel cache
- #       if: inputs.build_type == 'Bazel' && inputs.cache == 'true'
- #       uses: actions/cache@v6
- #       with:
- #        path: ${{ env.BCACHE_DIR }}
- #        key: bcache-${{ runner.os }}-${{ inputs.build_type }}-${{ env.FULL_BRANCH }}
- #        restore-keys: |
- #           bcache-${{ runner.os }}-${{ inputs.build_type }}-${{ env.FULL_BRANCH }}
-
       - name: Install ccache
         if: inputs.cache == 'true' && inputs.build_type == 'make'
         run: sudo apt-get update && sudo apt-get install -y ccache
@@ -166,9 +195,10 @@ jobs:
         uses: actions/cache@v6
         with:
           path: ${{ env.CCACHE_DIR }}
-          key: ccache-${{ runner.os }}-${{ inputs.build_type }}-${{ env.BASE_BRANCH }}
+          key: ccache-${{ runner.os }}-${{ inputs.build_type }}-${{ env.BASE_BRANCH }}-${{ inputs.root_flavor }}-${{ inputs.variant }}
           restore-keys: |
-            ccache-${{ runner.os }}-${{ inputs.build_type }}-${{ env.BASE_BRANCH }}
+            ccache-${{ runner.os }}-${{ inputs.build_type }}-${{ env.BASE_BRANCH }}-${{ inputs.root_flavor }}-
+            ccache-${{ runner.os }}-${{ inputs.build_type }}-${{ env.BASE_BRANCH }}-
             ccache-${{ runner.os }}-${{ inputs.build_type }}-
             
       - name: Ensure ccache is used
@@ -180,10 +210,7 @@ jobs:
         
       - name: Set CONFIG Environment Variable
         run: |
-          # Set CONFIG dynamically based on inputs values
           CONFIG="$BRANCH-$ANDROID_VERSION_$KERNEL_VERSION"
-
-          # Set CONFIG as an environment variable for future steps
           echo "CONFIG=$CONFIG" >> $GITHUB_ENV
 
       - name: dependencies
@@ -198,24 +225,77 @@ jobs:
       - name: Extract all tar.xz files and delete them
         run: |
           cd "$CONFIG"
-
           find . -type f -name '*.tar.xz' -print0 | while IFS= read -r -d '' file; do
             echo "Extracting $file"
             tar -xf "$file"
             rm "$file"
           done
 
-      - name: Add KernelSU-Next
-        if: inputs.ksun == 'true'
-        uses: ./.github/actions/ksun
+      - name: Setup Selected Root Implementation
+        if: inputs.root_flavor != ''
+        uses: ./.github/actions/root-setup
         with:
-          susfs: ${{ inputs.susfs }}
-        
+          flavor: ${{ inputs.root_flavor }}
+          commit: ${{ inputs.root_commit }}
+
+      - name: Disable SUSFS for ReSukiSU without SUSFS feature
+        if: inputs.root_flavor == 'resukisu' && inputs.susfs != 'true'
+        run: |
+          "$COMMON/scripts/config" --file "$GKI_DEFCONFIG" --disable CONFIG_KSU_SUSFS || true
+          echo "Disabled SUSFS for resukisu without SUSFS"
+
+      - name: Resolve SUSFS commit
+        id: susfs-cm
+        if: inputs.susfs == 'true'
+        shell: bash
+        run: |
+          set -euo pipefail
+          # KernelSU-Next (next) always uses latest tip so SUSFS stays API-matched.
+          # Other flavors use pinned verified commit per kernel version.
+          # We receive all per-version pins from kernel-samsung.yml inputs.
+          KVER="$KERNEL_VER"
+          AVER="$ANDROID_VERSION"
+          echo "KERNEL_VER=$KVER ANDROID_VER=$AVER root_flavor=${{ inputs.root_flavor }}"
+
+          pick_pin() {
+            case "$KVER" in
+              5.10) if [ "$AVER" = "android12" ]; then echo "${{ inputs.susfs_commit_android12_5_10 }}"; else echo "${{ inputs.susfs_commit_android13_5_10 }}"; fi ;;
+              5.15) if [ "$AVER" = "android14" ]; then echo "${{ inputs.susfs_commit_android14_5_15 }}"; else echo "${{ inputs.susfs_commit_android13_5_15 }}"; fi ;;
+              6.1) echo "${{ inputs.susfs_commit_android14_6_1 }}" ;;
+              6.6) echo "${{ inputs.susfs_commit_android15_6_6 }}" ;;
+              6.12) echo "${{ inputs.susfs_commit_android16_6_12 }}" ;;
+              *) echo "${{ inputs.susfs_commit }}" ;;
+            esac
+          }
+
+          if [ "${{ inputs.root_flavor }}" = "next" ]; then
+            BRANCH="gki-${AVER}-${KVER}"
+            # try android version fallback if branch missing
+            SUSFS_COMMIT="$(git ls-remote https://gitlab.com/simonpunk/susfs4ksu.git "refs/heads/${BRANCH}" | cut -f1)"
+            if [ -z "$SUSFS_COMMIT" ]; then
+              # fallback to generic gki branch
+              for b in "gki-android12-5.10" "gki-android13-5.15" "gki-android14-6.1" "gki-android15-6.6"; do
+                SUSFS_COMMIT="$(git ls-remote https://gitlab.com/simonpunk/susfs4ksu.git "refs/heads/${b}" | cut -f1 || true)"
+                [ -n "$SUSFS_COMMIT" ] && break
+              done
+            fi
+            # last resort: use pinned
+            if [ -z "$SUSFS_COMMIT" ]; then SUSFS_COMMIT="$(pick_pin)"; fi
+            echo "KernelSU-Next: resolving SUSFS at latest on ${BRANCH} -> ${SUSFS_COMMIT}"
+          else
+            SUSFS_COMMIT="$(pick_pin)"
+            if [ -z "$SUSFS_COMMIT" ]; then SUSFS_COMMIT="${{ inputs.susfs_commit }}"; fi
+            echo "Using pinned SUSFS commit: ${SUSFS_COMMIT}"
+          fi
+          echo "commit=${SUSFS_COMMIT}" >> "$GITHUB_OUTPUT"
+          echo "SUSFS_COMMIT=${SUSFS_COMMIT}" >> "$GITHUB_ENV"
+
       - name: Add SUSFS
         if: inputs.susfs == 'true'
         uses: ./.github/actions/susfs-patches
         with:
           nomount: ${{ inputs.nomount }}
+          susfs_commit: ${{ steps.susfs-cm.outputs.commit }}
 
       - name: Add Zeromount
         if: inputs.susfs == 'true' && inputs.zeromount == 'true'
@@ -224,6 +304,8 @@ jobs:
       - name: add nomount
         if: inputs.nomount == 'true'
         uses: ./.github/actions/nomount
+        with:
+          commit: ${{ inputs.nomount_commit }}
 
       - name: Add BBG
         if: inputs.bbg == 'true'
@@ -266,7 +348,6 @@ jobs:
         uses: ./.github/actions/m55-fix
 
       - name: Set Kernel Configuration Variables
-        if: inputs.ksun == 'true'
         uses: ./.github/actions/configs
          
       - name: Change Kernel Name and clean dirty
@@ -276,10 +357,11 @@ jobs:
         uses: ./.github/actions/abi-export
         
       - name: Set file name
-        if: inputs.ksun == 'true'
         uses: ./.github/actions/file-name
         with:
-         ksun: ${{ inputs.ksun }}
+         root_flavor: ${{ inputs.root_flavor }}
+         variant: ${{ inputs.variant }}
+         ksun: "true"
          susfs: ${{ inputs.susfs }}
          zeromount: ${{ inputs.zeromount }}
          nomount: ${{ inputs.nomount }}
@@ -290,11 +372,7 @@ jobs:
          ipv6_nat: ${{ inputs.ipv6_nat }}
          ttl: ${{ inputs.ttl }}
          unicodefix: ${{ inputs.unicodefix }}
-         
-
-#      - name: ensure bazel cache is set to be used
-#        if: inputs.build_type == 'Bazel' && inputs.cache == 'true'
-#        uses: ./.github/actions/use-bazcache
+          
 
       - name: change variables to ccache
         if: inputs.cache == 'true' && inputs.build_type == 'make'
@@ -315,10 +393,6 @@ jobs:
       - name: ccache stats
         if: inputs.cache == 'true' && inputs.build_type == 'make'
         run: ccache -s -v || ccache -s
-
-#      - name: bazel cache stats
-#        if: inputs.cache == 'true' && inputs.build_type == 'Bazel'
-#        run: bazel analyze-profile profile.json
           
       - name: Prepare AnyKernel3
         uses: ./.github/actions/ak3zip-prep
@@ -339,19 +413,16 @@ jobs:
           CONFIG_DIR="$CONFIG"
           REJECTS_DIR="$GITHUB_WORKSPACE/patch-rejects"
           mkdir -p "$REJECTS_DIR"
-          # Find all .rej files under the configuration directory
           mapfile -t REJS < <(find "$CONFIG_DIR" -type f -name '*.rej')
           REJ_COUNT=${#REJS[@]}
           echo "Found $REJ_COUNT .rej files under $CONFIG_DIR"
           echo "REJ_COUNT=$REJ_COUNT" >> $GITHUB_ENV
           if [ "$REJ_COUNT" -gt 0 ]; then
             for REJ in "${REJS[@]}"; do
-              # Relative path from $CONFIG
               REL="${REJ#"$CONFIG_DIR"/}"
               DEST="$REJECTS_DIR/$REL"
               mkdir -p "$(dirname "$DEST")"
               cp "$REJ" "$DEST"
-              # Copy the associated original file alongside the .rej
               ORIG="${REJ%.rej}"
               if [ -f "$ORIG" ]; then
                 ORIG_DEST="$REJECTS_DIR/${REL%.rej}"
@@ -365,95 +436,53 @@ jobs:
       - name: Generate Build Summary
         if: ${{ always() }}
         run: |
-          # Create build summary file for inclusion in Misc artifact
           echo "# Kernel Build Summary" > build_summary.md
-          
-          # Add build variant header
           echo "## ${{ env.FILE_NAME }}" >> build_summary.md
-          
-          # Add build info
           echo "## Build Information" >> build_summary.md
-          echo "- **Android Version**: ${{ inputs.android_version }}" >> build_summary.md
-          echo "- **Kernel Version**: ${{ inputs.kernel_version }}.${{ inputs.sub_level }}" >> build_summary.md
+          echo "- **Branch**: ${{ inputs.branch }}" >> build_summary.md
+          echo "- **Root**: ${{ inputs.variant || inputs.root_flavor }} @ ${{ inputs.root_commit }}" >> build_summary.md
+          echo "- **Kernel Version**: ${{ env.KERNEL_VER }}" >> build_summary.md
+          echo "- **Android Version**: ${{ env.ANDROID_VER }}" >> build_summary.md
+          echo "- **SUSFS**: ${{ env.SUSFS_COMMIT || 'disabled' }}" >> build_summary.md
           echo "- **BBG**: Installed" >> build_summary.md
           echo "" >> build_summary.md
 
-          # Get KernelSU-Next commit
           if [ -d "$CONFIG/KernelSU-Next" ]; then
             cd "$CONFIG/KernelSU-Next"
-            KSUN_COMMIT=$(git rev-parse HEAD)
-            KSUN_URL="https://github.com/WildKernels/KernelSU-Next/commit/$KSUN_COMMIT"
-            echo "- **KernelSU-Next**: [$KSUN_COMMIT]($KSUN_URL)" >> "$GITHUB_WORKSPACE/build_summary.md"
+            KSUN_COMMIT=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
+            echo "- **KernelSU-Next**: $KSUN_COMMIT" >> "$GITHUB_WORKSPACE/build_summary.md"
+            cd "$GITHUB_WORKSPACE"
+          elif [ -d "$CONFIG/KernelSU" ]; then
+            cd "$CONFIG/KernelSU"
+            KSU_COMMIT=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
+            echo "- **KernelSU**: $KSU_COMMIT" >> "$GITHUB_WORKSPACE/build_summary.md"
+            cd "$GITHUB_WORKSPACE"
+          elif [ -d "$CONFIG/ReSukiSU" ]; then
+            cd "$CONFIG/ReSukiSU"
+            RS_COMMIT=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
+            echo "- **ReSukiSU**: $RS_COMMIT" >> "$GITHUB_WORKSPACE/build_summary.md"
             cd "$GITHUB_WORKSPACE"
-          else
-            echo "- **KernelSU-Next**: not present" >> build_summary.md
           fi
           
-          # Get Baseband-guard commit
           if [ -d "$CONFIG/Baseband-guard" ]; then
             cd "$CONFIG/Baseband-guard"
             BBG_COMMIT=$(git rev-parse HEAD)
-            BBG_URL="https://github.com/vc-teahouse/Baseband-guard/commit/$BBG_COMMIT"
-            echo "- **Baseband-guard**: [$BBG_COMMIT]($BBG_URL)" >> "$GITHUB_WORKSPACE/build_summary.md"
+            echo "- **Baseband-guard**: $BBG_COMMIT" >> "$GITHUB_WORKSPACE/build_summary.md"
             cd "$GITHUB_WORKSPACE"
-          else
-            echo "- **Baseband-guard**: not present" >> build_summary.md
           fi
           
-          # Get SUSFS4KSU commit
           if [ -d "$GITHUB_WORKSPACE/susfs4ksu" ]; then
             cd "$GITHUB_WORKSPACE/susfs4ksu"
             SUSFS_COMMIT=$(git rev-parse HEAD)
-            SUSFS_URL="https://gitlab.com/simonpunk/susfs4ksu/-/commit/$SUSFS_COMMIT"
-            echo "- **SUSFS4KSU (v2.1.0)**: [$SUSFS_COMMIT]($SUSFS_URL)" >> "$GITHUB_WORKSPACE/build_summary.md"
+            echo "- **SUSFS4KSU**: $SUSFS_COMMIT" >> "$GITHUB_WORKSPACE/build_summary.md"
             cd "$GITHUB_WORKSPACE"
-          else
-            echo "- **SUSFS4KSU (v2.1.0)**: not present" >> build_summary.md
           fi
           echo "" >> build_summary.md
           
-          # Add artifact summary with presence verification
           echo "## Build Artifacts" >> build_summary.md
-
-          # Verify AnyKernel3 contents - check if kernel Image was actually copied (indicates successful build)
           if [ -d "AnyKernel3" ] && [ -f "AnyKernel3/Image" ]; then
             AK3_STATUS="✅"
           else
             AK3_STATUS="❌"
           fi
           echo "- **AnyKernel3**: $AK3_STATUS ${{ env.FILE_NAME }}-AnyKernel3" >> build_summary.md
-
-          echo "### Misc (uploaded files)" >> build_summary.md
-          FILES_PRESENT=0
-          for f in "${{ env.FILE_NAME }}-Image" "${{ env.FILE_NAME }}-Image.gz" "${{ env.FILE_NAME }}-Image.lz4" "${{ env.FILE_NAME }}-boot.img" "${{ env.FILE_NAME }}-boot-gz.img" "${{ env.FILE_NAME }}-boot-lz4.img"; do
-            if [ -f "$f" ]; then FILES_PRESENT=$((FILES_PRESENT+1)); fi
-          done
-          if [ "$FILES_PRESENT" -gt 0 ]; then
-            MISC_STATUS="✅"
-          else
-            MISC_STATUS="❌"
-          fi
-          echo "- **Set**: $MISC_STATUS ${{ env.FILE_NAME }}-Misc" >> build_summary.md
-          if [ "$MISC_STATUS" = "✅" ]; then
-            echo "  Included:" >> build_summary.md
-            for f in "${{ env.FILE_NAME }}-Image" "${{ env.FILE_NAME }}-Image.gz" "${{ env.FILE_NAME }}-Image.lz4" "${{ env.FILE_NAME }}-boot.img" "${{ env.FILE_NAME }}-boot-gz.img" "${{ env.FILE_NAME }}-boot-lz4.img"; do
-              if [ -f "$f" ]; then
-                echo "  - $f" >> build_summary.md
-              fi
-            done
-          fi
-
-          echo "### Diagnostics" >> build_summary.md
-          echo "- **Rejected Patches**: ${{ env.FILE_NAME }}-Rejected-Patches" >> build_summary.md
-          if [ -f patch-rejects/index.txt ]; then
-            if [ -s patch-rejects/index.txt ]; then
-              echo "  Rejected files:" >> build_summary.md
-              while IFS= read -r line; do
-                echo "    - $line" >> build_summary.md
-              done < patch-rejects/index.txt
-            else
-              echo "  Rejected file list is empty." >> build_summary.md
-            fi
-          else
-            echo "  No rejected patches found." >> build_summary.md
-          fi

+ 64 - 8
.github/workflows/kernel-samsung.yml

@@ -1,12 +1,61 @@
 name: Kernel Config - Samsung
 
 permissions:
-  contents: write  # Allow writing to repository contents
-  actions: write   # Allows triggering actions
+  contents: write
+  actions: write
 
 on:
   workflow_call:
     inputs:
+      root_flavor:
+        description: "next / kernelsu / resukisu"
+        required: false
+        type: string
+        default: "next"
+      root_commit:
+        required: false
+        type: string
+        default: ""
+      variant:
+        required: false
+        type: string
+        default: ""
+      susfs_commit:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android12_5_10:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android13_5_10:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android13_5_15:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android14_5_15:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android14_6_1:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android15_6_6:
+        required: false
+        type: string
+        default: ""
+      susfs_commit_android16_6_12:
+        required: false
+        type: string
+        default: ""
+      nomount_commit:
+        required: false
+        type: string
+        default: ""
       susfs:
         required: true
         type: string
@@ -22,9 +71,6 @@ on:
       nomount:
         required: true
         type: string
-      ksun:
-        required: true
-        type: string
       droidspace:
         required: true
         type: string
@@ -52,7 +98,7 @@ on:
 
 jobs:
   build-kernels-a12:
-    name: "Samsung-${{ matrix.branch }}-${{ matrix.kernel_version }}-${{ matrix.android_version }}"
+    name: "Samsung-${{ matrix.branch }}-${{ matrix.kernel_version }}-${{ matrix.android_version }} (${{ inputs.variant || inputs.root_flavor }})"
     strategy:
       fail-fast: false
       matrix:
@@ -182,12 +228,23 @@ jobs:
     with:
       branch: ${{ matrix.branch }}
       build_type: ${{ matrix.build_type }}
+      root_flavor: ${{ inputs.root_flavor }}
+      root_commit: ${{ inputs.root_commit }}
+      variant: ${{ inputs.variant }}
+      susfs_commit: ${{ inputs.susfs_commit }}
+      susfs_commit_android12_5_10: ${{ inputs.susfs_commit_android12_5_10 }}
+      susfs_commit_android13_5_10: ${{ inputs.susfs_commit_android13_5_10 }}
+      susfs_commit_android13_5_15: ${{ inputs.susfs_commit_android13_5_15 }}
+      susfs_commit_android14_5_15: ${{ inputs.susfs_commit_android14_5_15 }}
+      susfs_commit_android14_6_1: ${{ inputs.susfs_commit_android14_6_1 }}
+      susfs_commit_android15_6_6: ${{ inputs.susfs_commit_android15_6_6 }}
+      susfs_commit_android16_6_12: ${{ inputs.susfs_commit_android16_6_12 }}
+      nomount_commit: ${{ inputs.nomount_commit }}
       susfs: ${{ inputs.susfs }}
       bbg: ${{ inputs.bbg }}
       unicodefix: ${{ inputs.unicodefix }}
       zeromount: ${{ inputs.zeromount }}
       nomount: ${{ inputs.nomount }}
-      ksun: ${{ inputs.ksun }}
       droidspace: ${{ inputs.droidspace }}
       ntsync: ${{ inputs.ntsync }}
       bbrv3: ${{ inputs.bbrv3 }}
@@ -196,4 +253,3 @@ jobs:
       optimization: ${{ inputs.optimization }}
       ttl: ${{ inputs.ttl }}
       lto: ${{ inputs.lto }}
-

+ 193 - 74
.github/workflows/main.yml

@@ -27,11 +27,25 @@ on:
           - full
         default: default
 
-      ksun:
-        description: "KSUN"
+      commit_mode:
+        description: "latest = branch tips, verified = audited pins, update = build latest then promote verified pins on success"
         required: false
-        default: true
-        type: boolean
+        type: choice
+        options:
+          - latest
+          - verified
+          - update
+        default: verified
+
+      root_flavor:
+        description: "Root Flavor"
+        type: choice
+        options:
+          - KernelSU-Next
+          - KernelSU
+          - ReSukiSU
+          - All
+        default: All
 
       susfs:
         description: "SUSFS"
@@ -107,16 +121,166 @@ on:
 
 jobs:
 
+  resolve-sources:
+    runs-on: ubuntu-latest
+    outputs:
+      nomount_commit: ${{ steps.resolve.outputs.nomount_commit }}
+      kernelsu_commit: ${{ steps.resolve.outputs.kernelsu_commit }}
+      kernelsu_branch: ${{ steps.resolve.outputs.kernelsu_branch }}
+      root_flavor: ${{ steps.resolve.outputs.root_flavor }}
+      root_commit: ${{ steps.resolve.outputs.root_commit }}
+      root_matrix: ${{ steps.resolve.outputs.root_matrix }}
+      susfs_commit_android12_5_10: ${{ steps.resolve.outputs.susfs_commit_android12_5_10 }}
+      susfs_commit_android13_5_10: ${{ steps.resolve.outputs.susfs_commit_android13_5_10 }}
+      susfs_commit_android13_5_15: ${{ steps.resolve.outputs.susfs_commit_android13_5_15 }}
+      susfs_commit_android14_5_15: ${{ steps.resolve.outputs.susfs_commit_android14_5_15 }}
+      susfs_commit_android14_6_1: ${{ steps.resolve.outputs.susfs_commit_android14_6_1 }}
+      susfs_commit_android15_6_6: ${{ steps.resolve.outputs.susfs_commit_android15_6_6 }}
+      susfs_commit_android16_6_12: ${{ steps.resolve.outputs.susfs_commit_android16_6_12 }}
+      susfs_commit_android12_5_10_resukisu: ${{ steps.resolve.outputs.susfs_commit_android12_5_10_resukisu }}
+      susfs_commit_android13_5_10_resukisu: ${{ steps.resolve.outputs.susfs_commit_android13_5_10_resukisu }}
+      susfs_commit_android13_5_15_resukisu: ${{ steps.resolve.outputs.susfs_commit_android13_5_15_resukisu }}
+      susfs_commit_android14_5_15_resukisu: ${{ steps.resolve.outputs.susfs_commit_android14_5_15_resukisu }}
+      susfs_commit_android14_6_1_resukisu: ${{ steps.resolve.outputs.susfs_commit_android14_6_1_resukisu }}
+      susfs_commit_android15_6_6_resukisu: ${{ steps.resolve.outputs.susfs_commit_android15_6_6_resukisu }}
+      susfs_commit_android16_6_12_resukisu: ${{ steps.resolve.outputs.susfs_commit_android16_6_12_resukisu }}
+      ksu_commit: ${{ steps.resolve.outputs.ksu_commit }}
+      resukisu_commit: ${{ steps.resolve.outputs.resukisu_commit }}
+    steps:
+      - name: Resolve pinned component commits
+        id: resolve
+        shell: bash
+        run: |
+          set -euo pipefail
+          COMMIT_MODE="${{ inputs.commit_mode }}"
+          echo "commit_mode=${COMMIT_MODE}"
+          retry() {
+            local n=0
+            until [ "$n" -ge 5 ]; do
+              "$@" && return 0
+              n=$((n+1))
+              echo "retry $n/5 failed for: $*" >&2
+              sleep 5
+            done
+            return 1
+          }
+          resolve_sha() { retry git ls-remote "$1" "$2" | awk '{print $1; exit}'; }
+          emit() {
+            if [ -z "$2" ] || ! [[ "$2" =~ ^[0-9a-f]{40}$ ]]; then
+              echo "Failed to resolve $1 (got: ${2:-empty})" >&2
+              exit 1
+            fi
+            echo "$1=$2" >> "$GITHUB_OUTPUT"
+          }
+          # Audited pins - kept in sync with GKI_KernelSU_SUSFS dev
+          PIN_NOMOUNT="9a1431782f390453de54610fb91bdad03eab5b43"
+          PIN_KERNELSU="e38512f1255ea454d34cc2008d2ef7932547fad6"
+          PIN_RESUKISU="0b5efe9e0102c43ca5c41174d500f5a7080cd0c7"
+          declare -A PIN_SUSFS=(
+            [susfs_commit_android12_5_10]="ec785f47d49f7b3871ca9356f450411020af7017"
+            [susfs_commit_android13_5_10]="ed3d6d9c9a2652e1c70f153f5358701e996d646c"
+            [susfs_commit_android13_5_15]="bca0d2333c1a7d717e7278b019d7af7ba1d16005"
+            [susfs_commit_android14_5_15]="d54b51724afa912c4c99bb99731354ce934d1889"
+            [susfs_commit_android14_6_1]="4fc9c1898ea66f51847cdbc0d1473ea4ef525a70"
+            [susfs_commit_android15_6_6]="937215cb3a1b1f333d764c366c7a49972fa8e7a0"
+            [susfs_commit_android16_6_12]="7d91da2d2ce056d1abf378d9199aaf1072d37ab0"
+          )
+          declare -A PIN_SUSFS_RESUKISU=(
+            [susfs_commit_android12_5_10]="ec785f47d49f7b3871ca9356f450411020af7017"
+            [susfs_commit_android13_5_10]="ed3d6d9c9a2652e1c70f153f5358701e996d646c"
+            [susfs_commit_android13_5_15]="bca0d2333c1a7d717e7278b019d7af7ba1d16005"
+            [susfs_commit_android14_5_15]="d54b51724afa912c4c99bb99731354ce934d1889"
+            [susfs_commit_android14_6_1]="4fc9c1898ea66f51847cdbc0d1473ea4ef525a70"
+            [susfs_commit_android15_6_6]="937215cb3a1b1f333d764c366c7a49972fa8e7a0"
+            [susfs_commit_android16_6_12]="7d91da2d2ce056d1abf378d9199aaf1072d37ab0"
+          )
+          pick() {
+            local pinned="$1" repo="$2" ref="$3"
+            if [ "$COMMIT_MODE" = "verified" ] && [ -n "$pinned" ]; then
+              echo "$pinned"
+            else
+              resolve_sha "$repo" "$ref"
+            fi
+          }
+          emit nomount_commit "$(pick "$PIN_NOMOUNT" https://github.com/maxsteeel/nomount.git refs/heads/dev)"
+          emit kernelsu_commit "$(resolve_sha https://github.com/KernelSU-Next/KernelSU-Next.git refs/heads/dev)"
+          echo "kernelsu_branch=dev" >> "$GITHUB_OUTPUT"
+          KERNELSU_COMMIT="$(pick "$PIN_KERNELSU" https://github.com/tiann/KernelSU.git refs/heads/main)"
+          RESUKISU_COMMIT="$(pick "$PIN_RESUKISU" https://github.com/ReSukiSU/ReSukiSU.git refs/heads/main)"
+          emit ksu_commit "$KERNELSU_COMMIT"
+          emit resukisu_commit "$RESUKISU_COMMIT"
+          if [ "${{ inputs.susfs }}" = "true" ]; then
+            NEXT_COMMIT="$(resolve_sha https://github.com/pershoot/KernelSU-Next.git refs/heads/dev-susfs)"
+          else
+            NEXT_COMMIT="$(resolve_sha https://github.com/KernelSU-Next/KernelSU-Next.git refs/heads/dev)"
+          fi
+          mk_entry() { printf '{"root_flavor":"%s","variant":"%s","root_commit":"%s"}' "$1" "$2" "$3"; }
+          case "${{ inputs.root_flavor }}" in
+            KernelSU)
+              echo "root_flavor=kernelsu" >> "$GITHUB_OUTPUT"
+              emit root_commit "$KERNELSU_COMMIT"
+              ROOT_MATRIX="[$(mk_entry kernelsu KernelSU "$KERNELSU_COMMIT")]"
+              ;;
+            KernelSU-Next)
+              echo "root_flavor=next" >> "$GITHUB_OUTPUT"
+              emit root_commit "$NEXT_COMMIT"
+              ROOT_MATRIX="[$(mk_entry next KernelSU-Next "$NEXT_COMMIT")]"
+              ;;
+            ReSukiSU)
+              echo "root_flavor=resukisu" >> "$GITHUB_OUTPUT"
+              emit root_commit "$RESUKISU_COMMIT"
+              ROOT_MATRIX="[$(mk_entry resukisu ReSukiSU "$RESUKISU_COMMIT")]"
+              ;;
+            All)
+              ROOT_MATRIX="[$(mk_entry next KernelSU-Next "$NEXT_COMMIT"),$(mk_entry kernelsu KernelSU "$KERNELSU_COMMIT"),$(mk_entry resukisu ReSukiSU "$RESUKISU_COMMIT")]"
+              echo "root_flavor=" >> "$GITHUB_OUTPUT"
+              echo "root_commit=" >> "$GITHUB_OUTPUT"
+              ;;
+            *) echo "ERROR: unknown root_flavor '${{ inputs.root_flavor }}'" >&2; exit 1 ;;
+          esac
+          echo "root_matrix=$ROOT_MATRIX" >> "$GITHUB_OUTPUT"
+          declare -A SUSFS_BRANCHES=(
+            [susfs_commit_android12_5_10]="gki-android12-5.10"
+            [susfs_commit_android13_5_10]="gki-android13-5.10"
+            [susfs_commit_android13_5_15]="gki-android13-5.15"
+            [susfs_commit_android14_5_15]="gki-android14-5.15"
+            [susfs_commit_android14_6_1]="gki-android14-6.1"
+            [susfs_commit_android15_6_6]="gki-android15-6.6"
+            [susfs_commit_android16_6_12]="gki-android16-6.12"
+          )
+          for key in "${!SUSFS_BRANCHES[@]}"; do
+            emit "$key" "$(pick "${PIN_SUSFS[$key]}" https://gitlab.com/simonpunk/susfs4ksu.git refs/heads/${SUSFS_BRANCHES[$key]})"
+            emit "${key}_resukisu" "$(pick "${PIN_SUSFS_RESUKISU[$key]}" https://gitlab.com/simonpunk/susfs4ksu.git refs/heads/${SUSFS_BRANCHES[$key]})"
+          done
+          echo "Resolved:"
+          env | grep -E '^(nomount_commit|kernelsu_commit|root_commit|susfs_commit_)' | sort || true
+
   build-samsung:
+    needs: resolve-sources
+    strategy:
+      fail-fast: false
+      matrix:
+        include: ${{ fromJSON(needs.resolve-sources.outputs.root_matrix) }}
     uses: ./.github/workflows/kernel-samsung.yml
     secrets: inherit
     with:
+      root_flavor: ${{ matrix.root_flavor }}
+      root_commit: ${{ matrix.root_commit }}
+      variant: ${{ matrix.variant }}
+      susfs_commit: ${{ matrix.root_flavor == 'resukisu' && needs.resolve-sources.outputs.susfs_commit_android14_6_1_resukisu || needs.resolve-sources.outputs.susfs_commit_android14_6_1 }}
+      susfs_commit_android12_5_10: ${{ needs.resolve-sources.outputs.susfs_commit_android12_5_10 }}
+      susfs_commit_android13_5_10: ${{ needs.resolve-sources.outputs.susfs_commit_android13_5_10 }}
+      susfs_commit_android13_5_15: ${{ needs.resolve-sources.outputs.susfs_commit_android13_5_15 }}
+      susfs_commit_android14_5_15: ${{ needs.resolve-sources.outputs.susfs_commit_android14_5_15 }}
+      susfs_commit_android14_6_1: ${{ needs.resolve-sources.outputs.susfs_commit_android14_6_1 }}
+      susfs_commit_android15_6_6: ${{ needs.resolve-sources.outputs.susfs_commit_android15_6_6 }}
+      susfs_commit_android16_6_12: ${{ needs.resolve-sources.outputs.susfs_commit_android16_6_12 }}
+      nomount_commit: ${{ needs.resolve-sources.outputs.nomount_commit }}
       susfs: ${{ inputs.susfs }}
       bbg: ${{ inputs.bbg }}
       unicodefix: ${{ inputs.unicodefix }}
       zeromount: ${{ inputs.zeromount }}
       nomount: ${{ inputs.nomount }}
-      ksun: ${{ inputs.ksun }}
       droidspace: ${{ inputs.droidspace }}
       ntsync: ${{ inputs.ntsync }}
       bbrv3: ${{ inputs.bbrv3 }}
@@ -131,15 +295,16 @@ jobs:
     if: inputs.release_type != 'Actions'
     needs:
       - build-samsung
+      - resolve-sources
 
     env:
       GH_TOKEN: ${{ github.token }}
-      RELEASE_NAME: "Samsung GKI Kernels With KSUN v3.3.0 & SUSFS v2.3.0"
+      RELEASE_NAME: "Samsung Kernels With SUSFS v2.3.0"
       RELEASE_BODY: ""
     steps:
       - name: Free Disk Space
         if: true
-        uses: endersonmenezes/free-disk-space@v3  # Use @main for latest, @v3 for stable
+        uses: endersonmenezes/free-disk-space@v3
         with:
           remove_android: true
           remove_dotnet: true
@@ -149,8 +314,8 @@ jobs:
           remove_packages: "azure-cli google-cloud-cli microsoft-edge-stable google-chrome-stable firefox postgresql* temurin-* *llvm* mysql* dotnet-sdk-*"
           remove_packages_one_command: true
           remove_folders: "/usr/share/swift /usr/share/miniconda /usr/share/az* /usr/local/lib/node_modules /usr/local/share/chromium /usr/local/share/powershell /usr/local/julia /usr/local/aws-cli /usr/local/aws-sam-cli /usr/share/gradle"
-          rm_cmd: "rmz"  # Use 'rmz' for faster deletion (default: 'rm')
-          rmz_version: "3.1.1"  # Required when rm_cmd is 'rmz'
+          rm_cmd: "rmz"
+          rmz_version: "3.1.1"
           testing: false
       
       - name: Checkout code
@@ -177,13 +342,14 @@ jobs:
 
       - name: get commit hashes
         run: |
-         echo "SUSFS_510=$(git ls-remote https://gitlab.com/simonpunk/susfs4ksu.git refs/heads/gki-android12-5.10 | cut -f1)" >> $GITHUB_ENV
-         echo "SUSFS_515=$(git ls-remote https://gitlab.com/simonpunk/susfs4ksu.git refs/heads/gki-android13-5.15 | cut -f1)" >> $GITHUB_ENV
-         echo "SUSFS_61=$(git ls-remote https://gitlab.com/simonpunk/susfs4ksu.git refs/heads/gki-android14-6.1 | cut -f1)" >> $GITHUB_ENV
-         echo "SUSFS_66=$(git ls-remote https://gitlab.com/simonpunk/susfs4ksu.git refs/heads/gki-android15-6.6 | cut -f1)" >> $GITHUB_ENV
-         echo "KSUN_HASH=$(git ls-remote https://github.com/pershoot/KernelSU-Next.git refs/heads/dev | cut -f1)" >> $GITHUB_ENV
-         echo "BBG_HASH=$(git ls-remote https://github.com/vc-teahouse/Baseband-guard.git refs/heads/main | cut -f1)" >> $GITHUB_ENV
-         echo "NM_HASH=$(git ls-remote https://github.com/maxsteeel/nomount.git refs/heads/master | cut -f1)" >> $GITHUB_ENV
+         echo "SUSFS_510=${{ needs.resolve-sources.outputs.susfs_commit_android12_5_10 }}" >> $GITHUB_ENV
+         echo "SUSFS_515=${{ needs.resolve-sources.outputs.susfs_commit_android13_5_15 }}" >> $GITHUB_ENV
+         echo "SUSFS_61=${{ needs.resolve-sources.outputs.susfs_commit_android14_6_1 }}" >> $GITHUB_ENV
+         echo "SUSFS_66=${{ needs.resolve-sources.outputs.susfs_commit_android15_6_6 }}" >> $GITHUB_ENV
+         echo "KSU_COMMIT=${{ needs.resolve-sources.outputs.ksu_commit }}" >> $GITHUB_ENV
+         echo "KSUN_COMMIT=${{ needs.resolve-sources.outputs.kernelsu_commit }}" >> $GITHUB_ENV
+         echo "RESUKI_COMMIT=${{ needs.resolve-sources.outputs.resukisu_commit }}" >> $GITHUB_ENV
+         echo "NM_HASH=${{ needs.resolve-sources.outputs.nomount_commit }}" >> $GITHUB_ENV
 
       - name: Set release body
         run: |
@@ -197,16 +363,13 @@ jobs:
           Features:
           EOF
 
-          if [ "${{ inputs.ksun }}" = "true" ]; then
-          cat <<'EOF' >> release_body.md
-          -> KernelSU-Next v3.3.0 - https://github.com/KernelSU-Next/KernelSU-Next
-          NOTE: For kernel integration I am using pershoots fork of KernelSU-next. He has claimed that even though everything works fine, the dev has warned that this is not production ready!
+          cat <<EOF >> release_body.md
+          -> Root: ${{ inputs.root_flavor }} (commit_mode: ${{ inputs.commit_mode }})
           EOF
-          fi
 
           if [ "${{ inputs.susfs }}" = "true" ]; then
           cat <<'EOF' >> release_body.md
-          -> SUSFS v2.3.0 - https://gitlab.com/simonpunk/susfs4ksu
+          -> SUSFS v2.3.0 - https://gitlab.com/simonpunk/susfs4ksu
           -> SUSFS Inline hooks
           EOF
           fi
@@ -284,39 +447,17 @@ jobs:
           -> https://github.com/sidex15/ksu_module_susfs
           -> https://github.com/rrr333nnn333/BRENE
 
-          Commit Hashes:
+          Pinned Commits (verified mode):
           EOF
-          if ${{ inputs.ksun }} == 'true' ]]; then
-          cat <<'EOF' >> release_body.md
-          
-          KSUN: ${{ env.KSUN_HASH }}
-          
-          EOF
-          fi
-          if ${{ inputs.susfs }} == 'true' ]]; then
-          cat <<'EOF' >> release_body.md
-          SUSFS: 
-          android12-5.10: ${{ env.SUSFS_510 }}
-          android13-5.15: ${{ env.SUSFS_515 }}
-          android14-6.1: ${{ env.SUSFS_61 }}
-          android15-6.6: ${{ env.SUSFS_66 }}
-          
-          EOF
-          fi
-          
-          if ${{ inputs.bbg }} == 'true' ]]; then
-          cat <<'EOF' >> release_body.md
-          BBG: ${{ env.BBG_HASH }}
-          
-          EOF
-          fi
-          
-          if ${{ inputs.nomount }} == 'true' ]]; then
-          cat <<'EOF' >> release_body.md
+          cat <<EOF >> release_body.md
+          KernelSU: ${{ env.KSU_COMMIT }}
+          KernelSU-Next: ${{ env.KSUN_COMMIT }}
+          ReSukiSU: ${{ env.RESUKI_COMMIT }}
+          SUSFS 5.10: ${{ env.SUSFS_510 }}
+          SUSFS 6.1: ${{ env.SUSFS_61 }}
+          SUSFS 6.6: ${{ env.SUSFS_66 }}
           NoMount: ${{ env.NM_HASH }}
-          
           EOF
-          fi
 
       - name: Create GitHub Release
         uses: softprops/action-gh-release@v3
@@ -335,11 +476,9 @@ jobs:
             echo "No artifact directories found under ./downloaded-artifacts; skipping upload."
           else
             for dir in "${anykernel_dirs[@]}"; do
-              # Check if this is an AnyKernel3 artifact directory
               if [[ "$(basename "$dir")" == *"-AnyKernel3" ]]; then
                 artifact_name=$(basename "$dir")
                 echo "Creating ZIP for $artifact_name..."
-                # Navigate into the directory and zip its contents directly
                 cd "$dir"
                 zip -r -9 "../../${artifact_name}.zip" ./*
                 cd - > /dev/null
@@ -348,23 +487,3 @@ jobs:
               fi
             done
           fi
-            
-#      - name: Send Telegram Notification
-#        if: inputs.release_type != 'Actions'
-#        run: |
-#          RELEASE_TYPE_TEXT=""
-#          if [ "${{ inputs.release_type }}" == "Pre-Release" ]; then
-#            RELEASE_TYPE_TEXT="🧪 *Pre-Release*"
-#          else
-#            RELEASE_TYPE_TEXT="🚀 *Release*"
-#          fi
-#          
-#          curl -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \
-#            -F chat_id="${{ secrets.TELEGRAM_CHAT_ID }}" \
-#            -F message_thread_id="${{ secrets.TELEGRAM_TOPIC_ID_GKI }}" \
-#            -F text="
-#            🌽 *New Kernel $RELEASE_TYPE_TEXT Uploaded*  
-#            📦 *Repository:* [${{ github.repository }}](https://github.com/${{ github.repository }})  
-#            ✏️ *Commit:* [${{ github.sha }}](https://github.com/${{ github.repository }}/commit/${{ github.sha }})  
-#            [🔗 View GitHub Release](https://github.com/${{ github.repository }}/releases/tag/${{ env.NEW_TAG }})" \
-#            -F parse_mode="Markdown"

+ 61 - 82
README.md

@@ -2,128 +2,107 @@
 
 # 🔥 Wild Kernels for Samsung
 
+[![License: GPL-3.0](https://img.shields.io/badge/license-GPL--3.0-blue.svg)](LICENSE)
+[![Third-Party Notices](https://img.shields.io/badge/notices-THIRD__PARTY_NOTICES-lightgrey.svg)](THIRD_PARTY_NOTICES.md)
 [![KernelSU](https://img.shields.io/badge/KernelSU-Supported-green)](https://kernelsu.org/)
 [![SUSFS](https://img.shields.io/badge/SUSFS-Integrated-orange)](https://gitlab.com/simonpunk/susfs4ksu)
 
 </div>
-<div align="center">
-## ⚠️ Your warranty is no longer valid!
-
-I am **not responsible** for bricked devices, damaged hardware, or any issues that arise from using this kernel.
-
-**Please** do thorough research and fully understand the features included in this kernel before flashing it!
-
-By flashing this kernel, **YOU** are choosing to make these modifications. If something goes wrong, **do not blame me**!
-
----
 
-### 🚨 Proceed at your own risk!
+> [!CAUTION]
+> Wild Kernels is not responsible for bricked devices or damage. By flashing, you assume all risk. Back up your data and understand the risks before flashing.
 
 ---
 
-## 🔧 Available Kernels
+## About
 
-| Kernel | Repository | Status |
-|--------|------------|--------|
-| 🏗️ **GKI** | [GKI_KernelSU_SUSFS](https://github.com/WildKernels/GKI_KernelSU_SUSFS) | ✅ Active |
-| 👑 **Sultan** | [Sultan_KernelSU_SUSFS](https://github.com/WildKernels/Sultan_KernelSU_SUSFS) | ✅ Active |
-| 📱 **OnePlus** | [OnePlus_KernelSU_SUSFS](https://github.com/WildKernels/OnePlus_KernelSU_SUSFS) | ✅ Active |
-| 📱 **Samsung** | [Samsung_KernelSU_SUSFS](https://github.com/WildKernels/Samsung_KernelSU_SUSFS) | ✅ Active |
+Samsung kernels built on [Samsung's sources](https://github.com/WildKernels/manifest) with KernelSU and SUSFS for root hiding and detection evasion — per-model branches (OneUI) built from Samsung manifests. Now with multiple root-implementation flavors.
 
 ---
 
-## 🔗 Additional Resources
+## Features
 
-- 🩹 [Kernel Patches](https://github.com/WildKernels/kernel_patches)
-- ⚡ [Kernel Flasher](https://github.com/fatalcoder524/KernelFlasher)
+- **KernelSU / KernelSU-Next / ReSukiSU** — selectable root implementations (pinned commits; Next tracks latest for SUSFS API match)
+- **susfs4ksu** — root hiding (incl. Ptrace Leak Fix, Unicode Fix) — pinned per Android/kernel-version, branch-tip for Next
+- **NoMount / ZeroMount** — mount metamodule variants
+- **Baseband Guard** — partition protection
+- **Networking** — WireGuard, BBRv3, IPSet, CIFS, TTL/HL target, IPv6 NAT
+- **BPF** — BTF / eBPF / FUSE-BPF
+- **Performance** — incl. NTSync, build optimizations, LTO per kernel
+- **DroidSpaces** — container runtime
 
----
-
-## 📋 Installation Instructions
-
-For GKI installation, please follow the official guide:
-
-📖 **[KernelSU Installation Guide](https://kernelsu.org/guide/installation.html)**
+> [!TIP]
+> Full per-feature documentation: [GKI docs/features.md](https://github.com/WildKernels/GKI_KernelSU_SUSFS/blob/dev/docs/features.md) — same feature set, Samsung sources.
 
 ---
 
-## ✨ Features
+## Installation
 
-- 🔐 **KernelSU**: A root solution for Android GKI devices that works in kernel mode and grants root permission to userspace applications directly in kernel space
-- 🛡️ **SUSFS**: An addon root hiding kernel patches and userspace module for KernelSU
+See **[KernelSU Installation Guide](https://kernelsu.org/guide/installation.html)**. Flash the AnyKernel3 zip for your model/OneUI branch via custom recovery.
 
 ---
 
-| 🔧 **Project** | 👨‍💻 **Developer** | 🔗 **Link** |
-|:---------------:|:----------------:|:-----------:|
-| **KernelSU** | tiann | [![GitHub](https://img.shields.io/badge/GitHub-tiann-blue?style=flat-square&logo=github)](https://github.com/tiann/KernelSU) |
-| **KernelSU-Next** | rifsxd | [![GitHub](https://img.shields.io/badge/GitHub-rifsxd-blue?style=flat-square&logo=github)](https://github.com/KernelSU-Next/KernelSU-Next) |
-| **Magic-KSU** | 5ec1cff | [![GitHub](https://img.shields.io/badge/GitHub-5ec1cff-blue?style=flat-square&logo=github)](https://github.com/5ec1cff/KernelSU) |
-| **SUSFS** | simonpunk | [![GitLab](https://img.shields.io/badge/GitLab-simonpunk-orange?style=flat-square&logo=gitlab)](https://gitlab.com/simonpunk/susfs4ksu.git) |
-| **SUSFS Module** | sidex15 | [![GitHub](https://img.shields.io/badge/GitHub-sidex15-blue?style=flat-square&logo=github)](https://github.com/sidex15) |
-| **Sultan Kernels** | kerneltoast | [![GitHub](https://img.shields.io/badge/GitHub-kerneltoast-blue?style=flat-square&logo=github)](https://github.com/kerneltoast) |
+## Supported Devices
 
-🙏 Special thanks to the open-source community for their contributions!
+Samsung branches are per model + OneUI version (e.g. `SM-S938B-Oneui8.5`, `SM-S928B-Oneui7`). See the matrix in [`.github/workflows/kernel-samsung.yml`](.github/workflows/kernel-samsung.yml) for the full list.
 
 ---
 
-## 💬 Support
+## Our Projects
 
-If you encounter any issues or need help, feel free to:
-- 🐛 Open an issue in this repository
-- 💬 Reach out to me directly
+| Device | Repository | Description |
+|--------|------------|-------------|
+| **Multi** | [GKI_KernelSU_SUSFS](https://github.com/WildKernels/GKI_KernelSU_SUSFS) | Google GKI sources — built to be generic and work across many devices |
+| **Pixel** | [Sultan_KernelSU_SUSFS](https://github.com/WildKernels/Sultan_KernelSU_SUSFS) | Custom kernels for specific Pixel devices — built from Sultan sources |
+| **Samsung** | [Samsung_KernelSU_SUSFS](https://github.com/WildKernels/Samsung_KernelSU_SUSFS) | Built from Samsung sources and manifest |
+| **OnePlus** | [OnePlus_KernelSU_SUSFS](https://github.com/WildKernels/OnePlus_KernelSU_SUSFS) | Built from OnePlus sources and manifest |
 
 ---
 
-## ⚠️ Disclaimer
-
-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
-- 🧠 Understand the risks before proceeding
-
-**🚨 Proceed at your own risk!**
+## Special Thanks
+
+**These amazing people and projects make this possible:**
+- **KernelSU** — [tiann](https://github.com/tiann/KernelSU)
+- **KernelSU-Next** — [rifsxd](https://github.com/KernelSU-Next/KernelSU-Next)
+- **KernelSU-Next SUSFS Fork** — [pershoot](https://github.com/pershoot/KernelSU-Next)
+- **ReSukiSU** — [ReSukiSU](https://github.com/ReSukiSU/ReSukiSU)
+- **Magic-KSU** — [5ec1cff](https://github.com/5ec1cff/KernelSU)
+- **SUSFS** — [simonpunk](https://gitlab.com/simonpunk/susfs4ksu)
+- **SUSFS Module** — [sidex15](https://github.com/sidex15)
+- **NoMount** — [maxsteeel](https://github.com/maxsteeel/nomount)
+- **DroidSpaces-OSS** — [ravindu644](https://github.com/ravindu644/Droidspaces-OSS)
+- **Baseband-guard (BBG)** — [vc-teahouse](https://github.com/vc-teahouse/Baseband-guard)
+- **Kernel Patches** — [WildKernels/kernel_patches](https://github.com/WildKernels/kernel_patches)
+- **AnyKernel3** — [osm0sis](https://github.com/osm0sis/AnyKernel3)
+- **Sultan Kernels (Pixel)** — [kerneltoast](https://github.com/kerneltoast)
+- **Device Boot Fix** — [Boot fix commit](https://github.com/Anything-at-25-00/android_kernel_common_android12-5.10/commit/2476d262b597fe8af82cfb7aaf96676f51c6b4ed)
+
+**Contributors to this repository:**
+[![Contributors](https://contrib.rocks/image?repo=WildKernels/Samsung_KernelSU_SUSFS)](https://github.com/WildKernels/Samsung_KernelSU_SUSFS/graphs/contributors)
+Have an idea or improvement in mind? Contributions are always welcome — feel free to open a pull request or share your thoughts!
 
 ---
 
-<div align="center">
+## Community
 
-## 📱 Connect With Us
+<div align="center">
 
-[![Telegram](https://img.shields.io/badge/Telegram-Jimsterino98-blue?logo=telegram)](https://t.me/Ngadhnjim98)
-[![Telegram Group](https://img.shields.io/badge/Telegram-Wild__Kernels-blue?logo=telegram)](https://t.me/WildKernelsTG)
+[![Telegram Group](https://img.shields.io/badge/Telegram-%40WildKernelsTG-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/WildKernelsTG)
+[![Telegram DM](https://img.shields.io/badge/Telegram-%40TheWildJames-26A5E4?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/TheWildJames)
 
 </div>
 
----
-
-## 🌟 Special Thanks
-
-**These amazing people help make this project possible! ❤️**
-
-| Contributor | Contribution |
-|-------------|-------------|
-| 🛡️ [simonpunk](https://gitlab.com/simonpunk/susfs4ksu.git) | Created SUSFS! |
-| 📦 [sidex15](https://github.com/sidex15) | Created module! |
-| 🩹 [backslashxx](https://github.com/backslashxx) | Helped with patches! |
-| 🔧 [Teemo](https://github.com/liqideqq) | Helped with patches! |
-| 💝 [幕落](https://github.com/MuLuo688) | Donation! |
-| 🛡️ [vc-teahouse](https://github.com/vc-teahouse) | Created Baseband-guard (BBG)! |
-
-*If you have contributed and are not listed here, please remind me!* 🙏
+Need help? Open an issue in this repository or reach out on Telegram. Please ask in the [WildKernelsTG group](https://t.me/WildKernelsTG) first for general issues. DMs to [@TheWildJames](https://t.me/TheWildJames) are always open.
 
 ---
-<div align="center">
-## 💝 Donations
-
-Any and all donations are appreciated!
 
-PayPal: [paypal.me/NgadhnjimHoxha](paypal.me/NgadhnjimHoxha)
+## Donations
 
-Wise: [wise.com/pay/me/ngadhnjimh](wise.com/pay/me/ngadhnjimh)
-
-Ko-fi: [https://ko-fi.com/jimsterino98](https://ko-fi.com/jimsterino98)
-
-Buy me a coffee: [buymeacoffee.com/jimsterino98](buymeacoffee.com/jimsterino98)
+> [!IMPORTANT]
+> **Kind note:** A donation is truly just a gift — not a payment for support, features, or priority. It doesn't unlock anything extra on our side and doesn't change how we help you; everyone gets the same community support whether you donate or not. Think of it as a kind “thank you” to help keep development going — not a transaction. If you do choose to give, we're genuinely grateful, but please never feel obligated.
 
+- PayPal: [paypal.me/NgadhnjimHoxha](paypal.me/NgadhnjimHoxha)
+- Wise: [wise.com/pay/me/ngadhnjimh](wise.com/pay/me/ngadhnjimh)
+- Ko-fi: [https://ko-fi.com/jimsterino98](https://ko-fi.com/jimsterino98)
+- Buy me a coffee: [buymeacoffee.com/jimsterino98](buymeacoffee.com/jimsterino98)
 DM on telegram for crypto donations!
-