1
0
Fork 0

Moves release flavour to build type (#1693)

master
Mitchell Hentges 2019-04-22 20:02:39 +02:00 committed by Jeff Boek
parent d5ca417b16
commit 92b6d4a925
10 changed files with 63 additions and 155 deletions

View File

@ -30,36 +30,48 @@ android {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true' testInstrumentationRunnerArguments clearPackageData: 'true'
manifestPlaceholders.isRaptorEnabled = "false" manifestPlaceholders.isRaptorEnabled = "false"
buildConfigField "boolean", "IS_RELEASED", "false"
}
def releaseTemplate = {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
matchingFallbacks = ['release'] // Use on the "release" build type in dependencies (AARs)
} }
buildTypes { buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
releaseRaptor {
initWith release
manifestPlaceholders.isRaptorEnabled = "true"
matchingFallbacks = ['release']
}
debug { debug {
shrinkResources false shrinkResources false
minifyEnabled false minifyEnabled false
applicationIdSuffix ".debug" applicationIdSuffix ".debug"
manifestPlaceholders.isRaptorEnabled = "true" manifestPlaceholders.isRaptorEnabled = "true"
} }
// "releaseRaptor" is only used for performance testing, and isn't a real "release" type
releaseRaptor releaseTemplate >> { // the ">>" concatenates the releaseRaptor-specific options with the template
manifestPlaceholders.isRaptorEnabled = "true"
}
nightly releaseTemplate >> {
buildConfigField "boolean", "IS_RELEASED", "true"
}
beta releaseTemplate >> {
buildConfigField "boolean", "IS_RELEASED", "true"
}
}
variantFilter { // There's a "release" build type that exists by default that we don't use (it's replaced by "nightly" and "beta")
if (buildType.name == 'release') {
setIgnore true
}
} }
testOptions { testOptions {
execution 'ANDROIDX_TEST_ORCHESTRATOR' execution 'ANDROIDX_TEST_ORCHESTRATOR'
} }
flavorDimensions "abi", "channel" flavorDimensions "abi"
productFlavors { productFlavors {
// Processor architectures (abi dimension)
arm { arm {
dimension "abi" dimension "abi"
ndk { ndk {
@ -78,41 +90,6 @@ android {
abiFilter "arm64-v8a" abiFilter "arm64-v8a"
} }
} }
// Product channels (channel dimension)
// "Greenfield" is our clean version of Fenix without any of the "Fennec transition" code.
greenfield {
dimension "channel"
}
firefoxNightly {
dimension "channel"
// Aurora was a channel between nightly builds and beta versions. Aurora builds were published on Google
// Play. When the Aurora channel was shutdown in April 2017 the decision was made to instead ship Nightly
// builds to Google Play using the existing application id. Previously Nightly builds were not available
// on Google Play. Since then our Nightly package name is "fennec_aurora" instead of "fennec_nightly".
applicationId "org.mozilla.fennec_aurora"
}
firefoxBeta {
dimension "channel"
applicationId "org.mozilla.firefox_beta"
}
firefoxRelease {
dimension "channel"
applicationId "org.mozilla.firefox"
}
}
variantFilter { variant ->
def flavors = variant.flavors*.name.toString().toLowerCase()
if (!flavors.contains("greenfield")) {
// For now everything that isn't a "greenfield" build isn't used. So let's ignore those variants.
setIgnore(true)
}
} }
compileOptions { compileOptions {
@ -148,11 +125,12 @@ android.applicationVariants.all { variant ->
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
def buildType = variant.buildType.name def buildType = variant.buildType.name
def versionCode = null
buildConfigField 'Boolean', 'COLLECTIONS_ENABLED', (buildType != "release").toString() buildConfigField 'Boolean', 'COLLECTIONS_ENABLED', (buildType != "release").toString()
if (buildType == "release") { if (buildType == "nightly") {
def versionCode = generatedVersionCode versionCode = generatedVersionCode
// The Google Play Store does not allow multiple APKs for the same app that all have the // The Google Play Store does not allow multiple APKs for the same app that all have the
// same version code. Therefore we need to have different version codes for our ARM and x86 // same version code. Therefore we need to have different version codes for our ARM and x86
@ -168,15 +146,16 @@ android.applicationVariants.all { variant ->
versionCode = versionCode + 1 versionCode = versionCode + 1
}// else variant.flavorName.contains("Arm")) use generated version code }// else variant.flavorName.contains("Arm")) use generated version code
variant.outputs.all { output -> variant.outputs.all {
setVersionCodeOverride(versionCode) setVersionCodeOverride(versionCode)
} }
} }
println("----------------------------------------------") println("----------------------------------------------")
println("Build type: " + buildType) println("Variant name: " + variant.name)
println("Build type: " + variant.buildType.name)
println("Flavor: " + variant.flavorName) println("Flavor: " + variant.flavorName)
println("Version code: " + variant.mergedFlavor.versionCode) println("Version code: " + (versionCode ?: variant.mergedFlavor.versionCode))
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
// BuildConfig: Set variables for Sentry, Crash Reporting, and Telemetry // BuildConfig: Set variables for Sentry, Crash Reporting, and Telemetry
@ -215,7 +194,7 @@ android.applicationVariants.all { variant ->
print("Adjust token: ") print("Adjust token: ")
if (variantName.contains("Release")) { if (variant.buildType.buildConfigFields['IS_RELEASED']?.value) {
try { try {
def token = new File("${rootDir}/.adjust_token").text.trim() def token = new File("${rootDir}/.adjust_token").text.trim()
buildConfigField 'String', 'ADJUST_TOKEN', '"' + token + '"' buildConfigField 'String', 'ADJUST_TOKEN', '"' + token + '"'

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
sharedUserId: This flavor is meant to replace Firefox (Beta channel) and therefore needs to inherit
its sharedUserId for all eternity. Shipping an app update without sharedUserId can have
fatal consequences. For example see:
- https://issuetracker.google.com/issues/36924841
- https://issuetracker.google.com/issues/36905922
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="org.mozilla.firefox.sharedID">
</manifest>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
sharedUserId: This flavor is meant to replace Firefox (Nightly channel) and therefore needs to inherit
its sharedUserId for all eternity. Shipping an app update without sharedUserId can have
fatal consequences. For example see:
- https://issuetracker.google.com/issues/36924841
- https://issuetracker.google.com/issues/36905922
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="org.mozilla.fennec.sharedID">
</manifest>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
sharedUserId: This flavor is meant to replace Firefox (Release channel) and therefore needs to inherit
its sharedUserId for all eternity. Shipping an app update without sharedUserId can have
fatal consequences. For example see:
- https://issuetracker.google.com/issues/36924841
- https://issuetracker.google.com/issues/36905922
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="org.mozilla.firefox.sharedID">
</manifest>

View File

@ -18,7 +18,7 @@ class AdjustMetricsService(private val application: Application) : MetricsServic
if ((BuildConfig.ADJUST_TOKEN.isNullOrEmpty())) { if ((BuildConfig.ADJUST_TOKEN.isNullOrEmpty())) {
Log.i(LOGTAG, "No adjust token defined") Log.i(LOGTAG, "No adjust token defined")
if (!BuildConfig.DEBUG) { if (BuildConfig.IS_RELEASED) {
throw IllegalStateException("No adjust token defined for release build") throw IllegalStateException("No adjust token defined for release build")
} }

View File

@ -193,8 +193,8 @@ class SettingsFragment : PreferenceFragmentCompat(), CoroutineScope, AccountObse
preferenceMakeDefaultBrowser?.onPreferenceClickListener = preferenceMakeDefaultBrowser?.onPreferenceClickListener =
getClickListenerForMakeDefaultBrowser() getClickListenerForMakeDefaultBrowser()
preferenceLeakCanary?.isVisible = BuildConfig.DEBUG preferenceLeakCanary?.isVisible = !BuildConfig.IS_RELEASED
if (BuildConfig.DEBUG) { if (!BuildConfig.IS_RELEASED) {
preferenceLeakCanary?.onPreferenceChangeListener = preferenceLeakCanary?.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, newValue -> Preference.OnPreferenceChangeListener { _, newValue ->
(context?.applicationContext as FenixApplication).toggleLeakCanary(newValue as Boolean) (context?.applicationContext as FenixApplication).toggleLeakCanary(newValue as Boolean)

View File

@ -44,7 +44,7 @@ class Settings private constructor(context: Context) {
val isCrashReportingEnabled: Boolean val isCrashReportingEnabled: Boolean
get() = preferences.getBoolean(appContext.getPreferenceKey(R.string.pref_key_crash_reporter), true) && get() = preferences.getBoolean(appContext.getPreferenceKey(R.string.pref_key_crash_reporter), true) &&
BuildConfig.CRASH_REPORTING && BuildConfig.BUILD_TYPE == "release" BuildConfig.CRASH_REPORTING && BuildConfig.IS_RELEASED
val isRemoteDebuggingEnabled: Boolean val isRemoteDebuggingEnabled: Boolean
get() = preferences.getBoolean(appContext.getPreferenceKey(R.string.pref_key_remote_debugging), false) get() = preferences.getBoolean(appContext.getPreferenceKey(R.string.pref_key_remote_debugging), false)

View File

@ -13,7 +13,7 @@ import os
import taskcluster import taskcluster
from lib import build_variants from lib import build_variants
from lib.tasks import TaskBuilder, schedule_task_graph, _get_architecture_and_build_type_and_product_from_variant from lib.tasks import TaskBuilder, schedule_task_graph, get_architecture_and_build_type_from_variant
from lib.chain_of_trust import ( from lib.chain_of_trust import (
populate_chain_of_trust_task_graph, populate_chain_of_trust_task_graph,
populate_chain_of_trust_required_but_unused_files populate_chain_of_trust_required_but_unused_files
@ -57,7 +57,7 @@ def pr_or_push(is_master_push):
build_tasks[assemble_task_id] = BUILDER.craft_assemble_task(variant) build_tasks[assemble_task_id] = BUILDER.craft_assemble_task(variant)
build_tasks[taskcluster.slugId()] = BUILDER.craft_test_task(variant) build_tasks[taskcluster.slugId()] = BUILDER.craft_test_task(variant)
arch, build_type, _ = _get_architecture_and_build_type_and_product_from_variant(variant) arch, build_type = get_architecture_and_build_type_from_variant(variant)
# autophone only supports arm and aarch64, so only sign/perftest those builds # autophone only supports arm and aarch64, so only sign/perftest those builds
if ( if (
build_type == 'releaseRaptor' and build_type == 'releaseRaptor' and
@ -88,7 +88,7 @@ def nightly(track):
push_tasks = {} push_tasks = {}
build_task_id = taskcluster.slugId() build_task_id = taskcluster.slugId()
build_tasks[build_task_id] = BUILDER.craft_assemble_release_task(architectures, is_staging) build_tasks[build_task_id] = BUILDER.craft_assemble_nightly_task(architectures, is_staging)
signing_task_id = taskcluster.slugId() signing_task_id = taskcluster.slugId()
signing_tasks[signing_task_id] = BUILDER.craft_nightly_signing_task( signing_tasks[signing_task_id] = BUILDER.craft_nightly_signing_task(

View File

@ -39,12 +39,12 @@ class TaskBuilder(object):
self.date = arrow.get(date_string) self.date = arrow.get(date_string)
self.trust_level = trust_level self.trust_level = trust_level
def craft_assemble_release_task(self, architectures, is_staging=False): def craft_assemble_nightly_task(self, architectures, is_staging=False):
artifacts = { artifacts = {
'public/target.{}.apk'.format(arch): { 'public/target.{}.apk'.format(arch): {
"type": 'file', "type": 'file',
"path": '/opt/fenix/app/build/outputs/apk/' "path": '/opt/fenix/app/build/outputs/apk/'
'{}Greenfield/release/app-{}-greenfield-release-unsigned.apk'.format(arch, arch), '{}/nightly/app-{}-nightly-unsigned.apk'.format(arch, arch),
"expires": taskcluster.stringDate(taskcluster.fromNow(DEFAULT_EXPIRES_IN)), "expires": taskcluster.stringDate(taskcluster.fromNow(DEFAULT_EXPIRES_IN)),
} }
for arch in architectures for arch in architectures
@ -72,7 +72,7 @@ class TaskBuilder(object):
) )
gradle_commands = ( gradle_commands = (
'./gradlew --no-daemon -PcrashReports=true -Ptelemetry=true clean test assembleRelease', './gradlew --no-daemon -PcrashReports=true -Ptelemetry=true clean test assembleNightly',
) )
command = ' && '.join( command = ' && '.join(
@ -172,8 +172,8 @@ class TaskBuilder(object):
def craft_lint_task(self): def craft_lint_task(self):
return self._craft_clean_gradle_task( return self._craft_clean_gradle_task(
name='lint', name='lint',
description='Running lint for arm64 release variant', description='Running lint for aarch64 release variant',
gradle_task='lintAarch64GreenfieldRelease', gradle_task='lintAarch64Release',
treeherder={ treeherder={
'jobKind': 'test', 'jobKind': 'test',
'machine': { 'machine': {
@ -331,22 +331,20 @@ class TaskBuilder(object):
def craft_master_commit_signing_task( def craft_master_commit_signing_task(
self, assemble_task_id, variant self, assemble_task_id, variant
): ):
architecture, build_type, product = _get_architecture_and_build_type_and_product_from_variant(variant) architecture, build_type = get_architecture_and_build_type_from_variant(variant)
product = convert_camel_case_into_kebab_case(product)
postfix = convert_camel_case_into_kebab_case('{}-{}'.format(architecture, build_type))
routes = [ routes = [
'index.project.mobile.fenix.branch.master.revision.{}.{}.{}'.format( 'index.project.mobile.fenix.v2.branch.master.revision.{}.{}.{}'.format(
self.commit, product, postfix self.commit, build_type, architecture
), ),
'index.project.mobile.fenix.branch.master.latest.{}.{}'.format( 'index.project.mobile.fenix.v2.branch.master.latest.{}.{}.{}'.format(
product, postfix product, build_type, architecture
), ),
'index.project.mobile.fenix.branch.master.pushdate.{}.{}.{}.revision.{}.{}.{}'.format( 'index.project.mobile.fenix.v2.branch.master.pushdate.{}.{}.{}.revision.{}.{}.{}'.format(
self.date.year, self.date.month, self.date.day, self.commit, self.date.year, self.date.month, self.date.day, self.commit,
product, postfix build_type, architecture
), ),
'index.project.mobile.fenix.branch.master.pushdate.{}.{}.{}.latest.{}.{}'.format( 'index.project.mobile.fenix.v2.branch.master.pushdate.{}.{}.{}.latest.{}.{}'.format(
self.date.year, self.date.month, self.date.day, product, postfix self.date.year, self.date.month, self.date.day, build_type, architecture
), ),
] ]
@ -439,15 +437,13 @@ class TaskBuilder(object):
def _craft_treeherder_platform_from_variant(variant): def _craft_treeherder_platform_from_variant(variant):
architecture, build_type, _ = _get_architecture_and_build_type_and_product_from_variant( architecture, build_type = get_architecture_and_build_type_from_variant(variant)
variant
)
return 'android-{}-{}'.format(architecture, build_type) return 'android-{}-{}'.format(architecture, build_type)
def _craft_treeherder_group_symbol_from_variant(variant): def _craft_treeherder_group_symbol_from_variant(variant):
_, __, product = _get_architecture_and_build_type_and_product_from_variant(variant) _, build_type = get_architecture_and_build_type_from_variant(variant)
return product return build_type
def _craft_artifacts_from_variant(variant): def _craft_artifacts_from_variant(variant):
@ -461,29 +457,19 @@ def _craft_artifacts_from_variant(variant):
def _craft_apk_full_path_from_variant(variant): def _craft_apk_full_path_from_variant(variant):
architecture, build_type, product = _get_architecture_and_build_type_and_product_from_variant( architecture, build_type = get_architecture_and_build_type_from_variant(variant)
variant
)
short_variant = variant[:-len(build_type)]
postfix = '-unsigned' if build_type.startswith('release') else '' postfix = '-unsigned' if build_type.startswith('release') else ''
product = lower_case_first_letter(product) return '/opt/fenix/app/build/outputs/apk/{architecture}/{build_type}/app-{architecture}-{build_type}{postfix}.apk'.format( # noqa: E501
return '/opt/fenix/app/build/outputs/apk/{short_variant}/{build_type}/app-{architecture}-{product}-{build_type}{postfix}.apk'.format( # noqa: E501
architecture=architecture, architecture=architecture,
build_type=build_type, build_type=build_type,
product=product,
short_variant=short_variant,
postfix=postfix postfix=postfix
) )
_SUPPORTED_ARCHITECTURES = ('aarch64', 'arm', 'x86') _SUPPORTED_ARCHITECTURES = ('aarch64', 'arm', 'x86')
_SUPPORTED_BUILD_TYPES = ('Debug', 'Release', 'ReleaseRaptor')
_SUPPORTED_PRODUCTS = ('FirefoxBeta', 'FirefoxNightly', 'FirefoxRelease', 'Greenfield')
def _get_architecture_and_build_type_and_product_from_variant(variant): def get_architecture_and_build_type_from_variant(variant):
for supported_architecture in _SUPPORTED_ARCHITECTURES: for supported_architecture in _SUPPORTED_ARCHITECTURES:
if variant.startswith(supported_architecture): if variant.startswith(supported_architecture):
architecture = supported_architecture architecture = supported_architecture
@ -496,32 +482,8 @@ def _get_architecture_and_build_type_and_product_from_variant(variant):
) )
) )
for supported_build_type in _SUPPORTED_BUILD_TYPES: build_type = variant[len(architecture):]
if variant.endswith(supported_build_type): return architecture, build_type
build_type = lower_case_first_letter(supported_build_type)
break
else:
raise ValueError(
'Cannot identify build type in "{}". '
'Expected to find one of these supported ones: {}'.format(
variant, _SUPPORTED_BUILD_TYPES
)
)
remaining_variant_data = variant[len(architecture):len(variant) - len(build_type)]
for supported_product in _SUPPORTED_PRODUCTS:
if remaining_variant_data == supported_product:
product = supported_product
break
else:
raise ValueError(
'Cannot identify product in "{}" "{}". '
'Expected to find one of these supported ones: {}'.format(
remaining_variant_data, variant, _SUPPORTED_PRODUCTS
)
)
return architecture, build_type, product
def schedule_task(queue, taskId, task): def schedule_task(queue, taskId, task):

View File

@ -17,4 +17,4 @@
./gradlew -q \ ./gradlew -q \
ktlint \ ktlint \
detekt \ detekt \
app:assembleX86GreenfieldDebug app:assembleX86Debug