refactor(build): migrate to Baseline Profile Gradle Plugin

This commit is contained in:
Harsh Shandilya 2023-07-31 16:48:09 +05:30
parent d9ab751dbd
commit 3bb5dfffbe
No known key found for this signature in database
12 changed files with 42 additions and 55 deletions

1
.gitattributes vendored
View File

@ -2,3 +2,4 @@
**/dependencies/** linguist-generated **/dependencies/** linguist-generated
**/clawicons/** linguist-generated **/clawicons/** linguist-generated
android/src/main/baseline-prof.txt linguist-generated -diff android/src/main/baseline-prof.txt linguist-generated -diff
android/src/main/generated/** linguist-generated -diff

View File

@ -51,40 +51,27 @@ jobs:
# This allows us to build most of what we need without the emulator running # This allows us to build most of what we need without the emulator running
# and using resources # and using resources
- name: Build app and benchmark - name: Build app and benchmark
run: ./gradlew :benchmark:assembleBenchmark :android:assembleBenchmark run: ./gradlew :benchmark:assembleNonMinifiedBenchmark :android:assembleNonMinifiedRelease
- name: Clear unused Gradle Managed Devices - name: Setup emulator for benchmark
run: ./gradlew cleanManagedDevices --unused-only run: ./gradlew :benchmark:api31Setup
- name: Run benchmark on Gradle Managed Device - name: Run benchmark on Gradle Managed Device
run: | run: |
./gradlew api31BenchmarkAndroidTest \ ./gradlew cleanManagedDevices
-Dorg.gradle.workers.max=1 \ ./gradlew generateBaselineProfile \
-Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile \
-Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect" -Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect"
# If we're on main branch, copy over the baseline profile and # If we're on main branch, commit the baseline profile to the repository (if changed)
# commit it to the repository (if changed)
- name: Commit baseline profile into main - name: Commit baseline profile into main
if: github.ref == 'refs/heads/main' if: github.ref == 'refs/heads/main'
run: | run: |
# Pull down any changes which may have been committed while this workflow has been running
git pull
# Sort the baseline profile, output to android/
sort -o android/src/main/baseline-prof.txt benchmark/build/outputs/managed_device_android_test_additional_output/benchmark/api31/BaselineProfileGenerator_generateBaselineProfile-baseline-prof.txt
# If the baseline profile has changed, commit it # If the baseline profile has changed, commit it
if [[ $(git diff --stat android/src/main/baseline-prof.txt) != '' ]]; then if [[ $(git diff --stat android/src/main/generated/baselineProfiles/baseline-prof.txt) != '' ]]; then
git add android/src/main/baseline-prof.txt git add android/src/main/generated/baselineProfiles/baseline-prof.txt
git commit -m "chore(android): refresh baseline profile" && git push git commit -m "chore(android): refresh baseline profile" && git push
fi fi
# Upload the entire output folder and attach it to the CI run
- name: Attach baseline profile
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: Baseline profile output
path: benchmark/build/outputs/managed_device_android_test_additional_output
- name: Clean secrets - name: Clean secrets
if: always() if: always()
run: scripts/signing-cleanup.sh run: scripts/signing-cleanup.sh

View File

@ -1 +0,0 @@
-dontobfuscate

View File

@ -18,6 +18,7 @@ plugins {
alias(libs.plugins.anvil) alias(libs.plugins.anvil)
alias(libs.plugins.modulegraphassert) alias(libs.plugins.modulegraphassert)
alias(libs.plugins.whetstone) alias(libs.plugins.whetstone)
alias(libs.plugins.baselineprofile)
} }
android { android {
@ -28,18 +29,16 @@ android {
useLiveLiterals = false useLiveLiterals = false
kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get() kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get()
} }
buildTypes {
create("benchmark") {
signingConfig = signingConfigs["debug"]
matchingFallbacks += "release"
isDebuggable = false
proguardFile("benchmark-rules.pro")
applicationIdSuffix = ".benchmark"
}
}
packaging { jniLibs { useLegacyPackaging = true } } packaging { jniLibs { useLegacyPackaging = true } }
} }
baselineProfile {
dexLayoutOptimization = true
mergeIntoMain = true
saveInSrc = true
from(projects.benchmark.dependencyProject)
}
moduleGraphAssert { moduleGraphAssert {
assertOnAnyBuild = true assertOnAnyBuild = true
maxHeight = 4 maxHeight = 4

View File

@ -10,13 +10,14 @@ import com.android.build.api.dsl.ManagedVirtualDevice
plugins { plugins {
alias(libs.plugins.android.test) alias(libs.plugins.android.test)
id("dev.msfjarvis.claw.android-common")
id("dev.msfjarvis.claw.kotlin-android") id("dev.msfjarvis.claw.kotlin-android")
alias(libs.plugins.baselineprofile)
} }
android { android {
namespace = "dev.msfjarvis.claw.benchmark" namespace = "dev.msfjarvis.claw.benchmark"
compileSdk = 34
defaultConfig { defaultConfig {
minSdk = 28 minSdk = 28
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
@ -30,23 +31,23 @@ android {
} }
} }
testOptions { testOptions.managedDevices.devices {
managedDevices { create<ManagedVirtualDevice>("api31") {
devices { device = "Pixel 6"
create<ManagedVirtualDevice>("api31") { apiLevel = 31
device = "Pixel 6" systemImageSource = "aosp"
apiLevel = 31
systemImageSource = "aosp"
}
}
} }
} }
targetProjectPath = ":android" targetProjectPath = ":android"
experimentalProperties["android.experimental.self-instrumenting"] = true experimentalProperties["android.experimental.r8.dex-startup-optimization"] = true
} }
androidComponents { beforeVariants(selector().all()) { it.enable = it.buildType == "benchmark" } } baselineProfile {
managedDevices += "api31"
useConnectedDevices = false
enableEmulatorDisplay = false
}
dependencies { dependencies {
implementation(libs.androidx.benchmark.macro.junit4) implementation(libs.androidx.benchmark.macro.junit4)

View File

@ -28,6 +28,7 @@ class BaselineProfileGenerator {
baselineProfileRule.collect( baselineProfileRule.collect(
packageName = PACKAGE_NAME, packageName = PACKAGE_NAME,
maxIterations = 8, maxIterations = 8,
includeInStartupProfile = true,
) { ) {
device.executeShellCommand("pm clear $PACKAGE_NAME") device.executeShellCommand("pm clear $PACKAGE_NAME")

View File

@ -12,7 +12,7 @@ import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiObject2 import androidx.test.uiautomator.UiObject2
import androidx.test.uiautomator.Until import androidx.test.uiautomator.Until
const val PACKAGE_NAME = "dev.msfjarvis.claw.android.benchmark" const val PACKAGE_NAME = "dev.msfjarvis.claw.android"
private const val AWAIT_TIMEOUT = 10_000L private const val AWAIT_TIMEOUT = 10_000L
private const val SAVE_BUTTON_ID = "save_button" private const val SAVE_BUTTON_ID = "save_button"
private const val NAV_ID_HOTTEST = "HOTTEST" private const val NAV_ID_HOTTEST = "HOTTEST"

View File

@ -28,15 +28,7 @@ class SentryPlugin : Plugin<Project> {
onVariants(selector().all()) { variant -> onVariants(selector().all()) { variant ->
val sentryDsn = project.providers.environmentVariable(SENTRY_DSN_PROPERTY) val sentryDsn = project.providers.environmentVariable(SENTRY_DSN_PROPERTY)
variant.manifestPlaceholders.put("sentryDsn", sentryDsn.getOrElse("")) variant.manifestPlaceholders.put("sentryDsn", sentryDsn.getOrElse(""))
} variant.manifestPlaceholders.put("enableSentry", "${variant.name == "release"}")
onVariants(selector().withBuildType("benchmark")) { variant ->
variant.manifestPlaceholders.put("enableSentry", "false")
}
onVariants(selector().withBuildType("debug")) { variant ->
variant.manifestPlaceholders.put("enableSentry", "false")
}
onVariants(selector().withBuildType("release")) { variant ->
variant.manifestPlaceholders.put("enableSentry", "true")
} }
} }
project.plugins.apply(io.sentry.android.gradle.SentryPlugin::class) project.plugins.apply(io.sentry.android.gradle.SentryPlugin::class)

View File

@ -43,8 +43,11 @@ android.dependencyResolutionAtConfigurationTime.disallow=true
# Disallow parsing the manifest too early in the build process # Disallow parsing the manifest too early in the build process
android.disableEarlyManifestParsing=true android.disableEarlyManifestParsing=true
# Prevent CI stalling during setup
android.experimental.testOptions.managedDevices.setupTimeoutMinutes=20
# Disable warnings about unsupported features # Disable warnings about unsupported features
android.suppressUnsupportedOptionWarnings=android.dependencyResolutionAtConfigurationTime.disallow,android.disableEarlyManifestParsing,android.suppressUnsupportedOptionWarnings android.suppressUnsupportedOptionWarnings=android.dependencyResolutionAtConfigurationTime.disallow,android.disableEarlyManifestParsing,android.suppressUnsupportedOptionWarnings,,android.experimental.testOptions.managedDevices.setupTimeoutMinutes
# Add opens for KAPT # Add opens for KAPT
# https://youtrack.jetbrains.com/issue/KT-45545#focus=Comments-27-4862682.0-0 # https://youtrack.jetbrains.com/issue/KT-45545#focus=Comments-27-4862682.0-0

View File

@ -1,6 +1,7 @@
[versions] [versions]
accompanist = "0.31.4-beta" accompanist = "0.31.4-beta"
agp = "8.2.0-alpha14" agp = "8.2.0-alpha14"
benchmark = "1.2.0-beta02"
coil = "2.4.0" coil = "2.4.0"
# @keep used for kotlinCompilerExtensionVersion # @keep used for kotlinCompilerExtensionVersion
composeCompiler = "1.5.1" composeCompiler = "1.5.1"
@ -19,7 +20,7 @@ workmanager = "2.9.0-alpha02"
[libraries] [libraries]
accompanist-sysuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" } accompanist-sysuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" }
androidx-activity-compose = "androidx.activity:activity-compose:1.7.2" androidx-activity-compose = "androidx.activity:activity-compose:1.7.2"
androidx-benchmark-macro-junit4 = "androidx.benchmark:benchmark-macro-junit4:1.2.0-beta02" androidx-benchmark-macro-junit4 = { module = "androidx.benchmark:benchmark-macro-junit4", version.ref = "benchmark" }
androidx-browser = "androidx.browser:browser:1.5.0" androidx-browser = "androidx.browser:browser:1.5.0"
androidx-compose-animation = { module = "androidx.compose.animation:animation" } androidx-compose-animation = { module = "androidx.compose.animation:animation" }
androidx-compose-bom = "dev.chrisbanes.compose:compose-bom:2023.07.00-alpha02" androidx-compose-bom = "dev.chrisbanes.compose:compose-bom:2023.07.00-alpha02"
@ -98,6 +99,7 @@ whetstone = { module = "com.deliveryhero.whetstone:whetstone", version.ref = "wh
[plugins] [plugins]
android-test = { id = "com.android.test", version.ref = "agp" } android-test = { id = "com.android.test", version.ref = "agp" }
anvil = "com.squareup.anvil:2.4.7" anvil = "com.squareup.anvil:2.4.7"
baselineprofile = { id = "androidx.baselineprofile", version.ref = "benchmark" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
modulegraph = "dev.iurysouza.modulegraph:0.4.0" modulegraph = "dev.iurysouza.modulegraph:0.4.0"
modulegraphassert = "com.jraska.module.graph.assertion:2.4.1" modulegraphassert = "com.jraska.module.graph.assertion:2.4.1"

View File

@ -12,6 +12,8 @@ pluginManagement {
exclusiveContent { exclusiveContent {
forRepository { google() } forRepository { google() }
filter { filter {
includeGroup("androidx.baselineprofile")
includeGroup("androidx.benchmark")
includeGroup("androidx.databinding") includeGroup("androidx.databinding")
includeGroup("com.android") includeGroup("com.android")
includeModule("com.android.test", "com.android.test.gradle.plugin") includeModule("com.android.test", "com.android.test.gradle.plugin")