refactor(build): rename entry modules and remove DESKTOP_ONLY mode (#5476)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
James Rich
2026-05-18 07:44:12 -05:00
committed by GitHub
parent d24fc9ac92
commit f4b6b02ace
215 changed files with 1454 additions and 539 deletions
+2 -2
View File
@@ -18,7 +18,7 @@ git submodule update --init
./gradlew :core:data:allTests ./gradlew :core:data:allTests
# Single module tests (Android-only module like :app) # Single module tests (Android-only module like :app)
./gradlew :app:testFdroidDebugUnitTest ./gradlew :androidApp:testFdroidDebugUnitTest
# Cross-platform compilation check (no tests) # Cross-platform compilation check (no tests)
./gradlew kmpSmokeCompile ./gradlew kmpSmokeCompile
@@ -46,7 +46,7 @@ KMP modules have different task names than pure-Android modules. Using the wrong
## Quick Reference ## Quick Reference
- **Architecture**: KMP project (Android, Desktop, iOS). Business logic in `commonMain`; platform shells (`app/`, `desktop/`) wire DI and host UI. See `AGENTS.md` and `.skills/kmp-architecture/`. - **Architecture**: KMP project (Android, Desktop, iOS). Business logic in `commonMain`; platform shells (`androidApp/`, `desktopApp/`) wire DI and host UI. See `AGENTS.md` and `.skills/kmp-architecture/`.
- **Flavors**: `fdroid` (OSS) / `google` (Maps + DataDog). Only one installable at a time (different signing keys). - **Flavors**: `fdroid` (OSS) / `google` (Maps + DataDog). Only one installable at a time (different signing keys).
- **Verify before push**: Run `./gradlew spotlessApply detekt assembleDebug test allTests`, then confirm CI with `gh pr checks <PR>`. - **Verify before push**: Run `./gradlew spotlessApply detekt assembleDebug test allTests`, then confirm CI with `gh pr checks <PR>`.
- **Strings**: `stringResource(Res.string.key)` — run `python3 scripts/sort-strings.py` after adding strings. - **Strings**: `stringResource(Res.string.key)` — run `python3 scripts/sort-strings.py` after adding strings.
@@ -5,7 +5,7 @@ excludeAgent: "code-review"
# CI Workflow Rules # CI Workflow Rules
- Prefer explicit Gradle task paths (`app:lintFdroidDebug`) over shorthand (`lintDebug`). - Prefer explicit Gradle task paths (`androidApp:lintFdroidDebug`) over shorthand (`lintDebug`).
- CI uses `.github/ci-gradle.properties` — don't assume local `gradle.properties` values. - CI uses `.github/ci-gradle.properties` — don't assume local `gradle.properties` values.
- CI passes `-Pci=true` to enable full processor usage via `maxParallelForks`. - CI passes `-Pci=true` to enable full processor usage via `maxParallelForks`.
- Use `fetch-depth: 0` only where needed (spotless ratcheting, version code). Use `fetch-depth: 1` otherwise. - Use `fetch-depth: 0` only where needed (spotless ratcheting, version code). Use `fetch-depth: 1` otherwise.
+2 -2
View File
@@ -8,10 +8,10 @@ on:
- main - main
paths: paths:
# Only rebuild docs when source code changes (Dokka generates from KDoc) # Only rebuild docs when source code changes (Dokka generates from KDoc)
- 'app/src/**' - 'androidApp/src/**'
- 'core/**/src/**' - 'core/**/src/**'
- 'feature/**/src/**' - 'feature/**/src/**'
- 'desktop/src/**' - 'desktopApp/src/**'
- 'build-logic/**' - 'build-logic/**'
- 'build.gradle.kts' - 'build.gradle.kts'
- 'settings.gradle.kts' - 'settings.gradle.kts'
+5 -5
View File
@@ -30,9 +30,9 @@ jobs:
- '.github/workflows/**' - '.github/workflows/**'
- '.github/actions/**' - '.github/actions/**'
# Product modules validated by reusable-check # Product modules validated by reusable-check
- 'app/**' - 'androidApp/**'
- 'baselineprofile/**' - 'baselineprofile/**'
- 'desktop/**' - 'desktopApp/**'
- 'core/**' - 'core/**'
- 'feature/**' - 'feature/**'
- 'screenshot-tests/**' - 'screenshot-tests/**'
@@ -95,9 +95,9 @@ jobs:
PY PY
# 2. VALIDATION & BUILD: Delegate to reusable-check.yml # 2. VALIDATION & BUILD: Delegate to reusable-check.yml
# We disable coverage for PRs to keep feedback fast (< 10 mins). # We disable coverage and desktop builds for PRs to keep feedback fast
# Desktop compilation is covered by :desktop:test in the shard-app test shard. # (< 10 mins). Desktop compilation is already covered by the :desktopApp:test
# Native desktop packaging (createDistributable) only runs in release.yml. # task in the shard-app test shard.
validate-and-build: validate-and-build:
needs: check-changes needs: check-changes
if: needs.check-changes.outputs.android == 'true' if: needs.check-changes.outputs.android == 'true'
+29 -44
View File
@@ -150,9 +150,9 @@ jobs:
GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }} GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }}
GOOGLE_PLAY_JSON_KEY: ${{ secrets.GOOGLE_PLAY_JSON_KEY }} GOOGLE_PLAY_JSON_KEY: ${{ secrets.GOOGLE_PLAY_JSON_KEY }}
run: | run: |
rm -f ./app/google-services.json rm -f ./androidApp/google-services.json
echo $GSERVICES > ./app/google-services.json echo $GSERVICES > ./androidApp/google-services.json
echo $KEYSTORE | base64 -di > ./app/$KEYSTORE_FILENAME echo $KEYSTORE | base64 -di > ./androidApp/$KEYSTORE_FILENAME
echo "$KEYSTORE_PROPERTIES" > ./keystore.properties echo "$KEYSTORE_PROPERTIES" > ./keystore.properties
echo "datadogApplicationId=$DATADOG_APPLICATION_ID" >> ./secrets.properties echo "datadogApplicationId=$DATADOG_APPLICATION_ID" >> ./secrets.properties
echo "datadogClientToken=$DATADOG_CLIENT_TOKEN" >> ./secrets.properties echo "datadogClientToken=$DATADOG_CLIENT_TOKEN" >> ./secrets.properties
@@ -172,14 +172,14 @@ jobs:
run: bundle exec fastlane internal run: bundle exec fastlane internal
- name: List outputs - name: List outputs
run: ls -R app/build/outputs/ run: ls -R androidApp/build/outputs/
- name: Upload Google AAB artifact - name: Upload Google AAB artifact
if: always() if: always()
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v7
with: with:
name: google-aab name: google-aab
path: app/build/outputs/bundle/googleRelease/app-google-release.aab path: androidApp/build/outputs/bundle/googleRelease/androidApp-google-release.aab
retention-days: 1 retention-days: 1
- name: Upload Google APK artifact - name: Upload Google APK artifact
@@ -187,20 +187,20 @@ jobs:
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v7
with: with:
name: google-apk name: google-apk
path: app/build/outputs/apk/google/release/*.apk path: androidApp/build/outputs/apk/google/release/*.apk
retention-days: 1 retention-days: 1
- name: Attest Google AAB provenance - name: Attest Google AAB provenance
if: success() if: success()
uses: actions/attest-build-provenance@v4 uses: actions/attest-build-provenance@v4
with: with:
subject-path: app/build/outputs/bundle/googleRelease/app-google-release.aab subject-path: androidApp/build/outputs/bundle/googleRelease/androidApp-google-release.aab
- name: Attest Google APK provenance - name: Attest Google APK provenance
if: success() if: success()
uses: actions/attest-build-provenance@v4 uses: actions/attest-build-provenance@v4
with: with:
subject-path: app/build/outputs/apk/google/release/*.apk subject-path: androidApp/build/outputs/apk/google/release/*.apk
release-fdroid: release-fdroid:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
@@ -229,7 +229,7 @@ jobs:
KEYSTORE_FILENAME: ${{ secrets.KEYSTORE_FILENAME }} KEYSTORE_FILENAME: ${{ secrets.KEYSTORE_FILENAME }}
KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }} KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }}
run: | run: |
echo $KEYSTORE | base64 -di > ./app/$KEYSTORE_FILENAME echo $KEYSTORE | base64 -di > ./androidApp/$KEYSTORE_FILENAME
echo "$KEYSTORE_PROPERTIES" > ./keystore.properties echo "$KEYSTORE_PROPERTIES" > ./keystore.properties
- name: Setup Fastlane - name: Setup Fastlane
@@ -245,21 +245,21 @@ jobs:
run: bundle exec fastlane fdroid_build run: bundle exec fastlane fdroid_build
- name: List outputs - name: List outputs
run: ls -R app/build/outputs/ run: ls -R androidApp/build/outputs/
- name: Upload F-Droid APK artifact - name: Upload F-Droid APK artifact
if: always() if: always()
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v7
with: with:
name: fdroid-apk name: fdroid-apk
path: app/build/outputs/apk/fdroid/release/*.apk path: androidApp/build/outputs/apk/fdroid/release/*.apk
retention-days: 1 retention-days: 1
- name: Attest F-Droid APK provenance - name: Attest F-Droid APK provenance
if: success() if: success()
uses: actions/attest-build-provenance@v4 uses: actions/attest-build-provenance@v4
with: with:
subject-path: app/build/outputs/apk/fdroid/release/*.apk subject-path: androidApp/build/outputs/apk/fdroid/release/*.apk
release-desktop: release-desktop:
if: ${{ inputs.build_desktop }} if: ${{ inputs.build_desktop }}
@@ -307,13 +307,13 @@ jobs:
# `-PaboutLibraries.release=true` as member access on `-PaboutLibraries`, # `-PaboutLibraries.release=true` as member access on `-PaboutLibraries`,
# splitting the token and feeding `.release=true` to Gradle as a task name. # splitting the token and feeding `.release=true` to Gradle as a task name.
run: > run: >
./gradlew :desktop:packageReleaseDistributionForCurrentOS ./gradlew :desktopApp:packageReleaseDistributionForCurrentOS
${{ contains(runner.os, 'macOS') && ':desktop:packageReleaseUberJarForCurrentOS' || '' }} ${{ contains(runner.os, 'macOS') && ':desktopApp:packageReleaseUberJarForCurrentOS' || '' }}
'-PaboutLibraries.release=true' --no-daemon '-PaboutLibraries.release=true' --no-daemon
- name: List Desktop Binaries - name: List Desktop Binaries
if: runner.os == 'Linux' || runner.os == 'macOS' if: runner.os == 'Linux' || runner.os == 'macOS'
run: ls -R desktop/build/compose/binaries/main-release run: ls -R desktopApp/build/compose/binaries/main-release
- name: Upload Desktop Artifacts - name: Upload Desktop Artifacts
if: always() if: always()
@@ -321,13 +321,13 @@ jobs:
with: with:
name: desktop-${{ runner.os }}-${{ runner.arch }} name: desktop-${{ runner.os }}-${{ runner.arch }}
path: | path: |
desktop/build/compose/binaries/main-release/*/*.dmg desktopApp/build/compose/binaries/main-release/*/*.dmg
desktop/build/compose/binaries/main-release/*/*.msi desktopApp/build/compose/binaries/main-release/*/*.msi
desktop/build/compose/binaries/main-release/*/*.exe desktopApp/build/compose/binaries/main-release/*/*.exe
desktop/build/compose/binaries/main-release/*/*.deb desktopApp/build/compose/binaries/main-release/*/*.deb
desktop/build/compose/binaries/main-release/*/*.rpm desktopApp/build/compose/binaries/main-release/*/*.rpm
desktop/build/compose/binaries/main-release/*/*.AppImage desktopApp/build/compose/binaries/main-release/*/*.AppImage
desktop/build/compose/jars/*-release.jar desktopApp/build/compose/jars/*-release.jar
retention-days: 1 retention-days: 1
if-no-files-found: ignore if-no-files-found: ignore
@@ -336,13 +336,13 @@ jobs:
uses: actions/attest-build-provenance@v4 uses: actions/attest-build-provenance@v4
with: with:
subject-path: | subject-path: |
desktop/build/compose/binaries/main-release/*/*.dmg desktopApp/build/compose/binaries/main-release/*/*.dmg
desktop/build/compose/binaries/main-release/*/*.msi desktopApp/build/compose/binaries/main-release/*/*.msi
desktop/build/compose/binaries/main-release/*/*.exe desktopApp/build/compose/binaries/main-release/*/*.exe
desktop/build/compose/binaries/main-release/*/*.deb desktopApp/build/compose/binaries/main-release/*/*.deb
desktop/build/compose/binaries/main-release/*/*.rpm desktopApp/build/compose/binaries/main-release/*/*.rpm
desktop/build/compose/binaries/main-release/*/*.AppImage desktopApp/build/compose/binaries/main-release/*/*.AppImage
desktop/build/compose/jars/*-release.jar desktopApp/build/compose/jars/*-release.jar
create-flatpak-src: create-flatpak-src:
if: ${{ inputs.build_flatpak_src }} if: ${{ inputs.build_flatpak_src }}
@@ -370,22 +370,7 @@ jobs:
gradle_encryption_key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} gradle_encryption_key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
cache_read_only: 'true' cache_read_only: 'true'
- name: Python Setup
uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Install ast-grep
run: pip install ast-grep-cli
# Remove Android/iOS targets and other non-desktop bits
# that would break the flatpakGradleGenerator
- name: Prepare Offline Desktop Build
run: ./scripts/desktop-only-prep.sh
- name: Generate Flatpak Sources - name: Generate Flatpak Sources
env:
DESKTOP_ONLY: true
run: > run: >
./gradlew :build-logic:convention:flatpakGradleGenerator flatpakGradleGenerator ./gradlew :build-logic:convention:flatpakGradleGenerator flatpakGradleGenerator
--no-configuration-cache --refresh-dependencies --no-parallel --no-configuration-cache --refresh-dependencies --no-parallel
+58 -34
View File
@@ -94,7 +94,7 @@ jobs:
- name: Lint, Analysis & KMP Smoke Compile - name: Lint, Analysis & KMP Smoke Compile
if: inputs.run_lint == true if: inputs.run_lint == true
run: ./gradlew spotlessCheck detekt app:lintFdroidDebug app:lintGoogleDebug core:barcode:lintFdroidDebug core:barcode:lintGoogleDebug core:api:lintDebug kmpSmokeCompile -Pci=true --continue --scan run: ./gradlew spotlessCheck detekt androidApp:lintFdroidDebug androidApp:lintGoogleDebug core:barcode:lintFdroidDebug core:barcode:lintGoogleDebug core:api:lintDebug kmpSmokeCompile -Pci=true --continue --scan
- name: KMP Smoke Compile (lint skipped) - name: KMP Smoke Compile (lint skipped)
if: inputs.run_lint == false if: inputs.run_lint == false
@@ -152,13 +152,13 @@ jobs:
# See: https://github.com/meshtastic/Meshtastic-Android/issues/3231 # See: https://github.com/meshtastic/Meshtastic-Android/issues/3231
echo "── Step 1: Verify aboutlibraries.json determinism ──" echo "── Step 1: Verify aboutlibraries.json determinism ──"
rm -f app/src/main/resources/aboutlibraries.json rm -f androidApp/src/main/resources/aboutlibraries.json
./gradlew :app:exportLibraryDefinitions -Pci=true --no-configuration-cache ./gradlew :androidApp:exportLibraryDefinitions -Pci=true --no-configuration-cache
cp app/src/main/resources/aboutlibraries.json /tmp/aboutlibraries-run1.json cp androidApp/src/main/resources/aboutlibraries.json /tmp/aboutlibraries-run1.json
rm -f app/src/main/resources/aboutlibraries.json rm -f androidApp/src/main/resources/aboutlibraries.json
./gradlew :app:exportLibraryDefinitions -Pci=true --no-configuration-cache --rerun-tasks ./gradlew :androidApp:exportLibraryDefinitions -Pci=true --no-configuration-cache --rerun-tasks
cp app/src/main/resources/aboutlibraries.json /tmp/aboutlibraries-run2.json cp androidApp/src/main/resources/aboutlibraries.json /tmp/aboutlibraries-run2.json
if ! diff -q /tmp/aboutlibraries-run1.json /tmp/aboutlibraries-run2.json; then if ! diff -q /tmp/aboutlibraries-run1.json /tmp/aboutlibraries-run2.json; then
echo "::error::aboutlibraries.json is NOT deterministic across runs!" echo "::error::aboutlibraries.json is NOT deterministic across runs!"
@@ -168,9 +168,9 @@ jobs:
echo "✅ aboutlibraries.json is deterministic" echo "✅ aboutlibraries.json is deterministic"
echo "── Step 2: Build fdroid release APK ──" echo "── Step 2: Build fdroid release APK ──"
./gradlew :app:assembleFdroidRelease -Pci=true -Pmeshtastic.disableAbiSplits=true --no-configuration-cache ./gradlew :androidApp:assembleFdroidRelease -Pci=true -Pmeshtastic.disableAbiSplits=true --no-configuration-cache
APK=$(find app/build/outputs/apk/fdroid/release -name "*.apk" | head -1) APK=$(find androidApp/build/outputs/apk/fdroid/release -name "*.apk" | head -1)
if [ -z "$APK" ]; then if [ -z "$APK" ]; then
echo "::error::No fdroid release APK found" echo "::error::No fdroid release APK found"
exit 1 exit 1
@@ -295,7 +295,7 @@ jobs:
# Tests are split into 3 shards that run in parallel: # Tests are split into 3 shards that run in parallel:
# shard-core: core:* KMP module tests (allTests) # shard-core: core:* KMP module tests (allTests)
# shard-feature: feature:* KMP module tests (allTests) # shard-feature: feature:* KMP module tests (allTests)
# shard-app: Pure-Android/JVM tests (app, desktop, core:barcode, etc.) # shard-app: Pure-Android/JVM tests (androidApp, desktopApp, core:barcode, etc.)
test-shards: test-shards:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
permissions: permissions:
@@ -359,17 +359,17 @@ jobs:
:feature:settings:koverXmlReport :feature:settings:koverXmlReport
- name: shard-app - name: shard-app
tasks: >- tasks: >-
:app:testFdroidDebugUnitTest :androidApp:testFdroidDebugUnitTest
:app:testGoogleDebugUnitTest :androidApp:testGoogleDebugUnitTest
:desktop:test :desktopApp:test
:core:barcode:testFdroidDebugUnitTest :core:barcode:testFdroidDebugUnitTest
:core:barcode:testGoogleDebugUnitTest :core:barcode:testGoogleDebugUnitTest
kover: >- kover: >-
:app:koverXmlReportFdroidDebug :androidApp:koverXmlReportFdroidDebug
:app:koverXmlReportGoogleDebug :androidApp:koverXmlReportGoogleDebug
:core:barcode:koverXmlReportFdroidDebug :core:barcode:koverXmlReportFdroidDebug
:core:barcode:koverXmlReportGoogleDebug :core:barcode:koverXmlReportGoogleDebug
:desktop:koverXmlReport :desktopApp:koverXmlReport
steps: steps:
- name: Checkout code - name: Checkout code
@@ -447,14 +447,14 @@ jobs:
cache_read_only: ${{ needs.lint-check.outputs.cache_read_only }} cache_read_only: ${{ needs.lint-check.outputs.cache_read_only }}
- name: Build Android APKs - name: Build Android APKs
run: ./gradlew app:assembleFdroidDebug app:assembleGoogleDebug -Pci=true --parallel --configuration-cache --continue --scan run: ./gradlew androidApp:assembleFdroidDebug androidApp:assembleGoogleDebug -Pci=true --parallel --configuration-cache --continue --scan
- name: Upload debug artifact - name: Upload debug artifact
if: ${{ inputs.upload_artifacts }} if: ${{ inputs.upload_artifacts }}
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v7
with: with:
name: app-debug-apks name: app-debug-apks
path: app/build/outputs/apk/*/debug/*.apk path: androidApp/build/outputs/apk/*/debug/*.apk
retention-days: 7 retention-days: 7
- name: Report App Size - name: Report App Size
@@ -463,8 +463,47 @@ jobs:
echo "### App Size Report" >> $GITHUB_STEP_SUMMARY echo "### App Size Report" >> $GITHUB_STEP_SUMMARY
echo "| Artifact | Size |" >> $GITHUB_STEP_SUMMARY echo "| Artifact | Size |" >> $GITHUB_STEP_SUMMARY
echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY
find app/build/outputs/apk -name "*.apk" -exec du -h {} + | awk '{print "| " $2 " | " $1 " |"}' >> $GITHUB_STEP_SUMMARY find androidApp/build/outputs/apk -name "*.apk" -exec du -h {} + | awk '{print "| " $2 " | " $1 " |"}' >> $GITHUB_STEP_SUMMARY
# ── Desktop Build ───────────────────────────────────────────────────
build-desktop:
name: Build Desktop Debug (${{ matrix.os }})
if: inputs.run_desktop_builds == true
runs-on: ${{ matrix.os }}
permissions:
contents: read
timeout-minutes: 60
needs: lint-check
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-24.04, ubuntu-24.04-arm]
env:
VERSION_CODE: ${{ needs.lint-check.outputs.version_code }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 1
submodules: true
- name: Gradle Setup
uses: ./.github/actions/gradle-setup
with:
gradle_encryption_key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
cache_read_only: ${{ needs.lint-check.outputs.cache_read_only }}
- name: Build Desktop
run: ./gradlew :desktopApp:createDistributable -Pci=true --scan
- name: Upload Desktop artifact
if: ${{ inputs.upload_artifacts }}
uses: actions/upload-artifact@v7
with:
name: desktop-app-${{ runner.os }}-${{ runner.arch }}
path: desktopApp/build/compose/binaries/main/app/
retention-days: 7
# ── Flatpak Sources ─────────────────────────────────────────────────── # ── Flatpak Sources ───────────────────────────────────────────────────
build-flatpak-src: build-flatpak-src:
@@ -494,23 +533,8 @@ jobs:
with: with:
gradle_encryption_key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} gradle_encryption_key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
cache_read_only: true cache_read_only: true
- name: Python Setup
uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Install ast-grep
run: pip install ast-grep-cli
# Remove Android/iOS targets and other non-desktop bits
# that would break the flatpakGradleGenerator
- name: Prepare Offline Desktop Build
run: ./scripts/desktop-only-prep.sh
- name: Generate Flatpak Sources - name: Generate Flatpak Sources
env:
DESKTOP_ONLY: true
run: > run: >
./gradlew :build-logic:convention:flatpakGradleGenerator flatpakGradleGenerator ./gradlew :build-logic:convention:flatpakGradleGenerator flatpakGradleGenerator
--no-configuration-cache --refresh-dependencies --no-parallel --no-configuration-cache --refresh-dependencies --no-parallel
+4 -4
View File
@@ -22,7 +22,7 @@ jobs:
- name: Update firmware releases list - name: Update firmware releases list
id: firmware id: firmware
run: | run: |
firmware_file_path="app/src/main/assets/firmware_releases.json" firmware_file_path="androidApp/src/main/assets/firmware_releases.json"
temp_firmware_file="/tmp/new_firmware_releases.json" temp_firmware_file="/tmp/new_firmware_releases.json"
echo "Fetching latest firmware releases..." echo "Fetching latest firmware releases..."
@@ -51,7 +51,7 @@ jobs:
- name: Update hardware list - name: Update hardware list
id: hardware id: hardware
run: | run: |
hardware_file_path="app/src/main/assets/device_hardware.json" hardware_file_path="androidApp/src/main/assets/device_hardware.json"
temp_hardware_file="/tmp/new_device_hardware.json" temp_hardware_file="/tmp/new_device_hardware.json"
echo "Fetching latest device hardware data..." echo "Fetching latest device hardware data..."
@@ -172,8 +172,8 @@ jobs:
base: 'main' base: 'main'
delete-branch: true delete-branch: true
add-paths: | add-paths: |
app/src/main/assets/firmware_releases.json androidApp/src/main/assets/firmware_releases.json
app/src/main/assets/device_hardware.json androidApp/src/main/assets/device_hardware.json
fastlane/metadata/android/** fastlane/metadata/android/**
**/strings.xml **/strings.xml
**/README.md **/README.md
+4 -4
View File
@@ -23,8 +23,8 @@ When reviewing code, meticulously verify the following categories. Flag any devi
- [ ] **Compose Multiplatform Resources:** Ensure NO hardcoded strings. Must use `core:resources` (e.g., `stringResource(Res.string.key)` or asynchronous `getStringSuspend(Res.string.key)` for ViewModels/Coroutines). NEVER use blocking `getString()` in a coroutine. - [ ] **Compose Multiplatform Resources:** Ensure NO hardcoded strings. Must use `core:resources` (e.g., `stringResource(Res.string.key)` or asynchronous `getStringSuspend(Res.string.key)` for ViewModels/Coroutines). NEVER use blocking `getString()` in a coroutine.
- [ ] **String Formatting:** CMP only supports `%N$s` and `%N$d`. Flag any float formats (`%N$.1f`) in Compose string resources; they must be pre-formatted using `NumberFormatter.format()` from `core:common`. Use `MetricFormatter` for metric-specific displays (temperature, voltage, current, percent, humidity, pressure, SNR, RSSI). - [ ] **String Formatting:** CMP only supports `%N$s` and `%N$d`. Flag any float formats (`%N$.1f`) in Compose string resources; they must be pre-formatted using `NumberFormatter.format()` from `core:common`. Use `MetricFormatter` for metric-specific displays (temperature, voltage, current, percent, humidity, pressure, SNR, RSSI).
- [ ] **Centralized Dialogs & Alerts:** Flag inline alert-rendering logic. Mandate the use of `AlertHost(alertManager)` or `SharedDialogs` from `core:ui/commonMain`. - [ ] **Centralized Dialogs & Alerts:** Flag inline alert-rendering logic. Mandate the use of `AlertHost(alertManager)` or `SharedDialogs` from `core:ui/commonMain`.
- [ ] **Placeholders:** Require `PlaceholderScreen(name)` from `core:ui/commonMain` for unimplemented desktop/JVM features. No inline placeholders in feature modules. - [ ] **Placeholders:** Require `PlaceholderScreen(name)` from `core:ui/commonMain` for unimplemented desktopApp/JVM features. No inline placeholders in feature modules.
- [ ] **Adaptive Layouts:** Verify use of `currentWindowAdaptiveInfo(supportLargeAndXLargeWidth = true)` to support desktop/tablet breakpoints (≥ 1200dp). - [ ] **Adaptive Layouts:** Verify use of `currentWindowAdaptiveInfo(supportLargeAndXLargeWidth = true)` to support desktopApp/tablet breakpoints (≥ 1200dp).
### 3. Navigation & State ### 3. Navigation & State
- [ ] **Shared Navigation Graphs:** Feature navigation graphs must be defined as extension functions on `EntryProviderScope<NavKey>` in `commonMain` (e.g., `fun EntryProviderScope<NavKey>.settingsGraph(...)`). Flag any graphs defined in platform-specific source sets. - [ ] **Shared Navigation Graphs:** Feature navigation graphs must be defined as extension functions on `EntryProviderScope<NavKey>` in `commonMain` (e.g., `fun EntryProviderScope<NavKey>.settingsGraph(...)`). Flag any graphs defined in platform-specific source sets.
@@ -56,8 +56,8 @@ When reviewing code, meticulously verify the following categories. Flag any devi
- [ ] **Robolectric Configuration:** Check that Compose UI tests running via Robolectric on JVM are pinned to `@Config(sdk = [34])` to prevent Java 21 / SDK 35 compatibility issues. - [ ] **Robolectric Configuration:** Check that Compose UI tests running via Robolectric on JVM are pinned to `@Config(sdk = [34])` to prevent Java 21 / SDK 35 compatibility issues.
### 8. ProGuard / R8 Rules ### 8. ProGuard / R8 Rules
- [ ] **New Dependencies:** If a new reflection-heavy dependency is added (DI, serialization, JNI, ServiceLoader), verify keep rules exist in **both** `app/proguard-rules.pro` (R8) and `desktop/proguard-rules.pro` (ProGuard). The two files must stay aligned. - [ ] **New Dependencies:** If a new reflection-heavy dependency is added (DI, serialization, JNI, ServiceLoader), verify keep rules exist in **both** `androidApp/proguard-rules.pro` (R8) and `desktopApp/proguard-rules.pro` (ProGuard). The two files must stay aligned.
- [ ] **Release Smoke-Test:** For dependency or ProGuard rule changes, verify `assembleRelease` and `./gradlew :desktop:runRelease` succeed. - [ ] **Release Smoke-Test:** For dependency or ProGuard rule changes, verify `assembleRelease` and `./gradlew :desktopApp:runRelease` succeed.
## Review Output Guidelines ## Review Output Guidelines
1. **Be Specific & Constructive:** Provide exact file references and code snippets illustrating the required project pattern. 1. **Be Specific & Constructive:** Provide exact file references and code snippets illustrating the required project pattern.
+3 -3
View File
@@ -4,9 +4,9 @@
Guidelines for building shared UI, adaptive layouts, and handling strings/resources in Meshtastic-Android. The codebase uses Material 3 Adaptive. Guidelines for building shared UI, adaptive layouts, and handling strings/resources in Meshtastic-Android. The codebase uses Material 3 Adaptive.
## 1. UI Components & Layouts ## 1. UI Components & Layouts
- **Material 3 / Adaptive:** Use `currentWindowAdaptiveInfo(supportLargeAndXLargeWidth = true)` to support Large (1200dp) and XL (1600dp) breakpoints. Investigate 3-pane "Power User" scenes using Navigation 3 Scenes and draggable dividers for desktop/tablets. - **Material 3 / Adaptive:** Use `currentWindowAdaptiveInfo(supportLargeAndXLargeWidth = true)` to support Large (1200dp) and XL (1600dp) breakpoints. Investigate 3-pane "Power User" scenes using Navigation 3 Scenes and draggable dividers for desktopApp/tablets.
- **Dialogs & Alerts:** Use centralized components like `AlertHost(alertManager)` from `core:ui/commonMain`. Do NOT trigger alerts inline or duplicate alert logic. Use `SharedDialogs(uiViewModel)` for general popups. - **Dialogs & Alerts:** Use centralized components like `AlertHost(alertManager)` from `core:ui/commonMain`. Do NOT trigger alerts inline or duplicate alert logic. Use `SharedDialogs(uiViewModel)` for general popups.
- **Placeholders:** Use `PlaceholderScreen(name)` from `core:ui/commonMain` for unimplemented desktop/JVM features. - **Placeholders:** Use `PlaceholderScreen(name)` from `core:ui/commonMain` for unimplemented desktopApp/JVM features.
- **Theme Picker:** Use `ThemePickerDialog` from `feature:settings/commonMain`. - **Theme Picker:** Use `ThemePickerDialog` from `feature:settings/commonMain`.
- **Platform Implementations:** Inject platform-specific behavior (e.g., Map providers) via `CompositionLocal` from the `app` or `desktop` shells. Do not tightly couple Google Maps/osmdroid dependencies to `commonMain`. - **Platform Implementations:** Inject platform-specific behavior (e.g., Map providers) via `CompositionLocal` from the `app` or `desktop` shells. Do not tightly couple Google Maps/osmdroid dependencies to `commonMain`.
@@ -58,4 +58,4 @@ Choose the right tool for the job:
## Reference Anchors ## Reference Anchors
- **Shared Strings:** `core/resources/src/commonMain/composeResources/values/strings.xml` - **Shared Strings:** `core/resources/src/commonMain/composeResources/values/strings.xml`
- **Platform abstraction contract:** `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/MapViewProvider.kt` - **Platform abstraction contract:** `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/MapViewProvider.kt`
- **Provider wiring:** `app/src/main/kotlin/org/meshtastic/app/MainActivity.kt` - **Provider wiring:** `androidApp/src/main/kotlin/org/meshtastic/app/MainActivity.kt`
+2 -2
View File
@@ -35,7 +35,7 @@ A step-by-step workflow for implementing a new feature in the Meshtastic-Android
```bash ```bash
./gradlew spotlessCheck spotlessApply detekt assembleDebug test allTests ./gradlew spotlessCheck spotlessApply detekt assembleDebug test allTests
``` ```
- If the feature adds a new reflection-heavy dependency, add keep rules to **both** `app/proguard-rules.pro` and `desktop/proguard-rules.pro`, then verify release builds: - If the feature adds a new reflection-heavy dependency, add keep rules to **both** `androidApp/proguard-rules.pro` and `desktopApp/proguard-rules.pro`, then verify release builds:
```bash ```bash
./gradlew assembleFdroidRelease :desktop:runRelease ./gradlew assembleFdroidRelease :desktopApp:runRelease
``` ```
+2 -2
View File
@@ -52,10 +52,10 @@ Guidelines on managing Kotlin Multiplatform (KMP) source-sets, expected abstract
1. Ensure all new logic compiles against the KMP core (`jvm()`, `iosArm64()`, etc.). 1. Ensure all new logic compiles against the KMP core (`jvm()`, `iosArm64()`, etc.).
2. Do not use platform-specific constructs in `commonMain` or you break the iOS/Desktop builds. 2. Do not use platform-specific constructs in `commonMain` or you break the iOS/Desktop builds.
3. Test using `kmpSmokeCompile` to verify cross-platform compilation. 3. Test using `kmpSmokeCompile` to verify cross-platform compilation.
4. For desktop wiring, copy the pattern in `desktop/src/main/kotlin/org/meshtastic/desktop/di/DesktopKoinModule.kt` and use `NoopStubs.kt` to temporarily mock missing platform implementations. 4. For desktop wiring, copy the pattern in `desktopApp/src/main/kotlin/org/meshtastic/desktop/di/DesktopKoinModule.kt` and use `NoopStubs.kt` to temporarily mock missing platform implementations.
## Reference Anchors ## Reference Anchors
- **Shared Okio I/O:** `core/domain/src/commonMain/kotlin/org/meshtastic/core/domain/usecase/settings/ImportProfileUseCase.kt` - **Shared Okio I/O:** `core/domain/src/commonMain/kotlin/org/meshtastic/core/domain/usecase/settings/ImportProfileUseCase.kt`
- **Desktop DI Stubs:** `desktop/src/main/kotlin/org/meshtastic/desktop/stub/NoopStubs.kt` - **Desktop DI Stubs:** `desktopApp/src/main/kotlin/org/meshtastic/desktop/stub/NoopStubs.kt`
- **Version Catalog:** `gradle/libs.versions.toml` - **Version Catalog:** `gradle/libs.versions.toml`
- **Convention Plugins:** `build-logic/convention/` - **Convention Plugins:** `build-logic/convention/`
+5 -5
View File
@@ -7,7 +7,7 @@ This skill covers dependency injection (Koin Annotations 4.2.x) and JetBrains Na
### Guidelines ### Guidelines
1. **Annotations First:** Use `@Module`, `@ComponentScan`, and `@KoinViewModel` annotations directly in `commonMain` shared modules to encapsulate dependency graphs per feature. 1. **Annotations First:** Use `@Module`, `@ComponentScan`, and `@KoinViewModel` annotations directly in `commonMain` shared modules to encapsulate dependency graphs per feature.
2. **App Root Assembly:** Don't assume feature/core `@Module` classes are active automatically. Ensure they are included by the app root module (`@Module(includes = [...])`) in `app/src/main/kotlin/org/meshtastic/app/di/AppKoinModule.kt` and `desktop/.../DesktopKoinModule.kt`. 2. **App Root Assembly:** Don't assume feature/core `@Module` classes are active automatically. Ensure they are included by the app root module (`@Module(includes = [...])`) in `androidApp/src/main/kotlin/org/meshtastic/app/di/AppKoinModule.kt` and `desktopApp/.../DesktopKoinModule.kt`.
3. **No Platform Bleed:** Don't put Android framework dependencies (`Context`, `Activity`, `Application`) into shared `commonMain` business logic. Inject interfaces instead. 3. **No Platform Bleed:** Don't put Android framework dependencies (`Context`, `Activity`, `Application`) into shared `commonMain` business logic. Inject interfaces instead.
4. **Resolution:** Resolve app-layer wrappers via `koinViewModel()` or injected bindings within Compose navigation graphs. 4. **Resolution:** Resolve app-layer wrappers via `koinViewModel()` or injected bindings within Compose navigation graphs.
@@ -49,8 +49,8 @@ startKoin<AndroidKoinApp> {
- **Custom Backstack Mutation:** Do **not** mutate back navigation with custom stacks disconnected from the app backstack. Mutate `NavBackStack<NavKey>` directly with `add(...)` and `removeLastOrNull()`. - **Custom Backstack Mutation:** Do **not** mutate back navigation with custom stacks disconnected from the app backstack. Mutate `NavBackStack<NavKey>` directly with `add(...)` and `removeLastOrNull()`.
## Reference Anchors ## Reference Anchors
- **App Startup / Koin Bootstrap:** `app/src/main/kotlin/org/meshtastic/app/MeshUtilApplication.kt` - **App Startup / Koin Bootstrap:** `androidApp/src/main/kotlin/org/meshtastic/app/MeshUtilApplication.kt`
- **DI Bootstrap Object:** `app/src/main/kotlin/org/meshtastic/app/di/AndroidKoinApp.kt` - **DI Bootstrap Object:** `androidApp/src/main/kotlin/org/meshtastic/app/di/AndroidKoinApp.kt`
- **DI App Wiring:** `app/src/main/kotlin/org/meshtastic/app/di/AppKoinModule.kt` - **DI App Wiring:** `androidApp/src/main/kotlin/org/meshtastic/app/di/AppKoinModule.kt`
- **Shared Routes:** `core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt` - **Shared Routes:** `core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt`
- **Desktop Nav Shell:** `desktop/src/main/kotlin/org/meshtastic/desktop/ui/DesktopMainScreen.kt` - **Desktop Nav Shell:** `desktopApp/src/main/kotlin/org/meshtastic/desktop/ui/DesktopMainScreen.kt`
+2 -2
View File
@@ -11,7 +11,7 @@ Module directory, namespacing conventions, environment setup, and troubleshootin
| Directory | Description | | Directory | Description |
| :--- | :--- | | :--- | :--- |
| `app/` | Main application module. Contains `MainActivity`, Koin DI modules, and app-level logic. Uses package `org.meshtastic.app`. | | `androidApp/` | Main application module. Contains `MainActivity`, Koin DI modules, and app-level logic. Uses package `org.meshtastic.app`. |
| `build-logic/` | Convention plugins for shared build configuration (e.g., `meshtastic.kmp.feature`, `meshtastic.kmp.library`, `meshtastic.kmp.jvm.android`, `meshtastic.koin`). | | `build-logic/` | Convention plugins for shared build configuration (e.g., `meshtastic.kmp.feature`, `meshtastic.kmp.library`, `meshtastic.kmp.jvm.android`, `meshtastic.koin`). |
| `config/` | Detekt static analysis rules (`config/detekt/detekt.yml`) and Spotless formatting config (`config/spotless/.editorconfig`). | | `config/` | Detekt static analysis rules (`config/detekt/detekt.yml`) and Spotless formatting config (`config/spotless/.editorconfig`). |
| `docs/` | Architecture docs and agent playbooks. See `docs/kmp-status.md` and `docs/roadmap.md` for current status. | | `docs/` | Architecture docs and agent playbooks. See `docs/kmp-status.md` and `docs/roadmap.md` for current status. |
@@ -38,7 +38,7 @@ Module directory, namespacing conventions, environment setup, and troubleshootin
| `feature/` | Feature modules (e.g., `settings`, `map`, `messaging`, `node`, `intro`, `connections`, `firmware`, `wifi-provision`, `widget`). All are KMP except `widget`. Use `meshtastic.kmp.feature` convention plugin. | | `feature/` | Feature modules (e.g., `settings`, `map`, `messaging`, `node`, `intro`, `connections`, `firmware`, `wifi-provision`, `widget`). All are KMP except `widget`. Use `meshtastic.kmp.feature` convention plugin. |
| `feature/wifi-provision` | KMP WiFi provisioning via BLE (Nymea protocol). Uses `core:ble` Kable abstractions. | | `feature/wifi-provision` | KMP WiFi provisioning via BLE (Nymea protocol). Uses `core:ble` Kable abstractions. |
| `feature/firmware` | Fully KMP firmware update system: Unified OTA (BLE + WiFi), native Nordic Secure DFU protocol (pure KMP), USB/UF2 updates, and `FirmwareRetriever` with manifest-based resolution. Desktop is a first-class target. | | `feature/firmware` | Fully KMP firmware update system: Unified OTA (BLE + WiFi), native Nordic Secure DFU protocol (pure KMP), USB/UF2 updates, and `FirmwareRetriever` with manifest-based resolution. Desktop is a first-class target. |
| `desktop/` | Compose Desktop application. Thin host shell relying on feature modules for shared UI. Full Koin DI graph, TCP, Serial/USB, and BLE transports. Versioning via `config.properties` + `GitVersionValueSource`. | | `desktopApp/` | Compose Desktop application. Thin host shell relying on feature modules for shared UI. Full Koin DI graph, TCP, Serial/USB, and BLE transports. Versioning via `config.properties` + `GitVersionValueSource`. |
## Namespacing ## Namespacing
- **Standard:** Use the `org.meshtastic.*` namespace for all code. - **Standard:** Use the `org.meshtastic.*` namespace for all code.
+1 -1
View File
@@ -17,7 +17,7 @@ Run in a single invocation for routine changes to ensure code formatting, analys
> In KMP modules, the `test` task name is **ambiguous**. Gradle matches both `testAndroid` and > In KMP modules, the `test` task name is **ambiguous**. Gradle matches both `testAndroid` and
> `testAndroidHostTest` and refuses to run either, silently skipping KMP modules. > `testAndroidHostTest` and refuses to run either, silently skipping KMP modules.
> `allTests` is the `KotlinTestReport` lifecycle task registered by the KMP plugin. > `allTests` is the `KotlinTestReport` lifecycle task registered by the KMP plugin.
> Conversely, `allTests` does **not** cover pure-Android modules (`:app`, `:core:api`, etc.), which is why both `test` and `allTests` are needed. > Conversely, `allTests` does **not** cover pure-Android modules (`:androidApp`, `:core:api`, etc.), which is why both `test` and `allTests` are needed.
*Note: If testing Compose UI on the JVM (Robolectric) with Java 21, pin tests to `@Config(sdk = [34])` to avoid SDK 35 compatibility crashes.* *Note: If testing Compose UI on the JVM (Robolectric) with Java 21, pin tests to `@Config(sdk = [34])` to avoid SDK 35 compatibility crashes.*
+1 -1
View File
@@ -1 +1 @@
{"feature_directory":"specs/20260511-211823-compose-screenshot-testing"} {"feature_directory":"specs/006-kmp-project-structure"}
+1 -1
View File
@@ -49,5 +49,5 @@ You are an expert Android/KMP engineer. Maintain architectural boundaries, use M
<!-- SPECKIT START --> <!-- SPECKIT START -->
For additional context about technologies to be used, project structure, For additional context about technologies to be used, project structure,
shell commands, and other important information, read the current plan shell commands, and other important information, read the current plan
at `specs/20260511-211823-compose-screenshot-testing/plan.md` at `specs/006-kmp-project-structure/plan.md`
<!-- SPECKIT END --> <!-- SPECKIT END -->
+1 -1
View File
@@ -20,7 +20,7 @@ Thank you for your interest in contributing to Meshtastic-Android! We welcome co
- Add comments where necessary, especially for complex logic. - Add comments where necessary, especially for complex logic.
- Keep methods and classes focused and concise. - Keep methods and classes focused and concise.
- **Strings:** Use localised strings via the **Compose Multiplatform Resource** library in `:core:resources`. - **Strings:** Use localised strings via the **Compose Multiplatform Resource** library in `:core:resources`.
- Do **not** use the legacy `app/src/main/res/values/strings.xml`. - Do **not** use the legacy `androidApp/src/main/res/values/strings.xml`.
- **Definition:** Add strings to `core/resources/src/commonMain/composeResources/values/strings.xml`. - **Definition:** Add strings to `core/resources/src/commonMain/composeResources/values/strings.xml`.
- **Usage:** - **Usage:**
```kotlin ```kotlin
+31 -31
View File
@@ -1,7 +1,7 @@
# `:app` # `:androidApp`
## Overview ## Overview
The `:app` module is the entry point for the Meshtastic Android application. It orchestrates the various feature modules, manages global state, and provides the main UI shell. The `:androidApp` module is the entry point for the Meshtastic Android application. It orchestrates the various feature modules, manages global state, and provides the main UI shell.
## Key Components ## Key Components
@@ -9,7 +9,7 @@ The `:app` module is the entry point for the Meshtastic Android application. It
The single Activity of the application. It hosts the shared `MeshtasticNavDisplay` navigation shell and manages the root UI structure (Navigation Bar, Rail, etc.). The single Activity of the application. It hosts the shared `MeshtasticNavDisplay` navigation shell and manages the root UI structure (Navigation Bar, Rail, etc.).
### 2. `MeshService` ### 2. `MeshService`
The core background service that manages long-running communication with the mesh radio. While it is declared in the `:app` manifest for system visibility, its implementation resides in the `:core:service` module. It runs as a **Foreground Service** to ensure reliable communication even when the app is in the background. The core background service that manages long-running communication with the mesh radio. While it is declared in the `:androidApp` manifest for system visibility, its implementation resides in the `:core:service` module. It runs as a **Foreground Service** to ensure reliable communication even when the app is in the background.
### 3. Koin Application ### 3. Koin Application
`MeshUtilApplication` is the Koin entry point, providing the global dependency injection container. `MeshUtilApplication` is the Koin entry point, providing the global dependency injection container.
@@ -24,34 +24,34 @@ The module primarily serves as a "glue" layer, connecting:
<!--region graph--> <!--region graph-->
```mermaid ```mermaid
graph TB graph TB
:app[app]:::android-application :androidApp[androidApp]:::android-application
:app -.-> :core:ble :androidApp -.-> :core:ble
:app -.-> :core:common :androidApp -.-> :core:common
:app -.-> :core:data :androidApp -.-> :core:data
:app -.-> :core:database :androidApp -.-> :core:database
:app -.-> :core:datastore :androidApp -.-> :core:datastore
:app -.-> :core:di :androidApp -.-> :core:di
:app -.-> :core:domain :androidApp -.-> :core:domain
:app -.-> :core:model :androidApp -.-> :core:model
:app -.-> :core:navigation :androidApp -.-> :core:navigation
:app -.-> :core:network :androidApp -.-> :core:network
:app -.-> :core:nfc :androidApp -.-> :core:nfc
:app -.-> :core:prefs :androidApp -.-> :core:prefs
:app -.-> :core:proto :androidApp -.-> :core:proto
:app -.-> :core:service :androidApp -.-> :core:service
:app -.-> :core:resources :androidApp -.-> :core:resources
:app -.-> :core:ui :androidApp -.-> :core:ui
:app -.-> :core:barcode :androidApp -.-> :core:barcode
:app -.-> :core:takserver :androidApp -.-> :core:takserver
:app -.-> :feature:intro :androidApp -.-> :feature:intro
:app -.-> :feature:messaging :androidApp -.-> :feature:messaging
:app -.-> :feature:connections :androidApp -.-> :feature:connections
:app -.-> :feature:map :androidApp -.-> :feature:map
:app -.-> :feature:node :androidApp -.-> :feature:node
:app -.-> :feature:settings :androidApp -.-> :feature:settings
:app -.-> :feature:firmware :androidApp -.-> :feature:firmware
:app -.-> :feature:wifi-provision :androidApp -.-> :feature:wifi-provision
:app -.-> :feature:widget :androidApp -.-> :feature:widget
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000; classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-application-compose fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000; classDef android-application-compose fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
@@ -116,7 +116,7 @@ configure<ApplicationExtension> {
} }
// Disable ABI splits for bundle builds or when explicitly requested via Gradle property. // Disable ABI splits for bundle builds or when explicitly requested via Gradle property.
// Usage: ./gradlew :app:bundleGoogleRelease -Pmeshtastic.disableAbiSplits=true // Usage: ./gradlew :androidApp:bundleGoogleRelease -Pmeshtastic.disableAbiSplits=true
val disableSplits = providers.gradleProperty("meshtastic.disableAbiSplits").map { it.toBoolean() }.getOrElse(false) val disableSplits = providers.gradleProperty("meshtastic.disableAbiSplits").map { it.toBoolean() }.getOrElse(false)
// Enable ABI splits to generate smaller APKs per architecture for F-Droid/IzzyOnDroid // Enable ABI splits to generate smaller APKs per architecture for F-Droid/IzzyOnDroid

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Some files were not shown because too many files have changed in this diff Show More