Skip to content

Commit

Permalink
Add Baseline Profiles CI pipeline (#230)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Ben Weiss <benweiss@google.com>
  • Loading branch information
mlykotom and keyboardsurfer committed Jul 20, 2023
1 parent 249db05 commit 8e71615
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 9 deletions.
28 changes: 28 additions & 0 deletions .github/ci-gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#
# Copyright 2022 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

org.gradle.daemon=false
org.gradle.parallel=true
org.gradle.workers.max=2

kotlin.incremental=false
kotlin.compiler.execution.strategy=in-process

# Controls KotlinOptions.allWarningsAsErrors.
# This value used in CI and is currently set to false.
# If you want to treat warnings as errors locally, set this property to true
# in your ~/.gradle/gradle.properties file.
warningsAsErrors=false
117 changes: 117 additions & 0 deletions .github/workflows/generate-bp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
name: Generate Baseline Profiles

on:
push:
branches: [ main ]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true

jobs:
# This job checks for any file changed within MacrobenchmarkSample/ folder
# to distinguish if the build check for Macrobenchmark is needed to be run.
# It sets the outputs.macrobenchmark to true/false based on the changes.
# In the next build job, it checks for needs.changes.outputs.macrobenchmark == 'true'
# or skips the job otherwise.
changes:
if: github.repository_owner == 'android'
runs-on: ubuntu-latest
# Set job outputs to values from filter step to be able to use it in next job
outputs:
macrobenchmark: ${{ steps.filter.outputs.macrobenchmark }}
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
macrobenchmark:
- 'MacrobenchmarkSample/**'
baseline-profile:
needs: changes
# # Only run action for the main repo & not forks and if change is in macrobenchmark sample
if: github.repository_owner == 'android' && (needs.changes.outputs.macrobenchmark == 'true' || github.event_name == 'workflow_dispatch')
runs-on: macos-latest
timeout-minutes: 60
defaults:
run:
working-directory: ./MacrobenchmarkSample
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup JDK
id: setup-java
uses: actions/setup-java@v3
with:
java-version: 17
distribution: "zulu"

- name: Setup Gradle
uses: gradle/gradle-build-action@v2
with:
gradle-home-cache-cleanup: true

- name: Copy CI gradle.properties
working-directory: ./
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

- name: Clean GMD
run: ./gradlew cleanManagedDevices --unused-only

# Runs all Baseline Profiles generators on Gradle Managed Device
# If the module contains both benchmarks and generators, we need to filter just the generators,
# because benchmarks should be run on a physical device and thus would fail by default.
- name: Run generator with GMD
uses: nick-fields/retry@v2
with:
max_attempts: 2
command: >
./gradlew :app:generateBaselineProfile
-Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect"
-Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile
- name: Upload Logcat logs
uses: actions/upload-artifact@v3
if: always()
with:
name: "Logcat"
path: MacrobenchmarkSample/baselineProfile/build/outputs/androidTest-results/managedDevice/pixel6Api31/logcat-*.txt

# Upload all the generated profiles to artifacts
- name: Upload generated profiles
uses: actions/upload-artifact@v3
with:
name: "Baseline Profiles"
path: MacrobenchmarkSample/app/src/release/generated/baselineProfiles/*.txt

# Create a PR with the generated Baseline Profiles
- name: Create PR with generated profiles
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.ANDROID_DEVREL_BOT_TOKEN }}
commit-message: '[Generated] Baseline Profiles'
committer: BP Bot <android-devrel-github-bot@google.com>
author: BP Bot <android-devrel-github-bot@google.com>
title: '[Generated] Baseline Profiles'
body: 'Updates baseline profiles'
reviewers: ${{ github.actor }}
branch: bot/update-baseline-profiles

# If you generate the rules before producing your production app, you need to build it here with the profile.
# We use benchmark variant, because release variant is not specified,
# but generally this is where you want to generate your production version of your app
- name: Build production app
run: >
./gradlew assembleRelease
- name: Upload app with Baseline Profile
uses: actions/upload-artifact@v3
with:
name: "Production App"
path: MacrobenchmarkSample/app/build/outputs/apk/release/*.apk

8 changes: 5 additions & 3 deletions MacrobenchmarkSample/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ android {
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
// In real app, this would use its own release keystore
signingConfig = signingConfigs.getByName("debug")
}

create("benchmark") {
Expand All @@ -66,11 +68,11 @@ android {
// [END macrobenchmark_setup_app_build_type]

compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
jvmTarget = JavaVersion.VERSION_17.toString()
freeCompilerArgs = freeCompilerArgs + listOf(
"-opt-in=kotlin.RequiresOptIn"
)
Expand Down
1 change: 1 addition & 0 deletions MacrobenchmarkSample/baselineProfile/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ baselineProfile {
}

dependencies {
implementation(project(":baseBenchmarks"))
implementation(libs.benchmark.junit)
implementation(libs.androidx.junit)
implementation(libs.espresso)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ import org.junit.runner.RunWith
* start generating a profile directly by implementing [MacrobenchmarkScope.profileBlock].
*/
@RunWith(AndroidJUnit4::class)
@RequiresApi(Build.VERSION_CODES.P)
abstract class BaselineProfileGeneratorScaffold {

@get:Rule
val rule = BaselineProfileRule()

/**
* Generate a baseline profile in this function.
*/
Expand All @@ -50,4 +51,4 @@ abstract class BaselineProfileGeneratorScaffold {
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ import androidx.benchmark.macro.MacrobenchmarkScope
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Direction
import com.example.benchmark.macro.base.util.findOrFail
import com.example.benchmark.macro.base.util.waitAndFind
import org.junit.Ignore
import org.junit.runner.RunWith

@Ignore // TODO causing stale object excpetion on CI .. why?
@RunWith(AndroidJUnit4::class)
class ComposeActivityBaselineProfileGenerator : BaselineProfileGeneratorScaffold() {

Expand All @@ -31,10 +35,11 @@ class ComposeActivityBaselineProfileGenerator : BaselineProfileGeneratorScaffold
startActivityAndWait(Intent("$TARGET_PACKAGE.COMPOSE_ACTIVITY"))

// Scrolling through the Compose journey
device.findObject(By.res("myLazyColumn")).also {
device.waitAndFind(By.res("myLazyColumn")).also {
it.setGestureMargin(device.displayWidth / 10)
it.fling(Direction.DOWN)
it.fling(Direction.UP)
}

device.findOrFail(By.res("myLazyColumn")).fling(Direction.UP)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import androidx.benchmark.macro.MacrobenchmarkScope
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Direction
import org.junit.Ignore
import org.junit.runner.RunWith

@Ignore // TODO flinging not working, ignore for now to test the pipeline
@RunWith(AndroidJUnit4::class)
class RecyclerViewActivityBaselineProfileGenerator : BaselineProfileGeneratorScaffold() {

Expand All @@ -36,6 +38,5 @@ class RecyclerViewActivityBaselineProfileGenerator : BaselineProfileGeneratorSca
it.fling(Direction.DOWN)
it.fling(Direction.UP)
}

}
}
2 changes: 1 addition & 1 deletion MacrobenchmarkSample/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ profileInstaller = "1.3.1"
rules = "1.5.0"
testExt = "1.1.4"
tracing = "1.1.0"
uiAutomator = "2.2.0"
uiAutomator = "2.3.0-alpha03"

[libraries]
androidx-rules = { module = "androidx.test:rules", version.ref = "rules" }
Expand Down

0 comments on commit 8e71615

Please sign in to comment.