From 03166ef532770f447d3309d35e15a89c1f21ae5b Mon Sep 17 00:00:00 2001 From: Sagar Viradiya Date: Wed, 6 Dec 2023 23:11:13 +0530 Subject: [PATCH 1/2] Plugin configuration change - Remove firebase Project ID config and add service account credential --- .../AutoBenchmarkExtension.kt | 5 ++--- .../AutoBenchmarkPlugin.kt | 3 ++- sample/build.gradle.kts | 6 +----- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/auto-benchmark-plugin/plugin/src/main/kotlin/io.github.sagar.auto_benchmark_plugin/AutoBenchmarkExtension.kt b/auto-benchmark-plugin/plugin/src/main/kotlin/io.github.sagar.auto_benchmark_plugin/AutoBenchmarkExtension.kt index e0638b6..11c81cb 100644 --- a/auto-benchmark-plugin/plugin/src/main/kotlin/io.github.sagar.auto_benchmark_plugin/AutoBenchmarkExtension.kt +++ b/auto-benchmark-plugin/plugin/src/main/kotlin/io.github.sagar.auto_benchmark_plugin/AutoBenchmarkExtension.kt @@ -28,7 +28,6 @@ import org.gradle.api.Project import org.gradle.api.provider.MapProperty import org.gradle.api.provider.Property import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.getByType interface AutoBenchmarkExtension { @@ -43,9 +42,9 @@ interface AutoBenchmarkExtension { val benchmarkApkFilePath: Property /** - * Firebase project ID to access firebase test lab + * Service account JSON file to authenticate GCloud */ - val firebaseProjectId: Property + val serviceAccountJsonFilePath: Property /** * Physical device configuration map to run benchmark diff --git a/auto-benchmark-plugin/plugin/src/main/kotlin/io.github.sagar.auto_benchmark_plugin/AutoBenchmarkPlugin.kt b/auto-benchmark-plugin/plugin/src/main/kotlin/io.github.sagar.auto_benchmark_plugin/AutoBenchmarkPlugin.kt index e3de852..b7ccdf8 100644 --- a/auto-benchmark-plugin/plugin/src/main/kotlin/io.github.sagar.auto_benchmark_plugin/AutoBenchmarkPlugin.kt +++ b/auto-benchmark-plugin/plugin/src/main/kotlin/io.github.sagar.auto_benchmark_plugin/AutoBenchmarkPlugin.kt @@ -28,6 +28,7 @@ import com.android.build.api.variant.AndroidComponentsExtension import com.osacky.flank.gradle.FlankGradleExtension import org.gradle.api.Plugin import org.gradle.api.Project +import java.io.File class AutoBenchmarkPlugin : Plugin { companion object { @@ -80,7 +81,7 @@ class AutoBenchmarkPlugin : Plugin { extension.physicalDevices.get() ) ) - projectId.set(extension.firebaseProjectId.get()) + serviceAccountCredentials.set(File(extension.serviceAccountJsonFilePath.get())) } apply { diff --git a/sample/build.gradle.kts b/sample/build.gradle.kts index d480882..ed0ff01 100644 --- a/sample/build.gradle.kts +++ b/sample/build.gradle.kts @@ -24,8 +24,6 @@ @file:Suppress("UnstableApiUsage") -import java.util.Properties - plugins { id("com.android.application") id("org.jetbrains.kotlin.android") @@ -33,8 +31,6 @@ plugins { id("io.github.sagar-viradiya.autobenchmark") } -val properties = Properties().apply { load(project.rootProject.file("local.properties").inputStream()) } - android { namespace = "io.github.sagar.auto_benchmark" compileSdk = 33 @@ -98,7 +94,7 @@ dependencies { autoBenchmark { appApkFilePath.set("/sample/build/outputs/apk/benchmark/sample-benchmark.apk") benchmarkApkFilePath.set("/benchmark/build/outputs/apk/benchmark/benchmark-benchmark.apk") - firebaseProjectId.set(properties.getProperty("firebaseProjectId")) + serviceAccountJsonFilePath.set("../../../../.config/gcloud/") physicalDevices.set(mapOf( "model" to "redfin", "version" to "30" )) From 631976e4b808c0f402428c2a93b262ff49db97b7 Mon Sep 17 00:00:00 2001 From: Sagar Viradiya Date: Thu, 7 Dec 2023 23:57:57 +0530 Subject: [PATCH 2/2] Setup GitHub action for profile verification (#17) * CI setup to automate baseline profile - Add Github action workflow to trigger profile verification * Update dependency - Update macro-benchmark dependency * Update github workflow - Replace Java 11 setup with java 17 * Plugin config changes - Replace firebase project ID config with service account JSON config to support profile verification on CI * Plugin upgrade - Update AGP from 8.0.0 to 8.2.0 - Update compile SDK version from 33 to 34 * Workflow changes - Remove decoding json file and writing * Workflow changes - Inline the directory creation * Workflow changes - Change the run script within step * Workflow changes - Replace access of encoded service account from env to vars * Plugin config changes - Fix the service account JSON file path * Workflow changes - Add log for home path in GCloud authentication * Workflow changes - Update the service account JSON path for GCloud authentication * Plugin configuration change - Rename step to setup service account JSON * Workflow changes - Trigger workflow only on tag push * Workflow changes and version upgrade - Trigger profile verification workflow on pull request against release branch - Upgrade plugin version from 1.0.0-alpha01 to 1.0.0-alpha02 - Add CI setup details in the README --- .github/workflows/profile_verification.yml | 40 +++++++++++++++++++ README.md | 20 +++++----- auto-benchmark-plugin/gradle.properties | 2 +- .../AutoBenchmarkExtension.kt | 2 +- baseline-profile/build.gradle.kts | 2 +- ...BenchmarkSampleBaselineProfileGenerator.kt | 4 +- benchmark/build.gradle.kts | 6 +-- build.gradle.kts | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- sample/build.gradle.kts | 8 ++-- 10 files changed, 64 insertions(+), 26 deletions(-) create mode 100644 .github/workflows/profile_verification.yml diff --git a/.github/workflows/profile_verification.yml b/.github/workflows/profile_verification.yml new file mode 100644 index 0000000..da6d42f --- /dev/null +++ b/.github/workflows/profile_verification.yml @@ -0,0 +1,40 @@ +name: Verify Baseline Profile + +on: + pull_request: + branches: + - release + +jobs: + build-benchmark-apks: + name: Build APKs and Run profile verification + runs-on: macos-latest + timeout-minutes: 20 + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Validate Gradle Wrapper + uses: gradle/wrapper-validation-action@v1 + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: 17 + + - name: Build benchmark apk + run: ./gradlew :benchmark:assembleBenchmark + + - name: Build app apk + run: ./gradlew :sample:assembleBenchmark + + - name: Setup GCloud Credentials for Flank + run: | + GCLOUD_DIR="$HOME/.config/gcloud/" + mkdir -p "$GCLOUD_DIR" + echo "${{ vars.GCLOUD_KEY }}" | base64 --decode > "$GCLOUD_DIR/application_default_credentials.json" + + - name: Verify baseline profile + run: ./gradlew :sample:runBenchmarkAndVerifyProfile diff --git a/README.md b/README.md index 5719a8d..88b5216 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ For more information on benchmarking baseline profile visit official [Android gu Apply plugin to app module `build.gradle.kts` file. ```kotlin plugins { - id("io.github.sagar-viradiya.autobenchmark") version "1.0.0.alpha01" + id("io.github.sagar-viradiya.autobenchmark") version "1.0.0.alpha02" } ``` @@ -30,7 +30,7 @@ buildscript { } } dependencies { - classpath("io.github.sagar-viradiya:autobenchmark:1.0.0.alpha01") + classpath("io.github.sagar-viradiya:autobenchmark:1.0.0.alpha02") } } ``` @@ -51,8 +51,8 @@ autoBenchmark { appApkFilePath.set("/sample/build/outputs/apk/benchmark/sample-benchmark.apk") // A relative file path from the root to benchmark apk benchmarkApkFilePath.set("/benchmark/build/outputs/apk/benchmark/benchmark-benchmark.apk") - // Firebase project ID to access firebase test lab - firebaseProjectId.set("firebaseProjectId") + // Service account JSON file path to authenticate GCloud + serviceAccountJsonFilePath.set("../../.config/gcloud/application_default_credentials.json") // Physical device configuration map to run benchmark physicalDevices.set(mapOf( "model" to "redfin", "version" to "30" @@ -64,7 +64,7 @@ autoBenchmark { ### 🔐 Authenticate G-Cloud to run tests on Firebase test lab -To run tests on Firebase test lab you need to authenticate to G-Cloud. +To run tests on Firebase test lab and download JSON result of profile verification, you need to authenticate to G-Cloud. #### Authenticating on local machine @@ -76,19 +76,20 @@ This will store credentials in ~/.flank directory #### Authenticating on CI You will need service account JSON file to setup authentication on CI. Follow the [test lab docs](https://firebase.google.com/docs/test-lab/android/continuous) to create a service account. -Base64 encode this file on CI as GCLOUD_KEY using shell script. +Base64 encode this file on your local machine and set this as environment variable on CI as GCLOUD_KEY. ```shell base64 -i "$HOME/.config/gcloud/application_default_credentials.json" | pbcopy ``` -Then in CI decode the JSON. +Then on CI decode the JSON. ```shell GCLOUD_DIR="$HOME/.config/gcloud/" mkdir -p "$GCLOUD_DIR" echo "$GCLOUD_KEY" | base64 --decode > "$GCLOUD_DIR/application_default_credentials.json" ``` +Please refer to GitHub action setup to know how this is being done. For more info refer [this](https://flank.github.io/flank/#authenticate-with-a-service-account) flank guide for authentication as this plugin internally uses Fladle and Flank @@ -137,10 +138,9 @@ Run following commands to build apks ./gradlew :benchmark:assembleBenchmark ``` -You will need your firebase test lab project ID in local.properties file. Also, you need to authenticate -G-cloud to run tests on Firebase test lab. +Also make sure to have service account JSON file in the configured path (`serviceAccountJsonFilePath`) -Sample CI setup using github action is coming soon! +For verifying profile on CI, please refer to GitHub action setup. ## Contribution Unfortunately it is not ready to accept any contribution diff --git a/auto-benchmark-plugin/gradle.properties b/auto-benchmark-plugin/gradle.properties index 51e9eeb..2e9f53f 100644 --- a/auto-benchmark-plugin/gradle.properties +++ b/auto-benchmark-plugin/gradle.properties @@ -23,7 +23,7 @@ # ID=io.github.sagar-viradiya.autobenchmark -VERSION=1.0.0-alpha01 +VERSION=1.0.0-alpha02 GROUP=io.github.sagar-viradiya DISPLAY_NAME=Auto Benchmark DESCRIPTION=Automate baseline profile on CI by running benchmark instrumentation tests on Firebase test lab and verifying benchmark result. diff --git a/auto-benchmark-plugin/plugin/src/main/kotlin/io.github.sagar.auto_benchmark_plugin/AutoBenchmarkExtension.kt b/auto-benchmark-plugin/plugin/src/main/kotlin/io.github.sagar.auto_benchmark_plugin/AutoBenchmarkExtension.kt index 11c81cb..203bd95 100644 --- a/auto-benchmark-plugin/plugin/src/main/kotlin/io.github.sagar.auto_benchmark_plugin/AutoBenchmarkExtension.kt +++ b/auto-benchmark-plugin/plugin/src/main/kotlin/io.github.sagar.auto_benchmark_plugin/AutoBenchmarkExtension.kt @@ -42,7 +42,7 @@ interface AutoBenchmarkExtension { val benchmarkApkFilePath: Property /** - * Service account JSON file to authenticate GCloud + * Service account JSON file path to authenticate GCloud */ val serviceAccountJsonFilePath: Property diff --git a/baseline-profile/build.gradle.kts b/baseline-profile/build.gradle.kts index a571e67..5486299 100644 --- a/baseline-profile/build.gradle.kts +++ b/baseline-profile/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("androidx.test.ext:junit:1.1.5") implementation("androidx.test.espresso:espresso-core:3.5.1") implementation("androidx.test.uiautomator:uiautomator:2.2.0") - implementation("androidx.benchmark:benchmark-macro-junit4:1.1.1") + implementation("androidx.benchmark:benchmark-macro-junit4:1.2.0") } diff --git a/baseline-profile/src/main/java/io/github/sagar/baseline_profile/AutoBenchmarkSampleBaselineProfileGenerator.kt b/baseline-profile/src/main/java/io/github/sagar/baseline_profile/AutoBenchmarkSampleBaselineProfileGenerator.kt index aedb68d..e100037 100644 --- a/baseline-profile/src/main/java/io/github/sagar/baseline_profile/AutoBenchmarkSampleBaselineProfileGenerator.kt +++ b/baseline-profile/src/main/java/io/github/sagar/baseline_profile/AutoBenchmarkSampleBaselineProfileGenerator.kt @@ -24,19 +24,17 @@ package io.github.sagar.baseline_profile -import androidx.benchmark.macro.ExperimentalBaselineProfilesApi import androidx.benchmark.macro.junit4.BaselineProfileRule import org.junit.Rule import org.junit.Test -@OptIn(ExperimentalBaselineProfilesApi::class) class AutoBenchmarkSampleBaselineProfileGenerator { @get:Rule val baselineProfileRule = BaselineProfileRule() @Test - fun startup() = baselineProfileRule.collectBaselineProfile( + fun startup(): Unit = baselineProfileRule.collect( packageName = "io.github.sagar.auto_benchmark", profileBlock = { startActivityAndWait() diff --git a/benchmark/build.gradle.kts b/benchmark/build.gradle.kts index 795116b..cc0d764 100644 --- a/benchmark/build.gradle.kts +++ b/benchmark/build.gradle.kts @@ -29,7 +29,7 @@ plugins { android { namespace = "io.github.sagar.benchmark" - compileSdk = 33 + compileSdk = 34 compileOptions { sourceCompatibility = JavaVersion.VERSION_11 @@ -42,7 +42,7 @@ android { defaultConfig { minSdk = 24 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } @@ -64,7 +64,7 @@ dependencies { implementation("androidx.test.ext:junit:1.1.5") implementation("androidx.test.espresso:espresso-core:3.5.1") implementation("androidx.test.uiautomator:uiautomator:2.2.0") - implementation("androidx.benchmark:benchmark-macro-junit4:1.1.1") + implementation("androidx.benchmark:benchmark-macro-junit4:1.2.0") } androidComponents { diff --git a/build.gradle.kts b/build.gradle.kts index 4183e4a..63a1029 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,9 +23,9 @@ */ plugins { - id("com.android.application") version "8.0.0" apply false + id("com.android.application") version "8.2.0" apply false id("org.jetbrains.kotlin.android") version "1.8.10" apply false - id("com.android.test") version "8.0.0" apply false + id("com.android.test") version "8.2.0" apply false id("androidx.baselineprofile") version "1.2.0-alpha16" apply false } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b91614f..0ad0133 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -25,6 +25,6 @@ #Sat Jul 15 19:58:19 CEST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/sample/build.gradle.kts b/sample/build.gradle.kts index ed0ff01..3d800a8 100644 --- a/sample/build.gradle.kts +++ b/sample/build.gradle.kts @@ -33,12 +33,12 @@ plugins { android { namespace = "io.github.sagar.auto_benchmark" - compileSdk = 33 + compileSdk = 34 defaultConfig { applicationId = "io.github.sagar.auto_benchmark" minSdk = 24 - targetSdk = 33 + targetSdk = 34 versionCode = 1 versionName = "1.0" @@ -94,9 +94,9 @@ dependencies { autoBenchmark { appApkFilePath.set("/sample/build/outputs/apk/benchmark/sample-benchmark.apk") benchmarkApkFilePath.set("/benchmark/build/outputs/apk/benchmark/benchmark-benchmark.apk") - serviceAccountJsonFilePath.set("../../../../.config/gcloud/") + serviceAccountJsonFilePath.set("../../../../.config/gcloud/application_default_credentials.json") physicalDevices.set(mapOf( "model" to "redfin", "version" to "30" )) - tolerancePercentage.set(10f) + tolerancePercentage.set(5f) }