ci: Update Dokka configuration and unify AboutLibraries JSON generation (#4767)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich
2026-03-12 20:49:11 -05:00
committed by GitHub
parent 629d80ec65
commit 3321c47200
14 changed files with 43 additions and 79 deletions

View File

@@ -149,6 +149,11 @@ jobs:
ruby-version: '3.4.9'
bundler-cache: true
- name: Export Full Library Licenses
env:
GITHUB_TOKEN: ${{ github.token }}
run: ./gradlew exportLibraryDefinitions -Pci=true
- name: Build and Deploy Google Play to Internal Track with Fastlane
env:
VERSION_NAME: ${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}
@@ -229,6 +234,11 @@ jobs:
ruby-version: '3.4.9'
bundler-cache: true
- name: Export Full Library Licenses
env:
GITHUB_TOKEN: ${{ github.token }}
run: ./gradlew exportLibraryDefinitions -Pci=true
- name: Build F-Droid with Fastlane
env:
VERSION_NAME: ${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}
@@ -285,6 +295,11 @@ jobs:
build-scan-terms-of-use-url: 'https://gradle.com/terms-of-service'
build-scan-terms-of-use-agree: 'yes'
- name: Export Full Library Licenses
env:
GITHUB_TOKEN: ${{ github.token }}
run: ./gradlew exportLibraryDefinitions -Pci=true
- name: Package Native Distributions
run: ./gradlew :desktop:packageReleaseDistributionForCurrentOS -PappVersionName=${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }} --no-daemon
@@ -343,4 +358,4 @@ jobs:
generate_release_notes: false
files: ./artifacts/*/*
draft: false
prerelease: true
prerelease: true

5
.gitignore vendored
View File

@@ -37,6 +37,9 @@ keystore.properties
/fastlane/play-store-credentials.json
**/google-services.json
# Generated library definitions
**/src/main/resources/aboutlibraries.json
/fastlane/report.xml
/build-logic/convention/build/*
@@ -48,4 +51,4 @@ wireless-install.sh
# Git worktrees
.worktrees/
/firebase-debug.log
/firebase-debug.log

View File

@@ -337,7 +337,10 @@ aboutLibraries {
gitHubApiToken = ghToken.get()
}
}
export { excludeFields = listOf("generated") }
export {
excludeFields = listOf("generated")
outputFile = file("src/main/resources/aboutlibraries.json")
}
library {
duplicationMode = DuplicateMode.MERGE
duplicationRule = DuplicateRule.SIMPLE

View File

@@ -29,7 +29,6 @@ import org.koin.compose.viewmodel.koinViewModel
import org.meshtastic.app.settings.AndroidDebugViewModel
import org.meshtastic.app.settings.AndroidRadioConfigViewModel
import org.meshtastic.app.settings.AndroidSettingsViewModel
import org.meshtastic.app.util.AboutLibrariesJsonProvider
import org.meshtastic.core.navigation.NodesRoutes
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
@@ -185,10 +184,7 @@ fun EntryProviderScope<NavKey>.settingsGraph(backStack: NavBackStack<NavKey>) {
entry<SettingsRoutes.About> {
AboutScreen(
onNavigateUp = { backStack.removeLastOrNull() },
jsonProvider = {
// Load from AboutLibraries asset/classpath resource
AboutLibrariesJsonProvider.getJson()
},
jsonProvider = { SettingsRoutes::class.java.getResource("/aboutlibraries.json")?.readText() ?: "" },
)
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright (c) 2025-2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.meshtastic.app.util
import co.touchlab.kermit.Logger
import java.io.IOException
/**
* Provides the AboutLibraries JSON data for the About screen.
*
* The JSON is generated by the AboutLibraries Gradle plugin during the build process. For Android, we load it from the
* application's assets or classpath resource.
*/
object AboutLibrariesJsonProvider {
private val logger = Logger.withTag("AboutLibrariesJsonProvider")
/**
* Returns the AboutLibraries JSON string.
*
* Since the AboutLibraries Gradle plugin generates the JSON at build time, we attempt to load it from the
* classpath. If that fails, we return an empty object to allow the app to gracefully degrade.
*/
suspend fun getJson(): String = try {
val resource = AboutLibrariesJsonProvider::class.java.classLoader?.getResource("aboutlibraries.json")
if (resource != null) {
resource.readText()
} else {
// Fallback: return an empty libraries object
logger.w("AboutLibraries JSON resource not found in classpath")
"""{"libraries":[]}"""
}
} catch (e: SecurityException) {
// Security exception when accessing resources - return fallback
logger.w("SecurityException loading AboutLibraries JSON: ${e.message}")
"""{"libraries":[]}"""
} catch (e: IllegalStateException) {
// Libraries not generated/available - return fallback
logger.w("IllegalStateException loading AboutLibraries JSON: ${e.message}")
"""{"libraries":[]}"""
} catch (e: IOException) {
// I/O exception when reading resource - return fallback
logger.w("IOException loading AboutLibraries JSON: ${e.message}")
"""{"libraries":[]}"""
}
}

View File

@@ -42,6 +42,8 @@ fun Project.configureDokka() {
"main",
"commonMain",
"androidMain",
"jvmMain",
"jvmAndroidMain",
"fdroid",
"google",
"release"

View File

@@ -49,6 +49,11 @@ internal enum class PluginType(val id: String, val ref: String, val style: Strin
ref = "android-application-compose",
style = "fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000",
),
ComposeDesktopApplication(
id = "org.jetbrains.compose",
ref = "compose-desktop-application",
style = "fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000",
),
AndroidFeature(
id = "meshtastic.android.feature",
ref = "android-feature",
@@ -117,6 +122,7 @@ internal fun Project.configureGraphTasks() {
val projectPlugins = mutableMapOf<String, PluginType>()
val type = when {
pluginManager.hasPlugin("meshtastic.android.application") || pluginManager.hasPlugin("meshtastic.android.application.compose") -> PluginType.AndroidApplication
targetProjectPath.startsWith(":desktop") -> PluginType.ComposeDesktopApplication
targetProjectPath.startsWith(":feature:") -> PluginType.AndroidFeature
else -> PluginType.entries.firstOrNull { pluginManager.hasPlugin(it.id) } ?: Unknown
}

View File

@@ -34,7 +34,7 @@ plugins {
alias(libs.plugins.kotlin.multiplatform) apply false
alias(libs.plugins.kotlin.parcelize) apply false
alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.aboutlibraries) apply false
alias(libs.plugins.secrets) apply false
alias(libs.plugins.detekt) apply false
alias(libs.plugins.kover)

View File

@@ -33,6 +33,8 @@ kotlin {
sourceSets {
commonMain.dependencies {
api(libs.aboutlibraries.core)
implementation(libs.aboutlibraries.compose.m3)
implementation(libs.javax.inject)
implementation(libs.kotlinx.atomicfu)
implementation(libs.kotlinx.coroutines.core)

View File

@@ -28,7 +28,7 @@ plugins {
alias(libs.plugins.meshtastic.detekt)
alias(libs.plugins.meshtastic.spotless)
alias(libs.plugins.meshtastic.koin)
alias(libs.plugins.aboutlibraries.base)
alias(libs.plugins.aboutlibraries)
}
kotlin {
@@ -60,6 +60,9 @@ compose.desktop {
}
dependencies {
implementation(libs.aboutlibraries.core)
implementation(libs.aboutlibraries.compose.m3)
// Core KMP modules (JVM variants)
implementation(projects.core.common)
implementation(projects.core.di)

View File

@@ -196,9 +196,7 @@ fun EntryProviderScope<NavKey>.desktopSettingsGraph(backStack: NavBackStack<NavK
entry<SettingsRoutes.About> {
AboutScreen(
onNavigateUp = { backStack.removeLastOrNull() },
jsonProvider = {
object {}.javaClass.getResourceAsStream("/aboutlibraries.json")?.bufferedReader()?.readText() ?: ""
},
jsonProvider = { SettingsRoutes::class.java.getResource("/aboutlibraries.json")?.readText() ?: "" },
)
}

View File

File diff suppressed because one or more lines are too long

View File

@@ -51,9 +51,7 @@ import org.meshtastic.core.ui.component.MainAppBar
* - **contentPadding**: proper LazyColumn padding (avoids clipping during scroll)
* - **license dialog**: built-in license dialog on library tap (default behavior)
*
* Each platform provides a [jsonProvider] lambda that loads the library definitions JSON:
* - Android: reads from `R.raw.aboutlibraries` (auto-generated by `.android` plugin)
* - Desktop: reads from JVM classpath resource (exported via `aboutlibraries-base` plugin)
* Each platform provides a [jsonProvider] lambda that loads the library definitions JSON
*
* @see <a href="https://github.com/mikepenz/AboutLibraries">AboutLibraries KMP</a>
*/

View File

@@ -288,10 +288,8 @@ firebase-crashlytics = { id = "com.google.firebase.crashlytics", version = "3.0.
firebase-perf = { id = "com.google.firebase.firebase-perf", version = "2.0.2" }
# Other
aboutlibraries = { id = "com.mikepenz.aboutlibraries.plugin.android", version.ref = "aboutlibraries" }
aboutlibraries-base = { id = "com.mikepenz.aboutlibraries.plugin", version.ref = "aboutlibraries" }
aboutlibraries = { id = "com.mikepenz.aboutlibraries.plugin", version.ref = "aboutlibraries" }
datadog = { id = "com.datadoghq.dd-sdk-android-gradle-plugin", version = "1.23.0" }
# Removed dependency-analysis = { id = "com.autonomousapps.dependency-analysis", version = "3.5.1" }
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
wire = { id = "com.squareup.wire", version.ref = "wire" }