Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
148 lines
6.0 KiB
Groovy
148 lines
6.0 KiB
Groovy
plugins {
|
|
alias(libs.plugins.android.application)
|
|
}
|
|
|
|
android {
|
|
namespace 'com.evsuite.abrp'
|
|
compileSdk {
|
|
version = release(36) {
|
|
minorApiLevel = 1
|
|
}
|
|
}
|
|
|
|
// Signature de l'APK — rien à voir avec la clé d'API ABRP de l'utilisateur.
|
|
// Ces valeurs servent UNIQUEMENT au build : elles prouvent que l'APK vient bien de
|
|
// nous et n'entrent jamais dans l'application. La clé d'API et le token ABRP, eux,
|
|
// sont saisis dans l'app et stockés chiffrés sur l'appareil (voir SecurePrefs).
|
|
//
|
|
// Un keystore contient plusieurs clés : SIGNING_STORE_PASSWORD ouvre le conteneur,
|
|
// SIGNING_KEY_ALIAS choisit la clé, SIGNING_KEY_PASSWORD ouvre cette clé-là.
|
|
// Lues depuis l'environnement (CI) ou gradle.properties local — JAMAIS commitées.
|
|
def keystorePath = System.getenv("SIGNING_KEYSTORE") ?: project.findProperty("signing.keystore")
|
|
signingConfigs {
|
|
if (keystorePath != null && file(keystorePath).exists()) {
|
|
platform {
|
|
storeFile file(keystorePath)
|
|
storePassword System.getenv("SIGNING_STORE_PASSWORD") ?: project.findProperty("signing.store.password")
|
|
keyAlias System.getenv("SIGNING_KEY_ALIAS") ?: project.findProperty("signing.key.alias") ?: "platform"
|
|
keyPassword System.getenv("SIGNING_KEY_PASSWORD") ?: project.findProperty("signing.key.password")
|
|
}
|
|
}
|
|
}
|
|
|
|
defaultConfig {
|
|
applicationId "com.stinnesbeck.nilsmg4"
|
|
minSdk 27
|
|
targetSdk 36
|
|
versionCode 72
|
|
versionName "2.10.2"
|
|
|
|
// Nothing about the server ships in the APK: its URL and ingest token are entered in
|
|
// the app's Server tab (ServerConfig), and the database is only reachable by the server.
|
|
|
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
}
|
|
|
|
// null quand aucun keystore n'est configuré : le build reste possible sur une
|
|
// machine sans secrets (APK non signé), au lieu d'échouer.
|
|
def platformSigning = signingConfigs.findByName("platform")
|
|
|
|
// Deux canaux de distribution :
|
|
// - stable : diffusé en release taguée, AUCUN auto-update. L'utilisateur installe
|
|
// lui-même ; rien dans l'app ne va chercher un APK.
|
|
// - unstable : pré-releases publiées à chaque push sur master, avec OTA pour que les testeurs
|
|
// soient à jour sans manipulation. Installable à côté du stable.
|
|
flavorDimensions += "channel"
|
|
productFlavors {
|
|
stable {
|
|
dimension "channel"
|
|
buildConfigField "boolean", "OTA_ENABLED", "false"
|
|
}
|
|
unstable {
|
|
dimension "channel"
|
|
applicationIdSuffix ".unstable"
|
|
// Three-part versions, the same as defaultConfig ("2.8.1-unstable"). Upstream added
|
|
// a fourth part for its CI build number; there is no CI here and the OTA updater is
|
|
// off. The version code keeps upstream's x100000 so it never drops below codes
|
|
// already installed on the car (2.8.0.0 was 6600000): a lower code is a downgrade,
|
|
// which the installer refuses.
|
|
versionCode defaultConfig.versionCode * 100000
|
|
versionName defaultConfig.versionName
|
|
versionNameSuffix "-unstable"
|
|
buildConfigField "boolean", "OTA_ENABLED", "true"
|
|
}
|
|
}
|
|
|
|
buildTypes {
|
|
debug {
|
|
if (platformSigning != null) signingConfig platformSigning
|
|
}
|
|
release {
|
|
// [T-918] R8 enabled. CarPropertyAdapter reaches the car purely by
|
|
// reflection, so proguard-rules.pro must keep those targets; a release build
|
|
// needs an on-vehicle check of the car reads before it ships.
|
|
minifyEnabled true
|
|
if (platformSigning != null) signingConfig platformSigning
|
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
|
}
|
|
}
|
|
// BuildConfig.DEBUG gates the debug-only logging (T-912).
|
|
buildFeatures {
|
|
buildConfig true
|
|
}
|
|
|
|
lint {
|
|
abortOnError true
|
|
checkReleaseBuilds true
|
|
warningsAsErrors false
|
|
}
|
|
|
|
compileOptions {
|
|
sourceCompatibility JavaVersion.VERSION_11
|
|
targetCompatibility JavaVersion.VERSION_11
|
|
}
|
|
}
|
|
|
|
// The version build-car puts in the APK's file name ("NilsMG4-unstable-2.8.1.apk"), which
|
|
// is also the name the OTA updater reads a release's version from.
|
|
tasks.register('printUnstableVersion') {
|
|
doLast {
|
|
println android.defaultConfig.versionName
|
|
}
|
|
}
|
|
|
|
// Nomme les APK par canal pour que les artefacts de release soient lisibles.
|
|
androidComponents {
|
|
onVariants(selector().all()) { variant ->
|
|
variant.outputs.each { output ->
|
|
if (variant.buildType == "release") {
|
|
// Le canal unstable garde un nom de fichier stable : l'updater identifie
|
|
// la version par le tag de la pré-release, jamais par le nom d'APK.
|
|
output.outputFileName.set(variant.flavorName == "unstable"
|
|
? "NilsMG4-unstable.apk"
|
|
: "NilsMG4-${variant.flavorName}-${output.versionName.get()}.apk")
|
|
} else {
|
|
// Debug builds: NilsMG4-stable-debug.apk, NilsMG4-unstable-debug.apk.
|
|
output.outputFileName.set("NilsMG4-${variant.flavorName}-${variant.buildType}.apk")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation project(':evhardware')
|
|
implementation libs.appcompat
|
|
implementation libs.material
|
|
implementation libs.activity
|
|
implementation libs.constraintlayout
|
|
implementation libs.viewpager2
|
|
implementation libs.security.crypto
|
|
implementation 'com.google.zxing:core:3.5.3'
|
|
// android.jar's org.json is a stub in unit tests; the real implementation lets the
|
|
// telemetry payload tests parse what the app actually builds.
|
|
testImplementation libs.junit
|
|
testImplementation libs.json
|
|
androidTestImplementation libs.ext.junit
|
|
androidTestImplementation libs.espresso.core
|
|
}
|