From 6ad17594187fd2c067fb483143d700af06d16ddf Mon Sep 17 00:00:00 2001 From: Konrad Kollnig <5175206+kasnder@users.noreply.github.com> Date: Sun, 12 Jul 2026 13:35:41 +0200 Subject: [PATCH 1/9] Make Rust build F-Droid compatible --- .github/workflows/test.yml | 7 +- FDROID-UPDATE.md | 129 ++++++++++++++++++++++++++++++++++ README.md | 7 +- app/build.gradle | 26 ++++--- rust-toolchain.toml | 9 +++ scripts/setup_rust_android.sh | 28 ++++++++ wgbridge-rs/README.md | 38 +++++----- 7 files changed, 208 insertions(+), 36 deletions(-) create mode 100644 FDROID-UPDATE.md create mode 100644 rust-toolchain.toml create mode 100755 scripts/setup_rust_android.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7fdbdeff0..76faa07dd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,10 +22,7 @@ jobs: distribution: 'temurin' - name: Set up Rust - run: | - rustup toolchain install stable --profile minimal - rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android - cargo install cargo-ndk + run: ./scripts/setup_rust_android.sh - name: Cache cargo registry and build uses: actions/cache@v6 @@ -40,7 +37,7 @@ jobs: uses: gradle/actions/setup-gradle@v6 - name: Run Rust unit tests - run: cargo test --manifest-path wgbridge-rs/Cargo.toml + run: cargo test --manifest-path wgbridge-rs/Cargo.toml --locked --offline - name: Run unit tests run: ./gradlew testGithubDebugUnitTest diff --git a/FDROID-UPDATE.md b/FDROID-UPDATE.md new file mode 100644 index 000000000..62ae7443b --- /dev/null +++ b/FDROID-UPDATE.md @@ -0,0 +1,129 @@ +# Updating TrackerControl on F-Droid + +TrackerControl's WireGuard engine is compiled from Rust source. New F-Droid +build entries must prepare the pinned Rust toolchain and Cargo dependencies +before F-Droid starts its offline Gradle build. + +The examples below use release `2026071201` / `2026.07.12`. Substitute the +actual version code and version name for later releases. + +## 1. Tag the release + +Only tag a commit that includes the current `rust-toolchain.toml`, +`wgbridge-rs/Cargo.lock`, and `scripts/setup_rust_android.sh` files. + +```bash +git tag 2026071201 +git push origin 2026071201 +``` + +TrackerControl's F-Droid metadata uses numeric tags as release identifiers. + +## 2. Prepare an fdroiddata merge request + +Fork [fdroid/fdroiddata](https://gitlab.com/fdroid/fdroiddata), then clone the +fork and create a branch: + +```bash +git clone https://gitlab.com/YOUR_USERNAME/fdroiddata.git +cd fdroiddata +git remote add upstream https://gitlab.com/fdroid/fdroiddata.git +git switch -c trackercontrol-2026071201 +``` + +Edit: + +```text +metadata/net.kollnig.missioncontrol.fdroid.yml +``` + +Append this entry under `Builds:`: + +```yaml + - versionName: 2026.07.12-fdroid + versionCode: 2026071201 + commit: '2026071201' + subdir: app + sudo: + - apt-get update + - apt-get install -y rustup gcc libc-dev + gradle: + - fdroid + prebuild: + - ../scripts/setup_rust_android.sh + ndk: r27c +``` + +Update the current-version fields at the bottom of the file: + +```yaml +CurrentVersion: 2026.07.12-fdroid +CurrentVersionCode: 2026071201 +``` + +Keep the automatic-update configuration unchanged: + +```yaml +AutoUpdateMode: Version +UpdateCheckMode: Tags ^[0-9]+$ +``` + +## 3. Validate the metadata + +With `fdroidserver` installed and available on `PATH`, run from the +`fdroiddata` checkout: + +```bash +fdroid readmeta +fdroid lint net.kollnig.missioncontrol.fdroid +``` + +For an end-to-end local application check, first provision the pinned Rust +dependencies while networking is available, then build the release offline: + +```bash +./scripts/setup_rust_android.sh +./gradlew :app:assembleFdroidRelease --offline +``` + +The APK should contain `libwgbridge.so` for `armeabi-v7a`, `arm64-v8a`, `x86`, +and `x86_64`. + +## 4. Submit the metadata change + +From the `fdroiddata` checkout: + +```bash +git add metadata/net.kollnig.missioncontrol.fdroid.yml +git commit -m "Update TrackerControl to 2026071201" +git push origin trackercontrol-2026071201 +``` + +Open a merge request from that branch into `fdroid/fdroiddata:master`. + +Suggested merge-request description: + +```text +TrackerControl now builds its WireGuard engine from Rust source. + +The prebuild step installs the repository-pinned Rust toolchain, Android +targets, and cargo-ndk, and fetches Cargo.lock dependencies. The Gradle build +itself runs Cargo with --locked --offline. + +Locally verified with: +./gradlew :app:assembleFdroidRelease --offline +``` + +## If the update bot opens a merge request first + +The checkupdates bot normally copies the previous build recipe, which does not +contain the Rust preparation steps. Its source branch belongs to F-Droid's bot +fork and may not be editable by the TrackerControl maintainers. + +Create the complete merge request from the TrackerControl maintainer's own +`fdroiddata` fork as described above. Comment on the bot merge request with a +link to the replacement and ask F-Droid's maintainers to close the bot merge +request in favor of it. + +F-Droid's general contribution guide is available at +. diff --git a/README.md b/README.md index e4d99bae8..debb7f084 100644 --- a/README.md +++ b/README.md @@ -133,11 +133,10 @@ In combination with F-Droid, this repository uses automated builds and follows a You need: - Android Studio (with the Android SDK and build tools) -- Android NDK (any recent version) -- Rust via [rustup](https://rustup.rs) with the Android targets, for the WireGuard engine ([gotatun](https://github.com/mullvad/gotatun), built from source in `wgbridge-rs/`): +- Android NDK 27.2.12479018 (r27c) +- Rust via [rustup](https://rustup.rs), for the WireGuard engine ([gotatun](https://github.com/mullvad/gotatun), built from source in `wgbridge-rs/`). The compiler, Android targets, and `cargo-ndk` version are pinned; install them and pre-fetch locked crates with: ```bash - rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android - cargo install cargo-ndk + ./scripts/setup_rust_android.sh ``` Build from within Android Studio, or use the provided gradle wrapper — see the [Android developer documentation](https://developer.android.com/studio/build/building-cmdline). If you find any problems with these instructions, please file an issue. diff --git a/app/build.gradle b/app/build.gradle index f78459324..af113769e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,6 +9,7 @@ def wgbridgeSrcDir = file("$rootDir/wgbridge-rs") def wgbridgeOutDir = file("$buildDir/rustJniLibs") def wgbridgeAbis = ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'] def wgbridgeNdkVersion = '27.2.12479018' // keep in sync with defaultConfig.ndkVersion +def wgbridgeCargoNdkVersion = '4.1.2' // keep in sync with scripts/setup_rust_android.sh // Resolve the NDK directory the way AGP does (local.properties, then env), // since modern AGP extensions no longer expose android.ndkDirectory. @@ -70,7 +71,7 @@ tasks.register('wgbridgeBuild') { Could not find a `cargo` executable. Install Rust via rustup (https://rustup.rs), then: rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android - cargo install cargo-ndk + cargo install cargo-ndk@${wgbridgeCargoNdkVersion} --locked and either add ~/.cargo/bin to PATH (restart Android Studio), or pass -PcargoBin=/path/to/cargo to Gradle. """.stripIndent()) @@ -104,20 +105,23 @@ tasks.register('wgbridgeBuild') { env['CARGO_ENCODED_RUSTFLAGS'] = rustFlags.join('\u001f') env.remove('RUSTFLAGS') - // cargo-ndk drives the per-ABI cross-compilation and linker setup. - def cargoNdk = "${System.getProperty('user.home')}/.cargo/bin/cargo-ndk" - if (!file(cargoNdk).canExecute() && - !env['PATH'].split(File.pathSeparator).any { file("$it/cargo-ndk").canExecute() }) { - logger.lifecycle('Installing cargo-ndk ...') - providers.exec { - environment env - commandLine cargoBin, 'install', 'cargo-ndk' - }.result.get().assertNormalExitValue() + // Tool installation must happen before Gradle runs. In particular, + // F-Droid disables network access for the actual build phase. + def cargoNdkAvailable = file("${System.getProperty('user.home')}/.cargo/bin/cargo-ndk").canExecute() || + env['PATH'].split(File.pathSeparator).any { file("$it/cargo-ndk").canExecute() } + if (!cargoNdkAvailable) { + throw new GradleException(""" + Could not find cargo-ndk ${wgbridgeCargoNdkVersion}. Run: + ./scripts/setup_rust_android.sh + Gradle deliberately does not install build tools because release + and F-Droid builds must be able to run without network access. + """.stripIndent()) } def args = [cargoBin, 'ndk'] wgbridgeAbis.each { args += ['-t', it] } - args += ['--platform', '23', '-o', wgbridgeOutDir.absolutePath, 'build', '--release'] + args += ['--platform', '23', '-o', wgbridgeOutDir.absolutePath, + 'build', '--release', '--locked', '--offline'] providers.exec { workingDir wgbridgeSrcDir diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 000000000..47e85ae94 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,9 @@ +[toolchain] +channel = "1.95.0" +profile = "minimal" +targets = [ + "aarch64-linux-android", + "armv7-linux-androideabi", + "i686-linux-android", + "x86_64-linux-android", +] diff --git a/scripts/setup_rust_android.sh b/scripts/setup_rust_android.sh new file mode 100755 index 000000000..1324692dd --- /dev/null +++ b/scripts/setup_rust_android.sh @@ -0,0 +1,28 @@ +#!/bin/sh +set -eu + +ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) +CARGO_NDK_VERSION=4.1.2 + +if ! command -v rustup >/dev/null 2>&1; then + echo "rustup is required; install it before running this script." >&2 + exit 1 +fi + +# rust-toolchain.toml pins the compiler and Android targets. This command is +# idempotent and makes the required components available before offline builds. +rustup toolchain install 1.95.0 --profile minimal \ + --target aarch64-linux-android \ + --target armv7-linux-androideabi \ + --target i686-linux-android \ + --target x86_64-linux-android + +if ! command -v cargo-ndk >/dev/null 2>&1 || \ + [ "$(cargo-ndk --version 2>/dev/null | awk '{print $2}')" != "$CARGO_NDK_VERSION" ]; then + cargo install "cargo-ndk@$CARGO_NDK_VERSION" --locked +fi + +# Populate Cargo's cache while networking is allowed. wgbridgeBuild passes +# --offline and --locked so the later Gradle/F-Droid build cannot fetch or +# silently change dependencies. +cargo fetch --manifest-path "$ROOT/wgbridge-rs/Cargo.toml" --locked diff --git a/wgbridge-rs/README.md b/wgbridge-rs/README.md index fd2d08125..a9996a560 100644 --- a/wgbridge-rs/README.md +++ b/wgbridge-rs/README.md @@ -49,17 +49,20 @@ as its output, so it's skipped when the Rust source hasn't changed. ### Prerequisites -- **Rust ≥ 1.95** via [rustup](https://rustup.rs), with the Android targets: +- **Rust 1.95.0** via [rustup](https://rustup.rs). The version and Android + targets are pinned in the repository's `rust-toolchain.toml`. +- **cargo-ndk 4.1.2**. +- **Android NDK 27.2.12479018 (r27c)** (the Gradle task points cargo-ndk at + the NDK configured for the app module). - ```bash - rustup target add armv7-linux-androideabi aarch64-linux-android \ - i686-linux-android x86_64-linux-android - ``` +Install the pinned Rust prerequisites and pre-fetch the locked crates with: -- **cargo-ndk**: `cargo install cargo-ndk` (the Gradle task installs it - automatically if missing). -- **Android NDK ≥ 27** (the Gradle task points cargo-ndk at the NDK - configured for the app module). +```bash +./scripts/setup_rust_android.sh +``` + +The Gradle build is intentionally offline: it never installs tools or fetches +crates. This keeps local, CI, and F-Droid builds on the same inputs. ### Manual build (debugging) @@ -84,20 +87,23 @@ cargo test ## F-Droid build metadata -The F-Droid build server doesn't ship Rust by default. Add the following -to the `Builds:` entry in `metadata/net.kollnig.missioncontrol.yml`: +The F-Droid build server doesn't ship the required Rust setup by default. Add +the following to the new `Builds:` entry in +`metadata/net.kollnig.missioncontrol.fdroid.yml`: ```yaml sudo: - apt-get update - - apt-get install -y curl build-essential + - apt-get install -y rustup gcc libc-dev prebuild: - - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal - - source $HOME/.cargo/env - - rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android - - cargo install cargo-ndk + - ../scripts/setup_rust_android.sh +ndk: r27c ``` +The existing `gradle: [fdroid]` setting remains unchanged. The prebuild step +runs while dependency downloads are allowed; Gradle subsequently compiles the +locked crate graph with Cargo offline. + ## Java/Kotlin API surface The Java classes in `app/src/main/java/net/kollnig/missioncontrol/wgbridge/` From 8eb022a304ebabc7dd97b1d455d27f10d9fb26f5 Mon Sep 17 00:00:00 2001 From: Konrad Kollnig <5175206+kasnder@users.noreply.github.com> Date: Sun, 12 Jul 2026 13:38:59 +0200 Subject: [PATCH 2/9] Test F-Droid release build in CI --- .github/workflows/test.yml | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 76faa07dd..4c2de67f5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,6 +3,7 @@ name: Test on: push: branches: [ master, main ] + tags: [ '[0-9]*' ] pull_request: branches: [ master, main ] @@ -21,9 +22,6 @@ jobs: java-version: '17' distribution: 'temurin' - - name: Set up Rust - run: ./scripts/setup_rust_android.sh - - name: Cache cargo registry and build uses: actions/cache@v6 with: @@ -33,14 +31,28 @@ jobs: wgbridge-rs/target key: cargo-${{ runner.os }}-${{ hashFiles('wgbridge-rs/Cargo.lock') }} + - name: Set up Rust + run: ./scripts/setup_rust_android.sh + - name: Setup Gradle uses: gradle/actions/setup-gradle@v6 + - name: Prefetch Gradle dependencies + run: ./gradlew :app:dependencies + - name: Run Rust unit tests run: cargo test --manifest-path wgbridge-rs/Cargo.toml --locked --offline - name: Run unit tests - run: ./gradlew testGithubDebugUnitTest - - - name: Build debug APK - run: ./gradlew assembleGithubDebug + run: ./gradlew testGithubDebugUnitTest --offline + + - name: Build F-Droid release APK offline + run: ./gradlew :app:assembleFdroidRelease --offline + + - name: Verify WireGuard libraries in F-Droid APK + run: | + APK=$(find app/build/outputs/apk/fdroid -type f -name '*.apk' -print -quit) + test -n "$APK" + for ABI in armeabi-v7a arm64-v8a x86 x86_64; do + test "$(unzip -Z1 "$APK" "lib/$ABI/libwgbridge.so")" = "lib/$ABI/libwgbridge.so" + done From c9b68a8b24874bd52d5afb484add89cacb27e3f2 Mon Sep 17 00:00:00 2001 From: Konrad Kollnig <5175206+kasnder@users.noreply.github.com> Date: Sun, 12 Jul 2026 13:47:44 +0200 Subject: [PATCH 3/9] Prevent Crowdin translating resource references --- app/src/main/res/values-ru-rRU/strings.xml | 5 ----- app/src/main/res/values-uk-rUA/strings.xml | 5 ----- app/src/main/res/values-zh-rCN/strings.xml | 5 ----- app/src/main/res/values/strings.xml | 2 +- 4 files changed, 1 insertion(+), 16 deletions(-) diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index b1198b747..78ea45f6b 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -263,11 +263,6 @@ Whois %1$s Порт %1$d Скопировать - - @string/blocking_mode_minimal - Строка/blocking_mode_standard - Строка/blocking_mode_strict - Отключить доступ в интернет для этого приложения Название приложения diff --git a/app/src/main/res/values-uk-rUA/strings.xml b/app/src/main/res/values-uk-rUA/strings.xml index 035aae9c0..bc64ec540 100644 --- a/app/src/main/res/values-uk-rUA/strings.xml +++ b/app/src/main/res/values-uk-rUA/strings.xml @@ -376,11 +376,6 @@ Whois %1$s Порт %1$d Копіювати - - @string/режим_блокування_мінімальний - @string/режим_блокування_стандартний - @string/режим_блокування_суворий - Вимкнути доступ до Інтернету для цієї програми Назва програми diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 1754079cc..5e6b84276 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -378,11 +378,6 @@ Whois %1$s 端口 %1$d 复制 - - 最小 - 标准 - 严格 - 禁止此应用访问互联网 应用程序名称 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 269e8916e..ece6610a5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -439,7 +439,7 @@ Your internet traffic is not being sent to a remote VPN server. Port %1$d Copy - + @string/blocking_mode_minimal @string/blocking_mode_standard @string/blocking_mode_strict From 9948340ff2c69957b4700d817e54d45547a196a2 Mon Sep 17 00:00:00 2001 From: Konrad Kollnig <5175206+kasnder@users.noreply.github.com> Date: Sun, 12 Jul 2026 13:54:17 +0200 Subject: [PATCH 4/9] Provision native tools before offline CI build --- .github/workflows/test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4c2de67f5..ab85a87ca 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,6 +22,9 @@ jobs: java-version: '17' distribution: 'temurin' + - name: Install Android native build tools + run: sdkmanager "cmake;3.22.1" "ndk;27.2.12479018" + - name: Cache cargo registry and build uses: actions/cache@v6 with: From b0c4edfbc14185b25f92f1ed20bfcfcc945540a9 Mon Sep 17 00:00:00 2001 From: Konrad Kollnig <5175206+kasnder@users.noreply.github.com> Date: Sun, 12 Jul 2026 13:58:01 +0200 Subject: [PATCH 5/9] Use hosted Android SDK manager path --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ab85a87ca..6ca3d8e2d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,7 +23,7 @@ jobs: distribution: 'temurin' - name: Install Android native build tools - run: sdkmanager "cmake;3.22.1" "ndk;27.2.12479018" + run: "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" "cmake;3.22.1" "ndk;27.2.12479018" - name: Cache cargo registry and build uses: actions/cache@v6 From e6c472ef86fdedd3afd149e437d3cd458688b1d1 Mon Sep 17 00:00:00 2001 From: Konrad Kollnig <5175206+kasnder@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:33:23 +0200 Subject: [PATCH 6/9] Fix native tool setup workflow syntax --- .github/workflows/test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6ca3d8e2d..086b36ed9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,7 +23,10 @@ jobs: distribution: 'temurin' - name: Install Android native build tools - run: "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" "cmake;3.22.1" "ndk;27.2.12479018" + run: | + "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" \ + "cmake;3.22.1" \ + "ndk;27.2.12479018" - name: Cache cargo registry and build uses: actions/cache@v6 From ce59be5bd1a8bc11ff751805fa3fc91cf64feb54 Mon Sep 17 00:00:00 2001 From: Konrad Kollnig <5175206+kasnder@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:37:24 +0200 Subject: [PATCH 7/9] Run unit tests against F-Droid flavor --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 086b36ed9..6cfc1ff22 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -50,7 +50,7 @@ jobs: run: cargo test --manifest-path wgbridge-rs/Cargo.toml --locked --offline - name: Run unit tests - run: ./gradlew testGithubDebugUnitTest --offline + run: ./gradlew testFdroidDebugUnitTest --offline - name: Build F-Droid release APK offline run: ./gradlew :app:assembleFdroidRelease --offline From bd234a55a0a0810bd041ac6a0c793fc548274d0e Mon Sep 17 00:00:00 2001 From: Konrad Kollnig <5175206+kasnder@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:41:49 +0200 Subject: [PATCH 8/9] Prefetch Android lint dependencies --- .github/workflows/test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6cfc1ff22..1cb129c7b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -44,7 +44,9 @@ jobs: uses: gradle/actions/setup-gradle@v6 - name: Prefetch Gradle dependencies - run: ./gradlew :app:dependencies + run: | + ./gradlew :app:dependencies + ./gradlew :app:dependencies --configuration androidLintTool - name: Run Rust unit tests run: cargo test --manifest-path wgbridge-rs/Cargo.toml --locked --offline From 26f0ddaabd978b01953720d298b041b7761456ec Mon Sep 17 00:00:00 2001 From: Konrad Kollnig <5175206+kasnder@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:51:58 +0200 Subject: [PATCH 9/9] Materialize lint artifacts before offline build --- .github/workflows/test.yml | 2 +- app/build.gradle | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1cb129c7b..2dd583c0f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,7 +46,7 @@ jobs: - name: Prefetch Gradle dependencies run: | ./gradlew :app:dependencies - ./gradlew :app:dependencies --configuration androidLintTool + ./gradlew :app:prefetchAndroidLintDependencies - name: Run Rust unit tests run: cargo test --manifest-path wgbridge-rs/Cargo.toml --locked --offline diff --git a/app/build.gradle b/app/build.gradle index af113769e..55ccb7669 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,6 +11,16 @@ def wgbridgeAbis = ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'] def wgbridgeNdkVersion = '27.2.12479018' // keep in sync with defaultConfig.ndkVersion def wgbridgeCargoNdkVersion = '4.1.2' // keep in sync with scripts/setup_rust_android.sh +// Resolves the lint tool artifacts while networking is available so release +// builds can subsequently run with Gradle's --offline flag (as on F-Droid). +tasks.register('prefetchAndroidLintDependencies') { + description = 'Downloads the Android lint tool artifacts for a later offline build.' + group = 'build setup' + doLast { + configurations.named('androidLintTool').get().resolve() + } +} + // Resolve the NDK directory the way AGP does (local.properties, then env), // since modern AGP extensions no longer expose android.ndkDirectory. def findNdkDirectory = { ->