Skip to content

Commit

Permalink
feat(build): allow testing of release APK in connected test
Browse files Browse the repository at this point in the history
Users may not have correctly configured keystores for release APK
builds so it has to default off

Release builds currently use environment variables for keystore/key
password input, so use same pathway to switch to release testing

Switching to release testing means the 'Debug' gradle tasks completely
disappear and may not be referenced at all, they are replaced by the
'Release' variants, so make the task name dynamic and base it on presence
of the release mode testing environment variable

Some Android test frameworks do not minimize correctly out of the box,
so they need a separate proguard file
  • Loading branch information
mikehardy committed Jun 21, 2024
1 parent 17ef11b commit 126e96b
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 3 deletions.
9 changes: 8 additions & 1 deletion AnkiDroid/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ android {
aidl = true
}

if (rootProject.testReleaseBuild) {
testBuildType "release"
} else {
testBuildType "debug"
}

defaultConfig {
applicationId "com.ichi2.anki"
buildConfigField "Boolean", "CI", (System.getenv("CI") == "true").toString()
Expand Down Expand Up @@ -132,6 +138,7 @@ android {
minifyEnabled true
splits.abi.universalApk = universalApkEnabled // Build universal APK for release with `-Duniversal-apk=true`
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro', 'proguard-test-rules.pro'
signingConfig signingConfigs.release

// syntax: assembleRelease -PcustomSuffix="suffix" -PcustomName="New name"
Expand Down Expand Up @@ -283,7 +290,7 @@ tasks.register('assertNonzeroAndroidTests') {
}
}
afterEvaluate {
tasks.named('connectedPlayDebugAndroidTest').configure { finalizedBy('assertNonzeroAndroidTests') }
tasks.named(androidTestName).configure { finalizedBy('assertNonzeroAndroidTests') }
}

apply from: "./robolectricDownloader.gradle"
Expand Down
4 changes: 2 additions & 2 deletions AnkiDroid/jacoco.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def testReport = tasks.register('jacocoTestReport', JacocoReport) {
}
testReport.configure {
dependsOn('testPlayDebugUnitTest')
dependsOn('connectedPlayDebugAndroidTest')
dependsOn(rootProject.androidTestName)
}

// A unit-test only report task
Expand Down Expand Up @@ -166,4 +166,4 @@ def androidTestReport = tasks.register('jacocoAndroidTestReport', JacocoReport)
'**/*.ec'
])
}
androidTestReport.configure { dependsOn('connectedPlayDebugAndroidTest') }
androidTestReport.configure { dependsOn(rootProject.androidTestName) }
15 changes: 15 additions & 0 deletions AnkiDroid/proguard-test-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# These proguard rules are only needed when building
# for the combination of testing and release mode
# Certain androidx frameworks that are test-only have
# issues with proguard / minimization in release mode

# First build error in release mode for testing:
#
# ERROR: Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in /Users/mike/work/ankidroid/Anki-Android/AnkiDroid/build/outputs/mapping/playReleaseAndroidTest/missing_rules.txt.
# ERROR: R8: Missing class com.google.protobuf.GeneratedMessageLite$MergeFromVisitor (referenced from: java.lang.Object com.google.android.apps.common.testing.accessibility.framework.uielement.proto.AndroidFrameworkProtos$LayoutParamsProto.dynamicMethod(com.google.protobuf.GeneratedMessageLite$MethodToInvoke, java.lang.Object, java.lang.Object))
# Missing class com.google.protobuf.GeneratedMessageLite$Visitor (referenced from: java.lang.Object com.google.android.apps.common.testing.accessibility.framework.proto.AccessibilityEvaluationProtos$AccessibilityEvaluation.dynamicMethod(com.google.protobuf.GeneratedMessageLite$MethodToInvoke, java.lang.Object, java.lang.Object) and 19 other contexts)
#
# We are not using automated accessibility testing, so there should be
# no impact for these classes to be missing, ignore them
-dontwarn com.google.protobuf.GeneratedMessageLite$MergeFromVisitor
-dontwarn com.google.protobuf.GeneratedMessageLite$Visitor
5 changes: 5 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ val preDexEnabled by extra("true" == System.getProperty("pre-dex", "true"))
// allows for universal APKs to be generated
val universalApkEnabled by extra("true" == System.getProperty("universal-apk", "false"))

val testReleaseBuild by extra(System.getenv("TEST_RELEASE_BUILD") == "true")
var androidTestName by extra(
if (testReleaseBuild) "connectedPlayReleaseAndroidTest" else "connectedPlayDebugAndroidTest"
)

val gradleTestMaxParallelForks by extra(
if (System.getProperty("os.name") == "Mac OS X") {
// macOS reports hardware cores. This is accurate for CI, Intel (halved due to SMT) and Apple Silicon
Expand Down

0 comments on commit 126e96b

Please sign in to comment.