Rework build variants and add FOSS variant (#1775)

This commit is contained in:
AntsyLich 2025-02-26 00:17:36 +06:00 committed by GitHub
parent 1dd81ef1e1
commit fe22f5aa37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 125 additions and 111 deletions

View File

@ -41,10 +41,10 @@ jobs:
run: ./gradlew spotlessCheck
- name: Build app
run: ./gradlew assembleStandardRelease
run: ./gradlew assembleRelease
- name: Run unit tests
run: ./gradlew testReleaseUnitTest testStandardReleaseUnitTest
run: ./gradlew testReleaseUnitTest
- name: Upload APK
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
@ -56,4 +56,4 @@ jobs:
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: mapping-${{ github.sha }}
path: app/build/outputs/mapping/standardRelease
path: app/build/outputs/mapping/release

View File

@ -32,10 +32,10 @@ jobs:
run: ./gradlew spotlessCheck
- name: Build app
run: ./gradlew assembleStandardRelease
run: ./gradlew assembleRelease -Pwith-analytics -Pwith-updater
- name: Run unit tests
run: ./gradlew testReleaseUnitTest testStandardReleaseUnitTest
run: ./gradlew testReleaseUnitTest
- name: Upload APK
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
@ -47,7 +47,7 @@ jobs:
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: mapping-${{ github.sha }}
path: app/build/outputs/mapping/standardRelease
path: app/build/outputs/mapping/release
# Sign APK and create release for tags
@ -87,7 +87,7 @@ jobs:
mv app/build/outputs/apk/standard/release/app-standard-x86-release-unsigned-signed.apk mihon-x86-${{ env.VERSION_TAG }}.apk
sha=`sha256sum mihon-x86-${{ env.VERSION_TAG }}.apk | awk '{ print $1 }'`
echo "APK_X86_SHA=$sha" >> $GITHUB_ENV
mv app/build/outputs/apk/standard/release/app-standard-x86_64-release-unsigned-signed.apk mihon-x86_64-${{ env.VERSION_TAG }}.apk
sha=`sha256sum mihon-x86_64-${{ env.VERSION_TAG }}.apk | awk '{ print $1 }'`
echo "APK_X86_64_SHA=$sha" >> $GITHUB_ENV
@ -110,7 +110,7 @@ jobs:
| armeabi-v7a | ${{ env.APK_ARMEABI_V7A_SHA }}
| x86 | ${{ env.APK_X86_SHA }} |
| x86_64 | ${{ env.APK_X86_64_SHA }} |
## If you are unsure which version to choose then go with mihon-${{ env.VERSION_TAG }}.apk
files: |
mihon-${{ env.VERSION_TAG }}.apk

View File

@ -1,5 +1,3 @@
@file:Suppress("ChromeOsAbiSupport")
import mihon.buildlogic.getBuildTime
import mihon.buildlogic.getCommitCount
import mihon.buildlogic.getGitSha
@ -12,7 +10,10 @@ plugins {
alias(libs.plugins.aboutLibraries)
}
if (gradle.startParameter.taskRequests.toString().contains("Standard")) {
val includeAnalytics = project.hasProperty("with-analytics")
val includeUpdater = project.hasProperty("with-updater")
if (includeAnalytics) {
pluginManager.apply {
apply(libs.plugins.google.services.get().pluginId)
apply(libs.plugins.firebase.crashlytics.get().pluginId)
@ -21,8 +22,6 @@ if (gradle.startParameter.taskRequests.toString().contains("Standard")) {
shortcutHelper.setFilePath("./shortcuts.xml")
val supportedAbis = setOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
android {
namespace = "eu.kanade.tachiyomi"
@ -35,90 +34,100 @@ android {
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"")
buildConfigField("String", "BUILD_TIME", "\"${getBuildTime()}\"")
buildConfigField("boolean", "INCLUDE_UPDATER", "false")
buildConfigField("boolean", "INCLUDE_ANALYTICS", "$includeAnalytics")
buildConfigField("boolean", "INCLUDE_UPDATER", "$includeUpdater")
buildConfigField("boolean", "PREVIEW", "false")
ndk {
abiFilters += supportedAbis
}
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
val debug by getting {
applicationIdSuffix = ".dev"
versionNameSuffix = "-${getCommitCount()}"
isPseudoLocalesEnabled = true
}
val release by getting {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles("proguard-android-optimize.txt", "proguard-rules.pro")
}
create("foss") {
initWith(release)
applicationIdSuffix = ".t-foss"
matchingFallbacks.add(release.name)
}
create("preview") {
initWith(release)
applicationIdSuffix = ".debug"
versionNameSuffix = debug.versionNameSuffix
signingConfig = debug.signingConfig
matchingFallbacks.add(release.name)
buildConfigField("boolean", "PREVIEW", "true")
}
create("benchmark") {
initWith(release)
isDebuggable = false
isProfileable = true
versionNameSuffix = "-benchmark"
applicationIdSuffix = ".benchmark"
signingConfig = debug.signingConfig
matchingFallbacks.add(release.name)
}
}
sourceSets {
val analyticsDir = if (includeAnalytics) "analytics-firebase" else "analytics-firebase-noop"
getByName("main").kotlin.srcDirs("src/$analyticsDir/kotlin")
getByName("preview").res.srcDirs("src/debug/res")
getByName("benchmark").res.srcDirs("src/debug/res")
}
splits {
abi {
isEnable = true
reset()
include(*supportedAbis.toTypedArray())
isUniversalApk = true
}
}
buildTypes {
named("debug") {
versionNameSuffix = "-${getCommitCount()}"
applicationIdSuffix = ".debug"
isPseudoLocalesEnabled = true
}
named("release") {
isShrinkResources = true
isMinifyEnabled = true
proguardFiles("proguard-android-optimize.txt", "proguard-rules.pro")
}
create("preview") {
initWith(getByName("release"))
buildConfigField("boolean", "PREVIEW", "true")
signingConfig = signingConfigs.getByName("debug")
matchingFallbacks.add("release")
val debugType = getByName("debug")
versionNameSuffix = debugType.versionNameSuffix
applicationIdSuffix = debugType.applicationIdSuffix
}
create("benchmark") {
initWith(getByName("release"))
signingConfig = signingConfigs.getByName("debug")
matchingFallbacks.add("release")
isDebuggable = false
isProfileable = true
versionNameSuffix = "-benchmark"
applicationIdSuffix = ".benchmark"
}
}
sourceSets {
getByName("preview").res.srcDirs("src/debug/res")
getByName("benchmark").res.srcDirs("src/debug/res")
}
flavorDimensions.add("default")
productFlavors {
create("standard") {
buildConfigField("boolean", "INCLUDE_UPDATER", "true")
dimension = "default"
}
create("dev") {
dimension = "default"
reset()
include("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
}
}
packaging {
resources.excludes.addAll(
listOf(
jniLibs {
keepDebugSymbols += listOf(
"libandroidx.graphics.path",
"libarchive-jni",
"libconscrypt_jni",
"libimagedecoder",
"libquickjs",
"libsqlite3x",
)
.map { "**/$it.so" }
}
resources {
excludes += setOf(
"kotlin-tooling-metadata.json",
"META-INF/DEPENDENCIES",
"LICENSE.txt",
"META-INF/LICENSE",
"META-INF/**/*.properties",
"META-INF/**/LICENSE.txt",
"META-INF/*.properties",
"META-INF/**/*.properties",
"META-INF/README.md",
"META-INF/NOTICE",
"META-INF/*.version",
),
)
"META-INF/DEPENDENCIES",
"META-INF/LICENSE",
"META-INF/NOTICE",
"META-INF/README.md",
)
}
}
dependenciesInfo {
@ -263,9 +272,11 @@ dependencies {
implementation(libs.logcat)
// Crash reports/analytics
"standardImplementation"(platform(libs.firebase.bom))
"standardImplementation"(libs.firebase.analytics)
"standardImplementation"(libs.firebase.crashlytics)
if (includeAnalytics) {
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.analytics)
implementation(libs.firebase.crashlytics)
}
// Shizuku
implementation(libs.bundles.shizuku)

View File

@ -1,8 +1,7 @@
package eu.kanade.domain.ui.model
import dev.icerock.moko.resources.StringResource
import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
import eu.kanade.tachiyomi.util.system.isReleaseBuildType
import tachiyomi.i18n.MR
enum class AppTheme(val titleRes: StringResource?) {
@ -13,7 +12,7 @@ enum class AppTheme(val titleRes: StringResource?) {
MIDNIGHT_DUSK(MR.strings.theme_midnightdusk),
// TODO: re-enable for preview
NORD(MR.strings.theme_nord.takeIf { isDevFlavor || isPreviewBuildType }),
NORD(MR.strings.theme_nord.takeUnless { isReleaseBuildType }),
STRAWBERRY_DAIQUIRI(MR.strings.theme_strawberrydaiquiri),
TAKO(MR.strings.theme_tako),
TEALTURQUOISE(MR.strings.theme_tealturquoise),

View File

@ -20,8 +20,7 @@ import androidx.compose.ui.platform.LocalConfiguration
import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.tachiyomi.ui.library.LibrarySettingsScreenModel
import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
import eu.kanade.tachiyomi.util.system.isReleaseBuildType
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.core.common.preference.TriState
import tachiyomi.domain.category.model.Category
@ -118,10 +117,7 @@ private fun ColumnScope.FilterPage(
onClick = { screenModel.toggleFilter(LibraryPreferences::filterCompleted) },
)
// TODO: re-enable when custom intervals are ready for stable
if (
(isDevFlavor || isPreviewBuildType) &&
LibraryPreferences.MANGA_OUTSIDE_RELEASE_PERIOD in autoUpdateMangaRestrictions
) {
if ((!isReleaseBuildType) && LibraryPreferences.MANGA_OUTSIDE_RELEASE_PERIOD in autoUpdateMangaRestrictions) {
val filterIntervalCustom by screenModel.libraryPreferences.filterIntervalCustom().collectAsState()
TriStateItem(
label = stringResource(MR.strings.action_filter_interval_custom),

View File

@ -19,8 +19,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
import eu.kanade.tachiyomi.util.system.isReleaseBuildType
import kotlinx.collections.immutable.toImmutableList
import tachiyomi.domain.manga.interactor.FetchInterval
import tachiyomi.i18n.MR
@ -109,7 +108,7 @@ fun SetIntervalDialog(
}
Spacer(Modifier.height(MaterialTheme.padding.small))
if (onValueChanged != null && (isDevFlavor || isPreviewBuildType)) {
if (onValueChanged != null && (!isReleaseBuildType)) {
Text(stringResource(MR.strings.manga_interval_custom_amount))
BoxWithConstraints(

View File

@ -37,6 +37,7 @@ import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.compose.LocalLifecycleOwner
import eu.kanade.presentation.util.rememberRequestPackageInstallsPermissionState
import eu.kanade.tachiyomi.core.security.PrivacyPreferences
import eu.kanade.tachiyomi.util.system.analyticsIncluded
import eu.kanade.tachiyomi.util.system.launchRequestPackageInstallsPermission
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
@ -122,6 +123,8 @@ internal class PermissionStep : OnboardingStep {
color = MaterialTheme.colorScheme.onPrimaryContainer,
)
if (!analyticsIncluded) return@Column
val crashlyticsPref = privacyPreferences.crashlytics()
val crashlytics by crashlyticsPref.collectAsState()
PermissionSwitch(

View File

@ -48,8 +48,7 @@ import eu.kanade.tachiyomi.network.PREF_DOH_SHECAN
import eu.kanade.tachiyomi.ui.more.OnboardingScreen
import eu.kanade.tachiyomi.util.CrashLogUtil
import eu.kanade.tachiyomi.util.system.GLUtil
import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
import eu.kanade.tachiyomi.util.system.isReleaseBuildType
import eu.kanade.tachiyomi.util.system.isShizukuInstalled
import eu.kanade.tachiyomi.util.system.powerManager
import eu.kanade.tachiyomi.util.system.setDefaultSettings
@ -413,10 +412,10 @@ object SettingsAdvancedScreen : SearchableSettings {
entries = extensionInstallerPref.entries
.filter {
// TODO: allow private option in stable versions once URL handling is more fleshed out
if (isPreviewBuildType || isDevFlavor) {
true
} else {
if (isReleaseBuildType) {
it != BasePreferences.ExtensionInstaller.PRIVATE
} else {
true
}
}
.associateWith { stringResource(it.titleRes) }

View File

@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.core.security.PrivacyPreferences
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.authenticate
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.isAuthenticationSupported
import eu.kanade.tachiyomi.util.system.analyticsIncluded
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableMap
import tachiyomi.core.common.i18n.stringResource
@ -31,10 +32,11 @@ object SettingsSecurityScreen : SearchableSettings {
override fun getPreferences(): List<Preference> {
val securityPreferences = remember { Injekt.get<SecurityPreferences>() }
val privacyPreferences = remember { Injekt.get<PrivacyPreferences>() }
return listOf(
getSecurityGroup(securityPreferences),
getFirebaseGroup(privacyPreferences),
)
return buildList(2) {
add(getSecurityGroup(securityPreferences))
if (!analyticsIncluded) return@buildList
add(getFirebaseGroup(privacyPreferences))
}
}
@Composable

View File

@ -9,7 +9,7 @@ import eu.kanade.tachiyomi.core.security.PrivacyPreferences
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.network.NetworkPreferences
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.util.system.isDebugBuildType
import tachiyomi.core.common.preference.AndroidPreferenceStore
import tachiyomi.core.common.preference.PreferenceStore
import tachiyomi.core.common.storage.AndroidStorageFolderProvider
@ -31,7 +31,7 @@ class PreferenceModule(val app: Application) : InjektModule {
addSingletonFactory {
NetworkPreferences(
preferenceStore = get(),
verboseLogging = isDevFlavor,
verboseLogging = isDebugBuildType,
)
}
addSingletonFactory {

View File

@ -40,7 +40,7 @@ class CrashLogUtil(
fun getDebugInfo(): String {
return """
App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR}, ${BuildConfig.COMMIT_SHA}, ${BuildConfig.VERSION_CODE}, ${BuildConfig.BUILD_TIME})
App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.COMMIT_SHA}, ${BuildConfig.VERSION_CODE}, ${BuildConfig.BUILD_TIME})
Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT}; build ${Build.DISPLAY})
Device brand: ${Build.BRAND}
Device manufacturer: ${Build.MANUFACTURER}

View File

@ -1,12 +1,17 @@
@file:Suppress("UNUSED", "KotlinConstantConditions")
package eu.kanade.tachiyomi.util.system
import eu.kanade.tachiyomi.BuildConfig
val isDevFlavor: Boolean
get() = BuildConfig.FLAVOR == "dev"
val analyticsIncluded: Boolean
inline get() = BuildConfig.INCLUDE_ANALYTICS
val isDebugBuildType: Boolean
inline get() = BuildConfig.BUILD_TYPE == "debug"
val isPreviewBuildType: Boolean
get() = BuildConfig.BUILD_TYPE == "preview"
inline get() = BuildConfig.BUILD_TYPE == "preview"
val isReleaseBuildType: Boolean
get() = BuildConfig.BUILD_TYPE == "release"
inline get() = BuildConfig.BUILD_TYPE == "release"

View File

@ -171,7 +171,7 @@ fun Context.isInstalledFromFDroid(): Boolean {
return installerPackageName == "org.fdroid.fdroid" ||
// F-Droid builds typically disable the updater
(!BuildConfig.INCLUDE_UPDATER && !isDevFlavor)
(!BuildConfig.INCLUDE_UPDATER && !isDebugBuildType)
}
fun Context.launchRequestPackageInstallsPermission() {