From 694d08e67c45a8bd49acd88ec70436653adcde32 Mon Sep 17 00:00:00 2001 From: hawkff <109485367+hawkff@users.noreply.github.com> Date: Mon, 15 Jun 2026 15:49:16 -0400 Subject: [PATCH 1/8] feat: bundle Mieru native binary (no external plugin required) Build the Mieru client from source for all 4 Android ABIs and bundle it as app/executableSo//libmieru.so, so Mieru profiles work without installing the separate moe.matsuri.exe.mieru plugin. - buildScript/lib/mieru.sh: cross-compiles enfein/mieru v3.34.0 via the NDK for arm64-v8a, armeabi-v7a, x86, x86_64 (./run lib mieru). - PluginManager.initNativeInternal: resolve mieru-plugin -> libmieru.so from nativeLibraryDir, mirroring the bundled-Hysteria mechanism. Falls back to the external APK plugin when the bundled binary is absent. - Executable.EXECUTABLES: add libmieru.so so orphaned processes are cleaned up. - ci.yml: build + cache the Mieru binaries (Go+NDK) and restore before Gradle. Reuses the existing MieruBean / MieruFmt buildMieruConfig / BoxInstance run contract (config via MIERU_CONFIG_JSON_FILE, socket protection via MIERU_PROTECT_PATH) unchanged; upstream mieru v3 honors both. --- .github/workflows/ci.yml | 32 +++++++++++ .../io/nekohasekai/sagernet/bg/Executable.kt | 2 +- .../sagernet/plugin/PluginManager.kt | 1 + buildScript/lib/mieru.sh | 55 +++++++++++++++++++ 4 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 buildScript/lib/mieru.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a816079f..d283d7b06 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,11 +37,35 @@ jobs: - name: Native Build if: steps.cache.outputs.cache-hit != 'true' run: ./run lib core + mieru: + name: Native Build (Mieru) + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + - name: Mieru Status + run: cat buildScript/lib/mieru.sh | sha1sum > mieru_status + - name: Mieru Cache + id: cache + uses: actions/cache@v5 + with: + path: | + app/executableSo + key: ${{ hashFiles('.github/workflows/*', 'mieru_status') }}-mieru-ci + - name: Install Golang + if: steps.cache.outputs.cache-hit != 'true' + uses: actions/setup-go@v6 + with: + go-version: '1.24.9' + - name: Mieru Build + if: steps.cache.outputs.cache-hit != 'true' + run: ./run lib mieru build: name: Build OSS APK runs-on: ubuntu-latest needs: - libcore + - mieru steps: - name: Checkout uses: actions/checkout@v5 @@ -60,6 +84,14 @@ jobs: path: | app/libs/libcore.aar key: ${{ hashFiles('.github/workflows/*', 'golang_status', 'libcore_status') }}-ci + - name: Mieru Status + run: cat buildScript/lib/mieru.sh | sha1sum > mieru_status + - name: Mieru Cache + uses: actions/cache@v5 + with: + path: | + app/executableSo + key: ${{ hashFiles('.github/workflows/*', 'mieru_status') }}-mieru-ci - name: Gradle cache uses: actions/cache@v5 with: diff --git a/app/src/main/java/io/nekohasekai/sagernet/bg/Executable.kt b/app/src/main/java/io/nekohasekai/sagernet/bg/Executable.kt index 5b860b35f..511154ff0 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/bg/Executable.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/bg/Executable.kt @@ -10,7 +10,7 @@ import androidx.core.text.isDigitsOnly object Executable { private val EXECUTABLES = setOf( - "libtrojan.so", "libtrojan-go.so", "libnaive.so", "libtuic.so", "libhysteria.so" + "libtrojan.so", "libtrojan-go.so", "libnaive.so", "libtuic.so", "libhysteria.so", "libmieru.so" ) fun killAll(alsoKillBg: Boolean = false) { diff --git a/app/src/main/java/io/nekohasekai/sagernet/plugin/PluginManager.kt b/app/src/main/java/io/nekohasekai/sagernet/plugin/PluginManager.kt index 10307a1f7..87cc9fa40 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/plugin/PluginManager.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/plugin/PluginManager.kt @@ -73,6 +73,7 @@ object PluginManager { return when (pluginId) { "hysteria-plugin" -> soIfExist("libhysteria.so") "hysteria2-plugin" -> soIfExist("libhysteria2.so") + "mieru-plugin" -> soIfExist("libmieru.so") else -> null } } diff --git a/buildScript/lib/mieru.sh b/buildScript/lib/mieru.sh new file mode 100644 index 000000000..e04100192 --- /dev/null +++ b/buildScript/lib/mieru.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Build the Mieru client binary for all Android ABIs and install them as +# bundled native executables (app/executableSo//libmieru.so). +# +# This lets NekoBox run Mieru profiles without the separate external plugin +# (moe.matsuri.exe.mieru). PluginManager.initNativeInternal resolves +# "mieru-plugin" -> libmieru.so from nativeLibraryDir. +# +# Usage: ./run lib mieru +set -e + +source "buildScript/init/env.sh" + +# Mieru release tag to build from source. +MIERU_VERSION="${MIERU_VERSION:-v3.34.0}" + +DEPS="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin" +# macOS NDK host dir is darwin-x86_64; fall back if linux path is absent. +if [ ! -d "$DEPS" ]; then + DEPS="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin" +fi + +WORK="$(pwd)/.mieru-build" +OUT="$(pwd)/app/executableSo" + +# Fetch source (shallow clone at the pinned tag). +if [ ! -d "$WORK/.git" ]; then + rm -rf "$WORK" + git clone --depth 1 --branch "$MIERU_VERSION" https://github.com/enfein/mieru.git "$WORK" +else + git -C "$WORK" fetch --depth 1 origin "refs/tags/$MIERU_VERSION" + git -C "$WORK" checkout -q FETCH_HEAD +fi + +pushd "$WORK" >/dev/null + +build_abi() { + local abi="$1" goarch="$2" cc="$3" goarm="$4" + echo ">> building libmieru.so for $abi" + mkdir -p "$OUT/$abi" + env GOOS=android GOARCH="$goarch" ${goarm:+GOARM=$goarm} CGO_ENABLED=1 \ + CC="$DEPS/$cc" \ + go build -trimpath -ldflags='-s -w' \ + -o "$OUT/$abi/libmieru.so" ./cmd/mieru +} + +build_abi "arm64-v8a" "arm64" "aarch64-linux-android21-clang" +build_abi "armeabi-v7a" "arm" "armv7a-linux-androideabi21-clang" "7" +build_abi "x86" "386" "i686-linux-android21-clang" +build_abi "x86_64" "amd64" "x86_64-linux-android21-clang" + +popd >/dev/null + +echo ">> installed Mieru binaries:" +ls -la "$OUT"/*/libmieru.so From 19abde545d2dbed1f0431073df07c90f79694e64 Mon Sep 17 00:00:00 2001 From: hawkff <109485367+hawkff@users.noreply.github.com> Date: Mon, 15 Jun 2026 15:49:52 -0400 Subject: [PATCH 2/8] chore: mark buildScript/lib/mieru.sh executable --- buildScript/lib/mieru.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 buildScript/lib/mieru.sh diff --git a/buildScript/lib/mieru.sh b/buildScript/lib/mieru.sh old mode 100644 new mode 100755 From 7f3fec1a85fd50f65083b820a448f5e5d59d3e9a Mon Sep 17 00:00:00 2001 From: hawkff <109485367+hawkff@users.noreply.github.com> Date: Mon, 15 Jun 2026 15:57:45 -0400 Subject: [PATCH 3/8] ci: harden Mieru build wiring across all workflows Address review feedback and ensure shipping APKs bundle Mieru: - Add the Mieru native-build job + cache restore + artifact verification to build.yml, preview.yml, release.yml (previously only ci.yml had it), so release/preview APKs also bundle libmieru.so. - Include buildScript/init/env.sh in the Mieru cache-status hash (mieru.sh sources it). - Pin MIERU_VERSION as a workflow env and include it in the cache key so a version override invalidates stale binaries. - Add a 'Verify Mieru Artifacts' step in each build job that fails fast if any ABI's libmieru.so is missing (guards against a silent cache miss shipping an APK without the bundled binary). - mieru.sh: validate ANDROID_NDK_HOME is set before use. --- .github/workflows/build.yml | 45 +++++++++++++++++++++++++++++++++++ .github/workflows/ci.yml | 21 ++++++++++++---- .github/workflows/preview.yml | 45 +++++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 45 +++++++++++++++++++++++++++++++++++ buildScript/lib/mieru.sh | 5 ++++ 5 files changed, 157 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e15bf3f92..c96304740 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,11 +32,39 @@ jobs: - name: Native Build if: steps.cache.outputs.cache-hit != 'true' run: ./run lib core + mieru: + name: Native Build (Mieru) + runs-on: ubuntu-latest + env: + MIERU_VERSION: v3.34.0 + steps: + - name: Checkout + uses: actions/checkout@v5 + - name: Mieru Status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + - name: Mieru Cache + id: cache + uses: actions/cache@v5 + with: + path: | + app/executableSo + key: ${{ hashFiles('.github/workflows/*', 'mieru_status') }}-${{ env.MIERU_VERSION }}-mieru + - name: Install Golang + if: steps.cache.outputs.cache-hit != 'true' + uses: actions/setup-go@v6 + with: + go-version: '1.24.9' + - name: Mieru Build + if: steps.cache.outputs.cache-hit != 'true' + run: ./run lib mieru build: name: Build OSS APK runs-on: ubuntu-latest + env: + MIERU_VERSION: v3.34.0 needs: - libcore + - mieru steps: - name: Checkout uses: actions/checkout@v5 @@ -50,6 +78,23 @@ jobs: path: | app/libs/libcore.aar key: ${{ hashFiles('.github/workflows/*', 'golang_status', 'libcore_status') }} + - name: Mieru Status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + - name: Mieru Cache + id: mieru-cache + uses: actions/cache@v5 + with: + path: | + app/executableSo + key: ${{ hashFiles('.github/workflows/*', 'mieru_status') }}-${{ env.MIERU_VERSION }}-mieru + - name: Verify Mieru Artifacts + run: | + for abi in arm64-v8a armeabi-v7a x86 x86_64; do + if [ ! -x "app/executableSo/$abi/libmieru.so" ]; then + echo "Error: missing app/executableSo/$abi/libmieru.so (Mieru cache miss)" >&2 + exit 1 + fi + done - name: Gradle cache uses: actions/cache@v5 with: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d283d7b06..45dbcb662 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,18 +40,20 @@ jobs: mieru: name: Native Build (Mieru) runs-on: ubuntu-latest + env: + MIERU_VERSION: v3.34.0 steps: - name: Checkout uses: actions/checkout@v5 - name: Mieru Status - run: cat buildScript/lib/mieru.sh | sha1sum > mieru_status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status - name: Mieru Cache id: cache uses: actions/cache@v5 with: path: | app/executableSo - key: ${{ hashFiles('.github/workflows/*', 'mieru_status') }}-mieru-ci + key: ${{ hashFiles('.github/workflows/*', 'mieru_status') }}-${{ env.MIERU_VERSION }}-mieru-ci - name: Install Golang if: steps.cache.outputs.cache-hit != 'true' uses: actions/setup-go@v6 @@ -63,6 +65,8 @@ jobs: build: name: Build OSS APK runs-on: ubuntu-latest + env: + MIERU_VERSION: v3.34.0 needs: - libcore - mieru @@ -85,13 +89,22 @@ jobs: app/libs/libcore.aar key: ${{ hashFiles('.github/workflows/*', 'golang_status', 'libcore_status') }}-ci - name: Mieru Status - run: cat buildScript/lib/mieru.sh | sha1sum > mieru_status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status - name: Mieru Cache + id: mieru-cache uses: actions/cache@v5 with: path: | app/executableSo - key: ${{ hashFiles('.github/workflows/*', 'mieru_status') }}-mieru-ci + key: ${{ hashFiles('.github/workflows/*', 'mieru_status') }}-${{ env.MIERU_VERSION }}-mieru-ci + - name: Verify Mieru Artifacts + run: | + for abi in arm64-v8a armeabi-v7a x86 x86_64; do + if [ ! -x "app/executableSo/$abi/libmieru.so" ]; then + echo "Error: missing app/executableSo/$abi/libmieru.so (Mieru cache miss)" >&2 + exit 1 + fi + done - name: Gradle cache uses: actions/cache@v5 with: diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index c59e303ae..f942fa1b0 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -28,11 +28,39 @@ jobs: - name: Native Build if: steps.cache.outputs.cache-hit != 'true' run: ./run lib core + mieru: + name: Native Build (Mieru) + runs-on: ubuntu-latest + env: + MIERU_VERSION: v3.34.0 + steps: + - name: Checkout + uses: actions/checkout@v5 + - name: Mieru Status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + - name: Mieru Cache + id: cache + uses: actions/cache@v5 + with: + path: | + app/executableSo + key: ${{ hashFiles('.github/workflows/*', 'mieru_status') }}-${{ env.MIERU_VERSION }}-mieru + - name: Install Golang + if: steps.cache.outputs.cache-hit != 'true' + uses: actions/setup-go@v6 + with: + go-version: '1.24.9' + - name: Mieru Build + if: steps.cache.outputs.cache-hit != 'true' + run: ./run lib mieru build: name: Build OSS APK runs-on: ubuntu-latest + env: + MIERU_VERSION: v3.34.0 needs: - libcore + - mieru steps: - name: Checkout uses: actions/checkout@v5 @@ -46,6 +74,23 @@ jobs: path: | app/libs/libcore.aar key: ${{ hashFiles('.github/workflows/*', 'golang_status', 'libcore_status') }} + - name: Mieru Status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + - name: Mieru Cache + id: mieru-cache + uses: actions/cache@v5 + with: + path: | + app/executableSo + key: ${{ hashFiles('.github/workflows/*', 'mieru_status') }}-${{ env.MIERU_VERSION }}-mieru + - name: Verify Mieru Artifacts + run: | + for abi in arm64-v8a armeabi-v7a x86 x86_64; do + if [ ! -x "app/executableSo/$abi/libmieru.so" ]; then + echo "Error: missing app/executableSo/$abi/libmieru.so (Mieru cache miss)" >&2 + exit 1 + fi + done - name: Gradle cache uses: actions/cache@v5 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2252e059d..1abbc8843 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,11 +34,39 @@ jobs: - name: Native Build if: steps.cache.outputs.cache-hit != 'true' run: ./run lib core + mieru: + name: Native Build (Mieru) + runs-on: ubuntu-latest + env: + MIERU_VERSION: v3.34.0 + steps: + - name: Checkout + uses: actions/checkout@v5 + - name: Mieru Status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + - name: Mieru Cache + id: cache + uses: actions/cache@v5 + with: + path: | + app/executableSo + key: ${{ hashFiles('.github/workflows/*', 'mieru_status') }}-${{ env.MIERU_VERSION }}-mieru + - name: Install Golang + if: steps.cache.outputs.cache-hit != 'true' + uses: actions/setup-go@v6 + with: + go-version: '1.24.9' + - name: Mieru Build + if: steps.cache.outputs.cache-hit != 'true' + run: ./run lib mieru build: name: Build OSS APK runs-on: ubuntu-latest + env: + MIERU_VERSION: v3.34.0 needs: - libcore + - mieru steps: - name: Checkout uses: actions/checkout@v5 @@ -52,6 +80,23 @@ jobs: path: | app/libs/libcore.aar key: ${{ hashFiles('.github/workflows/*', 'golang_status', 'libcore_status') }} + - name: Mieru Status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + - name: Mieru Cache + id: mieru-cache + uses: actions/cache@v5 + with: + path: | + app/executableSo + key: ${{ hashFiles('.github/workflows/*', 'mieru_status') }}-${{ env.MIERU_VERSION }}-mieru + - name: Verify Mieru Artifacts + run: | + for abi in arm64-v8a armeabi-v7a x86 x86_64; do + if [ ! -x "app/executableSo/$abi/libmieru.so" ]; then + echo "Error: missing app/executableSo/$abi/libmieru.so (Mieru cache miss)" >&2 + exit 1 + fi + done - name: Gradle cache uses: actions/cache@v5 with: diff --git a/buildScript/lib/mieru.sh b/buildScript/lib/mieru.sh index e04100192..74bcc4f74 100755 --- a/buildScript/lib/mieru.sh +++ b/buildScript/lib/mieru.sh @@ -11,6 +11,11 @@ set -e source "buildScript/init/env.sh" +if [ -z "$ANDROID_NDK_HOME" ]; then + echo "Error: ANDROID_NDK_HOME is not set (NDK required to cross-compile Mieru)." >&2 + exit 1 +fi + # Mieru release tag to build from source. MIERU_VERSION="${MIERU_VERSION:-v3.34.0}" From e436305a0c58ab4f148f303931a35759ceca1bd3 Mon Sep 17 00:00:00 2001 From: hawkff <109485367+hawkff@users.noreply.github.com> Date: Mon, 15 Jun 2026 16:02:19 -0400 Subject: [PATCH 4/8] ci: use -f not -x to verify Mieru artifacts GitHub Actions cache restore does not reliably preserve the execute bit, so testing with -x could falsely fail on a cache hit. The runtime execute permission is applied by Android when extracting from the APK; here we only need to confirm the binary exists. --- .github/workflows/build.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/preview.yml | 2 +- .github/workflows/release.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c96304740..6b3d5520e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -90,7 +90,7 @@ jobs: - name: Verify Mieru Artifacts run: | for abi in arm64-v8a armeabi-v7a x86 x86_64; do - if [ ! -x "app/executableSo/$abi/libmieru.so" ]; then + if [ ! -f "app/executableSo/$abi/libmieru.so" ]; then echo "Error: missing app/executableSo/$abi/libmieru.so (Mieru cache miss)" >&2 exit 1 fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 45dbcb662..12a456520 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -100,7 +100,7 @@ jobs: - name: Verify Mieru Artifacts run: | for abi in arm64-v8a armeabi-v7a x86 x86_64; do - if [ ! -x "app/executableSo/$abi/libmieru.so" ]; then + if [ ! -f "app/executableSo/$abi/libmieru.so" ]; then echo "Error: missing app/executableSo/$abi/libmieru.so (Mieru cache miss)" >&2 exit 1 fi diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index f942fa1b0..b0226fd78 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -86,7 +86,7 @@ jobs: - name: Verify Mieru Artifacts run: | for abi in arm64-v8a armeabi-v7a x86 x86_64; do - if [ ! -x "app/executableSo/$abi/libmieru.so" ]; then + if [ ! -f "app/executableSo/$abi/libmieru.so" ]; then echo "Error: missing app/executableSo/$abi/libmieru.so (Mieru cache miss)" >&2 exit 1 fi diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1abbc8843..40cde35a8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -92,7 +92,7 @@ jobs: - name: Verify Mieru Artifacts run: | for abi in arm64-v8a armeabi-v7a x86 x86_64; do - if [ ! -x "app/executableSo/$abi/libmieru.so" ]; then + if [ ! -f "app/executableSo/$abi/libmieru.so" ]; then echo "Error: missing app/executableSo/$abi/libmieru.so (Mieru cache miss)" >&2 exit 1 fi From 3a93d099d3bf5d952c3302c3d1f4787256e8d0de Mon Sep 17 00:00:00 2001 From: hawkff <109485367+hawkff@users.noreply.github.com> Date: Mon, 15 Jun 2026 16:06:10 -0400 Subject: [PATCH 5/8] ci: validate resolved NDK toolchain dir in mieru.sh Fail fast with a clear message if neither the linux-x86_64 nor darwin-x86_64 NDK LLVM toolchain dir exists, instead of a cryptic CC-not-found later. --- buildScript/lib/mieru.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/buildScript/lib/mieru.sh b/buildScript/lib/mieru.sh index 74bcc4f74..f0f582f27 100755 --- a/buildScript/lib/mieru.sh +++ b/buildScript/lib/mieru.sh @@ -24,6 +24,10 @@ DEPS="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin" if [ ! -d "$DEPS" ]; then DEPS="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin" fi +if [ ! -d "$DEPS" ]; then + echo "Error: NDK LLVM toolchain not found under $ANDROID_NDK_HOME (unsupported host or NDK layout)." >&2 + exit 1 +fi WORK="$(pwd)/.mieru-build" OUT="$(pwd)/app/executableSo" From 8153cd3d0c33576dd9157144b216ece0ced23521 Mon Sep 17 00:00:00 2001 From: hawkff <109485367+hawkff@users.noreply.github.com> Date: Mon, 15 Jun 2026 16:09:34 -0400 Subject: [PATCH 6/8] ci: re-clone Mieru source if existing checkout is unhealthy Guard the incremental-fetch path: if fetch/checkout fail (e.g. a corrupted .mieru-build from a prior failed run), remove and clone fresh instead of erroring out. --- buildScript/lib/mieru.sh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/buildScript/lib/mieru.sh b/buildScript/lib/mieru.sh index f0f582f27..a07532153 100755 --- a/buildScript/lib/mieru.sh +++ b/buildScript/lib/mieru.sh @@ -32,13 +32,20 @@ fi WORK="$(pwd)/.mieru-build" OUT="$(pwd)/app/executableSo" -# Fetch source (shallow clone at the pinned tag). -if [ ! -d "$WORK/.git" ]; then +# Fetch source (shallow clone at the pinned tag). Re-clone fresh if the existing +# checkout is missing or its git operations fail (e.g. corrupted by a prior build). +need_clone=1 +if [ -d "$WORK/.git" ]; then + if git -C "$WORK" fetch --depth 1 origin "refs/tags/$MIERU_VERSION" \ + && git -C "$WORK" checkout -q FETCH_HEAD; then + need_clone=0 + else + echo ">> existing $WORK is unusable; re-cloning" + fi +fi +if [ "$need_clone" -eq 1 ]; then rm -rf "$WORK" git clone --depth 1 --branch "$MIERU_VERSION" https://github.com/enfein/mieru.git "$WORK" -else - git -C "$WORK" fetch --depth 1 origin "refs/tags/$MIERU_VERSION" - git -C "$WORK" checkout -q FETCH_HEAD fi pushd "$WORK" >/dev/null From 489f034a3ac410fd1e234eac99cbde8fc207144d Mon Sep 17 00:00:00 2001 From: hawkff <109485367+hawkff@users.noreply.github.com> Date: Mon, 15 Jun 2026 16:14:10 -0400 Subject: [PATCH 7/8] ci: support darwin-arm64 NDK host in mieru.sh Add a darwin-arm64 fallback for the NDK LLVM toolchain so local Mieru builds work natively on Apple Silicon Macs (newer NDKs ship darwin-arm64). --- buildScript/lib/mieru.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/buildScript/lib/mieru.sh b/buildScript/lib/mieru.sh index a07532153..c1ceb810f 100755 --- a/buildScript/lib/mieru.sh +++ b/buildScript/lib/mieru.sh @@ -20,10 +20,13 @@ fi MIERU_VERSION="${MIERU_VERSION:-v3.34.0}" DEPS="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin" -# macOS NDK host dir is darwin-x86_64; fall back if linux path is absent. +# macOS NDK host dirs are darwin-x86_64 / darwin-arm64; fall back if linux is absent. if [ ! -d "$DEPS" ]; then DEPS="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin" fi +if [ ! -d "$DEPS" ]; then + DEPS="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-arm64/bin" +fi if [ ! -d "$DEPS" ]; then echo "Error: NDK LLVM toolchain not found under $ANDROID_NDK_HOME (unsupported host or NDK layout)." >&2 exit 1 From 8b0433956ddb2b813cbafacf542852daa40e4b00 Mon Sep 17 00:00:00 2001 From: hawkff <109485367+hawkff@users.noreply.github.com> Date: Mon, 15 Jun 2026 16:59:28 -0400 Subject: [PATCH 8/8] ci: address review - env_ndk.sh in cache hash, consolidate MIERU_VERSION, pipefail - Include buildScript/init/env_ndk.sh (NDK version pin) in the Mieru cache-key hash so bumping the NDK invalidates stale binaries. - Hoist MIERU_VERSION to a single workflow-level env block per workflow (was duplicated in the mieru and build jobs). - Add 'set -o pipefail' to mieru.sh as a defensive guard. --- .github/workflows/build.yml | 10 ++++------ .github/workflows/ci.yml | 10 ++++------ .github/workflows/preview.yml | 10 ++++------ .github/workflows/release.yml | 10 ++++------ buildScript/lib/mieru.sh | 1 + 5 files changed, 17 insertions(+), 24 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6b3d5520e..51c67139f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,8 @@ on: - main paths: - 'nb4a.properties' +env: + MIERU_VERSION: v3.34.0 jobs: libcore: name: Native Build (LibCore) @@ -35,13 +37,11 @@ jobs: mieru: name: Native Build (Mieru) runs-on: ubuntu-latest - env: - MIERU_VERSION: v3.34.0 steps: - name: Checkout uses: actions/checkout@v5 - name: Mieru Status - run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh buildScript/init/env_ndk.sh | sha1sum > mieru_status - name: Mieru Cache id: cache uses: actions/cache@v5 @@ -60,8 +60,6 @@ jobs: build: name: Build OSS APK runs-on: ubuntu-latest - env: - MIERU_VERSION: v3.34.0 needs: - libcore - mieru @@ -79,7 +77,7 @@ jobs: app/libs/libcore.aar key: ${{ hashFiles('.github/workflows/*', 'golang_status', 'libcore_status') }} - name: Mieru Status - run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh buildScript/init/env_ndk.sh | sha1sum > mieru_status - name: Mieru Cache id: mieru-cache uses: actions/cache@v5 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12a456520..b7a4868d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,8 @@ on: branches: - '*' pull_request: +env: + MIERU_VERSION: v3.34.0 jobs: libcore: name: Native Build (LibCore) @@ -40,13 +42,11 @@ jobs: mieru: name: Native Build (Mieru) runs-on: ubuntu-latest - env: - MIERU_VERSION: v3.34.0 steps: - name: Checkout uses: actions/checkout@v5 - name: Mieru Status - run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh buildScript/init/env_ndk.sh | sha1sum > mieru_status - name: Mieru Cache id: cache uses: actions/cache@v5 @@ -65,8 +65,6 @@ jobs: build: name: Build OSS APK runs-on: ubuntu-latest - env: - MIERU_VERSION: v3.34.0 needs: - libcore - mieru @@ -89,7 +87,7 @@ jobs: app/libs/libcore.aar key: ${{ hashFiles('.github/workflows/*', 'golang_status', 'libcore_status') }}-ci - name: Mieru Status - run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh buildScript/init/env_ndk.sh | sha1sum > mieru_status - name: Mieru Cache id: mieru-cache uses: actions/cache@v5 diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index b0226fd78..10257facd 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -2,6 +2,8 @@ name: Preview Build on: workflow_dispatch: inputs: +env: + MIERU_VERSION: v3.34.0 jobs: libcore: name: Native Build (LibCore) @@ -31,13 +33,11 @@ jobs: mieru: name: Native Build (Mieru) runs-on: ubuntu-latest - env: - MIERU_VERSION: v3.34.0 steps: - name: Checkout uses: actions/checkout@v5 - name: Mieru Status - run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh buildScript/init/env_ndk.sh | sha1sum > mieru_status - name: Mieru Cache id: cache uses: actions/cache@v5 @@ -56,8 +56,6 @@ jobs: build: name: Build OSS APK runs-on: ubuntu-latest - env: - MIERU_VERSION: v3.34.0 needs: - libcore - mieru @@ -75,7 +73,7 @@ jobs: app/libs/libcore.aar key: ${{ hashFiles('.github/workflows/*', 'golang_status', 'libcore_status') }} - name: Mieru Status - run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh buildScript/init/env_ndk.sh | sha1sum > mieru_status - name: Mieru Cache id: mieru-cache uses: actions/cache@v5 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 40cde35a8..1279b68f6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,6 +8,8 @@ on: publish: description: "Publish: If want ignore" required: false +env: + MIERU_VERSION: v3.34.0 jobs: libcore: name: Native Build (LibCore) @@ -37,13 +39,11 @@ jobs: mieru: name: Native Build (Mieru) runs-on: ubuntu-latest - env: - MIERU_VERSION: v3.34.0 steps: - name: Checkout uses: actions/checkout@v5 - name: Mieru Status - run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh buildScript/init/env_ndk.sh | sha1sum > mieru_status - name: Mieru Cache id: cache uses: actions/cache@v5 @@ -62,8 +62,6 @@ jobs: build: name: Build OSS APK runs-on: ubuntu-latest - env: - MIERU_VERSION: v3.34.0 needs: - libcore - mieru @@ -81,7 +79,7 @@ jobs: app/libs/libcore.aar key: ${{ hashFiles('.github/workflows/*', 'golang_status', 'libcore_status') }} - name: Mieru Status - run: cat buildScript/lib/mieru.sh buildScript/init/env.sh | sha1sum > mieru_status + run: cat buildScript/lib/mieru.sh buildScript/init/env.sh buildScript/init/env_ndk.sh | sha1sum > mieru_status - name: Mieru Cache id: mieru-cache uses: actions/cache@v5 diff --git a/buildScript/lib/mieru.sh b/buildScript/lib/mieru.sh index c1ceb810f..f0fcc0bbf 100755 --- a/buildScript/lib/mieru.sh +++ b/buildScript/lib/mieru.sh @@ -8,6 +8,7 @@ # # Usage: ./run lib mieru set -e +set -o pipefail source "buildScript/init/env.sh"