Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add billing and infrastructure flavor dimensions #4684

Merged
merged 7 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/android-app.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Android - Build and test
on:

Check warning on line 3 in .github/workflows/android-app.yml

View workflow job for this annotation

GitHub Actions / check-formatting

3:1 [truthy] truthy value should be one of [false, true]
pull_request:
paths:
- '**'
Expand Down Expand Up @@ -193,7 +193,7 @@
uses: burrunan/gradle-cache-action@v1
with:
job-id: jdk17
arguments: assembleDebug
arguments: assembleOssProdDebug
gradle-version: wrapper
build-root-directory: android

Expand Down Expand Up @@ -222,7 +222,7 @@
uses: burrunan/gradle-cache-action@v1
with:
job-id: jdk17
arguments: assembleAndroidTest
arguments: assembleOssProdAndroidTest
gradle-version: wrapper
build-root-directory: android
execution-only-caches: true
Expand Down
168 changes: 114 additions & 54 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
import com.android.build.gradle.internal.tasks.factory.dependsOn
import java.io.FileInputStream
import java.util.Properties
import java.util.*
import org.gradle.configurationcache.extensions.capitalized

plugins {
id(Dependencies.Plugin.androidApplicationId)
Expand Down Expand Up @@ -47,64 +48,70 @@ android {

if (keystorePropertiesFile.exists()) {
signingConfigs {
create("release") {
create(SigningConfigs.RELEASE) {
storeFile = file("$credentialsPath/app-keys.jks")
storePassword = keystoreProperties.getProperty("storePassword")
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
}
}

buildTypes {
getByName("release") {
signingConfig = signingConfigs.getByName("release")
}
}
}

buildTypes {
getByName("release") {
getByName(BuildTypes.RELEASE) {
signingConfig = signingConfigs.findByName(SigningConfigs.RELEASE)
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}

create("fdroid") {
initWith(buildTypes.getByName("release"))
isMinifyEnabled = true
isShrinkResources = true
create(BuildTypes.FDROID) {
initWith(buildTypes.getByName(BuildTypes.RELEASE))
signingConfig = null
matchingFallbacks += "release"
matchingFallbacks += BuildTypes.RELEASE
}
create(BuildTypes.LEAK_CANARY) {
initWith(buildTypes.getByName(BuildTypes.DEBUG))
applicationIdSuffix = ".leakcanary"
matchingFallbacks += BuildTypes.DEBUG
}
}

create("leakCanary") {
initWith(buildTypes.getByName("debug"))
matchingFallbacks += "debug"
flavorDimensions += FlavorDimensions.BILLING
flavorDimensions += FlavorDimensions.INFRASTRUCTURE

productFlavors {
create(Flavors.OSS) {
dimension = FlavorDimensions.BILLING
isDefault = true
}
create(Flavors.PLAY) { dimension = FlavorDimensions.BILLING }
create(Flavors.PROD) {
dimension = FlavorDimensions.INFRASTRUCTURE
isDefault = true
}
create(Flavors.DEVMOLE) {
dimension = FlavorDimensions.INFRASTRUCTURE
applicationId = "net.mullvad.mullvadvpn.devmole"
}
}

sourceSets {
getByName("main") {
val changelogDir = gradleLocalProperties(rootProject.projectDir).getOrDefault(
"OVERRIDE_CHANGELOG_DIR",
defaultChangeLogAssetsDirectory
)
val changelogDir =
gradleLocalProperties(rootProject.projectDir)
.getOrDefault("OVERRIDE_CHANGELOG_DIR", defaultChangeLogAssetsDirectory)

assets.srcDirs(extraAssetsDirectory, changelogDir)
jniLibs.srcDirs(extraJniDirectory)
}
}

buildFeatures {
compose = true
}
buildFeatures { compose = true }

composeOptions {
kotlinCompilerExtensionVersion = Versions.kotlinCompilerExtensionVersion
}
composeOptions { kotlinCompilerExtensionVersion = Versions.kotlinCompilerExtensionVersion }

compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
Expand All @@ -114,12 +121,13 @@ android {
kotlinOptions {
allWarningsAsErrors = false
jvmTarget = Versions.jvmTarget
freeCompilerArgs = listOf(
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlinx.coroutines.ObsoleteCoroutinesApi",
// Opt-in option for Koin annotation of KoinComponent.
"-opt-in=kotlin.RequiresOptIn"
)
freeCompilerArgs =
listOf(
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlinx.coroutines.ObsoleteCoroutinesApi",
// Opt-in option for Koin annotation of KoinComponent.
"-opt-in=kotlin.RequiresOptIn"
)
}

tasks.withType<com.android.build.gradle.tasks.MergeSourceSetFolders> {
Expand All @@ -143,29 +151,29 @@ android {
packaging {
jniLibs.useLegacyPackaging = true
resources {
pickFirsts += setOf(
// Fixes packaging error caused by: androidx.compose.ui:ui-test-junit4
"META-INF/AL2.0",
"META-INF/LGPL2.1",
// Fixes packaging error caused by: jetified-junit-*
"META-INF/LICENSE.md",
"META-INF/LICENSE-notice.md"
)
pickFirsts +=
setOf(
// Fixes packaging error caused by: androidx.compose.ui:ui-test-junit4
"META-INF/AL2.0",
"META-INF/LGPL2.1",
// Fixes packaging error caused by: jetified-junit-*
"META-INF/LICENSE.md",
"META-INF/LICENSE-notice.md"
)
}
}

applicationVariants.configureEach {
val alwaysShowChangelog = gradleLocalProperties(rootProject.projectDir)
.getProperty("ALWAYS_SHOW_CHANGELOG") ?: "false"
val alwaysShowChangelog =
gradleLocalProperties(rootProject.projectDir).getProperty("ALWAYS_SHOW_CHANGELOG")
?: "false"

buildConfigField(
"boolean",
"ALWAYS_SHOW_CHANGELOG",
alwaysShowChangelog
)
buildConfigField("boolean", "ALWAYS_SHOW_CHANGELOG", alwaysShowChangelog)

val enableInAppVersionNotifications = gradleLocalProperties(rootProject.projectDir)
.getProperty("ENABLE_IN_APP_VERSION_NOTIFICATIONS") ?: "true"
val enableInAppVersionNotifications =
gradleLocalProperties(rootProject.projectDir)
.getProperty("ENABLE_IN_APP_VERSION_NOTIFICATIONS")
?: "true"

buildConfigField(
"boolean",
Expand All @@ -174,9 +182,63 @@ android {
)
}

applicationVariants.all {
val artifactSuffix = buildString {
productFlavors.getOrNull(0)?.name?.let { billingFlavorName ->
if (billingFlavorName != Flavors.OSS) {
append(".$billingFlavorName")
}
}

productFlavors.getOrNull(1)?.name?.let { infrastructureFlavorName ->
if (infrastructureFlavorName != Flavors.PROD) {
append(".$infrastructureFlavorName")
}
}

if (buildType.name != BuildTypes.RELEASE) {
append(".${buildType.name}")
}
}

val variantName = name
val capitalizedVariantName = variantName.capitalized()
val artifactName = "MullvadVPN-${versionName}${artifactSuffix}"

tasks.register<Copy>("create${capitalizedVariantName}DistApk") {
from(packageApplicationProvider)
into("${rootDir.parent}/dist")
include { it.name.endsWith(".apk") }
rename { "$artifactName.apk" }
}

val createDistBundle =
tasks.register<Copy>("create${capitalizedVariantName}DistBundle") {
from("$buildDir/outputs/bundle/$variantName")
into("${rootDir.parent}/dist")
include { it.name.endsWith(".aab") }
rename { "$artifactName.aab" }
}

createDistBundle.dependsOn("bundle$capitalizedVariantName")
}

project.tasks.preBuild.dependsOn("ensureJniDirectoryExist")
}

androidComponents {
beforeVariants { variantBuilder ->
variantBuilder.enable =
variantBuilder.let { currentVariant ->
val enabledVariants =
enabledVariantTriples.map { (billing, infra, buildType) ->
billing + infra.capitalized() + buildType.capitalized()
}
enabledVariants.contains(currentVariant.name)
}
}
}

configure<org.owasp.dependencycheck.gradle.extension.DependencyCheckExtension> {
// Skip the lintClassPath configuration, which relies on many dependencies that has been flagged
// to have CVEs, as it's related to the lint tooling rather than the project's compilation class
Expand Down Expand Up @@ -212,9 +274,7 @@ afterEvaluate {
}
}

play {
serviceAccountCredentials.set(file("play-api-key.json"))
}
play { serviceAccountCredentials.set(file("play-api-key.json")) }

configurations.all {
resolutionStrategy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,12 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
import net.mullvad.mullvadvpn.BuildConfig
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.compose.extensions.getExpiryQuantityString
import net.mullvad.mullvadvpn.compose.state.ConnectNotificationState
import net.mullvad.mullvadvpn.compose.test.NOTIFICATION_BANNER
import net.mullvad.mullvadvpn.compose.util.rememberPrevious
import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes
import net.mullvad.mullvadvpn.constant.IS_PLAY_BUILD
import net.mullvad.mullvadvpn.lib.common.util.getErrorNotificationResources
import net.mullvad.mullvadvpn.lib.theme.AppTheme
import net.mullvad.mullvadvpn.lib.theme.Dimens
Expand Down Expand Up @@ -122,21 +121,21 @@ private fun ShowNotification(
versionInfoNotification(
versionInfo = connectNotificationState.versionInfo,
onClickUpdateVersion =
if (BuildConfig.BUILD_TYPE != BuildTypes.RELEASE) {
onClickUpdateVersion
} else {
if (IS_PLAY_BUILD) {
null
} else {
onClickUpdateVersion
}
)
}
is ConnectNotificationState.ShowAccountExpiryNotification -> {
accountExpiryNotification(
expiry = connectNotificationState.expiry,
onClickShowAccount =
if (BuildConfig.BUILD_TYPE != BuildTypes.RELEASE) {
onClickShowAccount
} else {
if (IS_PLAY_BUILD) {
null
} else {
onClickShowAccount
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import me.onebone.toolbar.ScrollStrategy
import me.onebone.toolbar.rememberCollapsingToolbarScaffoldState
import net.mullvad.mullvadvpn.BuildConfig
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.compose.button.ActionButton
import net.mullvad.mullvadvpn.compose.component.CollapsingToolbarScaffold
Expand All @@ -36,7 +35,7 @@ import net.mullvad.mullvadvpn.compose.component.InformationView
import net.mullvad.mullvadvpn.compose.component.MissingPolicy
import net.mullvad.mullvadvpn.compose.component.drawVerticalScrollbar
import net.mullvad.mullvadvpn.compose.state.AccountUiState
import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes
import net.mullvad.mullvadvpn.constant.IS_PLAY_BUILD
import net.mullvad.mullvadvpn.lib.common.util.capitalizeFirstCharOfEachWord
import net.mullvad.mullvadvpn.lib.common.util.openAccountPageInBrowser
import net.mullvad.mullvadvpn.lib.theme.Dimens
Expand Down Expand Up @@ -158,7 +157,7 @@ fun AccountScreen(

Spacer(modifier = Modifier.weight(1f))

if (BuildConfig.BUILD_TYPE != BuildTypes.RELEASE) {
if (IS_PLAY_BUILD.not()) {
ActionButton(
text = stringResource(id = R.string.manage_account),
onClick = onManageAccountClick,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ import net.mullvad.mullvadvpn.compose.extensions.itemWithDivider
import net.mullvad.mullvadvpn.compose.state.SettingsUiState
import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_TEST_TAG
import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes
import net.mullvad.mullvadvpn.lib.common.util.appendHideNavOnReleaseBuild
import net.mullvad.mullvadvpn.lib.common.util.openLink
import net.mullvad.mullvadvpn.lib.theme.Dimens
import net.mullvad.mullvadvpn.util.appendHideNavOnPlayBuild

@OptIn(ExperimentalMaterial3Api::class)
@Preview
Expand Down Expand Up @@ -132,7 +132,7 @@ fun SettingsScreen(
Uri.parse(
context.resources
.getString(R.string.download_url)
.appendHideNavOnReleaseBuild()
.appendHideNavOnPlayBuild()
)
)
},
Expand Down Expand Up @@ -208,7 +208,7 @@ fun SettingsScreen(
Uri.parse(
context.resources
.getString(R.string.privacy_policy_url)
.appendHideNavOnReleaseBuild()
.appendHideNavOnPlayBuild()
)
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package net.mullvad.mullvadvpn.constant

import net.mullvad.mullvadvpn.BuildConfig

const val IS_PLAY_BUILD = BuildConfig.FLAVOR_billing == "play"
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.ui.platform.ComposeView
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.compose.screen.ConnectScreen
import net.mullvad.mullvadvpn.lib.common.util.appendHideNavOnReleaseBuild
import net.mullvad.mullvadvpn.lib.theme.AppTheme
import net.mullvad.mullvadvpn.ui.MainActivity
import net.mullvad.mullvadvpn.ui.NavigationBarPainter
import net.mullvad.mullvadvpn.util.appendHideNavOnPlayBuild
import net.mullvad.mullvadvpn.viewmodel.ConnectViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel

Expand Down Expand Up @@ -58,9 +58,7 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter {
Intent(
Intent.ACTION_VIEW,
Uri.parse(
requireContext()
.getString(R.string.download_url)
.appendHideNavOnReleaseBuild()
requireContext().getString(R.string.download_url).appendHideNavOnPlayBuild()
)
)
.apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK }
Expand Down
Loading
Loading