Files
QSfera/Android/qsferaApp/build.gradle
T
Курнат Андрей 0acda06d5e Bump Android release to 1.3.10
2026-06-10 06:56:07 +03:00

329 lines
11 KiB
Groovy

apply plugin: 'com.android.application'
apply plugin: 'com.google.devtools.ksp'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
def commitSHA1 = 'COMMIT_SHA1'
def gitRemote = 'GIT_REMOTE'
def envValue(String primary, String legacy = null) {
def value = System.getenv(primary)
if (value) {
return value
}
return legacy ? System.getenv(legacy) : null
}
def releaseSigningEnv = [
[primary: 'QSFERA_RELEASE_KEYSTORE', legacy: 'OC_RELEASE_KEYSTORE'],
[primary: 'QSFERA_RELEASE_KEYSTORE_PASSWORD', legacy: 'OC_RELEASE_KEYSTORE_PASSWORD'],
[primary: 'QSFERA_RELEASE_KEY_ALIAS', legacy: 'OC_RELEASE_KEY_ALIAS'],
[primary: 'QSFERA_RELEASE_KEY_PASSWORD', legacy: 'OC_RELEASE_KEY_PASSWORD'],
]
def missingReleaseSigningEnvKeys = {
releaseSigningEnv.findAll { !envValue(it.primary, it.legacy) }
.collect { "${it.primary} (${it.legacy} legacy fallback)" }
}
dependencies {
// Data and domain modules
implementation project(':qsferaDomain')
implementation project(':qsferaData')
// Kotlin
implementation libs.kotlin.stdlib
implementation libs.kotlinx.coroutines.core
// Android X
implementation libs.androidx.activity
implementation libs.androidx.annotation
implementation libs.androidx.appcompat
implementation libs.androidx.biometric
implementation libs.androidx.constraintlayout
implementation libs.androidx.core.ktx
implementation libs.androidx.fragment.ktx
implementation libs.androidx.legacy.support
implementation libs.androidx.lifecycle.common.java8
implementation libs.androidx.lifecycle.extensions
implementation libs.androidx.lifecycle.livedata.ktx
implementation libs.androidx.lifecycle.runtime.ktx
implementation libs.androidx.lifecycle.viewmodel.ktx
implementation libs.androidx.preference.ktx
implementation libs.androidx.room.runtime
implementation libs.androidx.sqlite.ktx
implementation libs.androidx.work.runtime.ktx
implementation(libs.androidx.browser) { because "CustomTabs required for OAuth2 and OIDC" }
implementation(libs.androidx.enterprise.feedback) { because "MDM feedback" }
// Image loading
implementation libs.coil
implementation libs.glide
implementation libs.glide.vector
// Zooming Android ImageView.
implementation libs.photoview
// Koin dependency injector
implementation libs.koin.androidx.workmanager
implementation libs.koin.core
// Miscellaneous
implementation libs.disklrucache
implementation libs.media3.exoplayer
implementation libs.media3.ui
implementation libs.floatingactionbutton
implementation libs.material
implementation libs.patternlockview
// Markdown Preview
implementation libs.bundles.markwon
// Timber
implementation libs.timber
// Tests
testImplementation project(":qsferaTestUtil")
testImplementation libs.androidx.arch.core.testing
testImplementation libs.junit4
testImplementation libs.kotlinx.coroutines.test
testImplementation libs.mockk
// Instrumented tests
androidTestImplementation project(":qsferaTestUtil")
androidTestImplementation libs.androidx.annotation
androidTestImplementation libs.androidx.arch.core.testing
androidTestImplementation libs.androidx.test.core
androidTestImplementation libs.androidx.test.ext.junit
androidTestImplementation libs.androidx.test.rules
androidTestImplementation libs.androidx.test.runner
androidTestImplementation libs.androidx.test.uiautomator
androidTestImplementation libs.bundles.espresso
androidTestImplementation libs.dexopener
androidTestImplementation(libs.mockk.android) { exclude module: "objenesis" }
// Kaspresso
androidTestImplementation libs.kaspresso
// Debug
debugImplementation libs.androidx.fragment.testing
debugImplementation libs.androidx.test.monitor
debugImplementation libs.stetho
// Detekt
detektPlugins libs.detekt.formatting
detektPlugins libs.detekt.libraries
}
configurations.all {
resolutionStrategy {
force "androidx.test:core:1.6.1"
force "androidx.test:core-ktx:1.6.1"
force "androidx.test:monitor:1.7.2"
force "androidx.test:runner:1.6.2"
force "androidx.test:rules:1.6.1"
force "androidx.test.espresso:espresso-core:3.6.1"
}
}
android {
compileSdkVersion sdkCompileVersion
defaultConfig {
minSdkVersion sdkMinVersion
targetSdkVersion sdkTargetVersion
testInstrumentationRunner "eu.qsfera.android.utils.OCTestAndroidJUnitRunner"
versionCode = 38
versionName = "1.3.10"
buildConfigField "String", gitRemote, "\"" + getGitOriginRemote() + "\""
buildConfigField "String", commitSHA1, "\"" + getLatestGitHash() + "\""
// 2. If the caller (GitHub) provided a specific number, overwrite the versionCode.
if (project.hasProperty('versionCode')) {
versionCode project.property('versionCode').toInteger()
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}
sourceSets {
androidTest.java.srcDirs += "src/test-common/java"
test.java.srcDirs += "src/test-common/java"
androidTest {
java.srcDirs += ['src/integrationTest/java']
}
}
lint {
abortOnError false
htmlOutput file('../lint-app-report.html')
ignoreWarnings false
xmlReport false
}
signingConfigs {
release {
def releaseKeystore = envValue('QSFERA_RELEASE_KEYSTORE', 'OC_RELEASE_KEYSTORE')
if (releaseKeystore) {
storeFile file(releaseKeystore) // use an absolute path
storePassword envValue('QSFERA_RELEASE_KEYSTORE_PASSWORD', 'OC_RELEASE_KEYSTORE_PASSWORD')
keyAlias envValue('QSFERA_RELEASE_KEY_ALIAS', 'OC_RELEASE_KEY_ALIAS')
keyPassword envValue('QSFERA_RELEASE_KEY_PASSWORD', 'OC_RELEASE_KEY_PASSWORD')
}
}
}
buildTypes {
release {
if (envValue('QSFERA_RELEASE_KEYSTORE', 'OC_RELEASE_KEYSTORE')) {
signingConfig signingConfigs.release
}
}
debug {
applicationIdSuffix ".debug"
}
}
flavorDimensions "management"
productFlavors {
original {
dimension "management"
}
//mdm {
// dimension "management"
//}
qa {
dimension "management"
applicationIdSuffix ".qa"
// replace stuff from setup.xml
resValue "string", "app_name", "КуСфера QA"
resValue "string", "account_type", "eu.qsfera.qa"
resValue "string", "authority", "eu.qsfera.qa"
resValue "string", "document_provider_authority", "eu.qsfera.qa.documents"
resValue "string", "file_provider_authority", "eu.qsfera.qa.files"
resValue "string", "search_suggest_authority", "eu.qsfera.qa.search.users_and_groups"
resValue "string", "search_suggest_intent_action", "eu.qsfera.qa.search.users_and_groups.action.SHARE_WITH"
}
}
applicationVariants.all { variant ->
def appName = envValue('QSFERA_APP_NAME', 'OC_APP_NAME')
setOutputFileName(variant, appName, project)
}
testOptions {
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
unitTests.returnDefaultValues = true
animationsDisabled = true
}
buildFeatures {
viewBinding true
buildConfig true
}
packagingOptions {
resources.excludes.add("META-INF/*")
}
namespace "eu.qsfera.android"
testNamespace "eu.qsfera.android.test"
}
gradle.taskGraph.whenReady { taskGraph ->
def releaseBuildRequested = taskGraph.allTasks.any { task ->
def taskName = task.name.toLowerCase()
taskName.endsWith("release") &&
(taskName.startsWith("assemble") || taskName.startsWith("bundle") || taskName.startsWith("package"))
}
def missingSigningEnvKeys = missingReleaseSigningEnvKeys()
if (releaseBuildRequested && !missingSigningEnvKeys.isEmpty()) {
throw new GradleException(
"Release builds must be signed. Missing env vars: ${missingSigningEnvKeys.join(', ')}"
)
}
}
// Updates output file names of a given variant to format
// [appName].[variant.versionName].[QSFERA_BUILD_NUMBER]-[variant.name].apk.
//
// QSFERA_BUILD_NUMBER is an environment variable read directly in this method. If undefined, it's not added.
// OC_BUILD_NUMBER is still accepted as a legacy fallback.
//
// @param variant Build variant instance which output file name will be updated.
// @param appName String to use as first part of the new file name. May be undefined, the original
// project.archivesBaseName property will be used instead.
// @param callerProject Caller project.
def setOutputFileName(variant, appName, callerProject) {
logger.info("Setting new name for output of variant $variant.name")
def originalFile = variant.outputs[0].outputFile
def originalName = originalFile.name
println "originalName is $originalName"
def newName = ""
if (appName) {
newName += appName
} else {
newName += "QSfera"
}
def versionName = "$variant.mergedFlavor.versionName"
if (variant.mergedFlavor.manifestPlaceholders.versionName != null) {
versionName = "$variant.mergedFlavor.manifestPlaceholders.versionName"
}
if (variant.buildType.manifestPlaceholders.versionName != null) {
versionName = "$variant.buildType.manifestPlaceholders.versionName"
}
newName += "_$versionName"
def buildNumber = envValue('QSFERA_BUILD_NUMBER', 'OC_BUILD_NUMBER')
if (buildNumber) {
newName += "_$buildNumber"
}
newName += originalName.substring(callerProject.archivesBaseName.length())
println "$variant.name: newName is $newName"
variant.outputs.all {
outputFileName = newName
}
}
static def getLatestGitHash() {
def process = "git rev-parse --short HEAD".execute()
return process.text.toString().trim()
}
static def getGitOriginRemote() {
def process = "git remote -v".execute()
def values = process.text.toString().trim().split("\\r\\n|\\n|\\r")
def found = values.find { it.startsWith("origin") && it.endsWith("(push)") }
return found.replace("origin", "").replace("(push)", "").replace(".git", "").trim()
}
tasks.withType(io.gitlab.arturbosch.detekt.Detekt).configureEach {
jvmTarget = "17"
}