Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e63d51a

Browse files
committedJun 18, 2024·
Run android emulator on ubuntu build agent. gradle-managed-devices is used instead of reactivecircus/android-emulator-runner GitHub action task
1 parent c189411 commit e63d51a

File tree

23 files changed

+207
-127
lines changed

23 files changed

+207
-127
lines changed
 

‎.github/workflows/pull_request.yml

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,46 +8,41 @@ on:
88
branches: [ master ]
99

1010
jobs:
11+
jobEmulatorMatrixSetup:
12+
runs-on: ubuntu-latest
13+
outputs:
14+
emulator_jobs_matrix: ${{ steps.dataStep.outputs.emulator_jobs_matrix }}
15+
steps:
16+
- uses: actions/checkout@v4
17+
- name: Set up JDK
18+
uses: actions/setup-java@v3
19+
with:
20+
distribution: 'zulu'
21+
java-version: '17'
22+
cache: gradle
23+
- name: Prepare the matrix JSON
24+
run: ./gradlew ciEmulatorJobsMatrixSetup
25+
- id: dataStep
26+
run: echo "emulator_jobs_matrix=$(jq -c . < ./build/emulator_jobs_matrix.json)" >> $GITHUB_OUTPUT
1127
build-android:
12-
runs-on: macos-13
28+
needs: jobEmulatorMatrixSetup
29+
runs-on: ubuntu-latest
1330
strategy:
14-
matrix:
15-
api-level: [ 34 ]
31+
fail-fast: false
32+
matrix: ${{ fromJson(needs.jobEmulatorMatrixSetup.outputs.emulator_jobs_matrix) }}
1633
steps:
1734
- uses: actions/checkout@v3
35+
- name: Enable KVM group perms
36+
run: |
37+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
38+
sudo udevadm control --reload-rules
39+
sudo udevadm trigger --name-match=kvm
1840
- name: Setup test environment
1941
uses: ./.github/actions/setup_test_action
20-
- name: AVD cache
21-
uses: actions/cache@v3
22-
id: avd-cache
23-
with:
24-
path: |
25-
~/.android/avd/*
26-
~/.android/adb*
27-
key: avd-${{ matrix.api-level }}-${{ runner.os }}-${{ runner.arch }}
28-
- name: create AVD and generate snapshot for caching
29-
if: steps.avd-cache.outputs.cache-hit != 'true'
30-
uses: reactivecircus/android-emulator-runner@v2
31-
with:
32-
api-level: ${{ matrix.api-level }}
33-
arch: x86_64
34-
target: google_apis
35-
avd-name: pixel6_API${{ matrix.api-level }}
36-
force-avd-creation: false
37-
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
38-
disable-animations: false
39-
script: echo "Generated AVD snapshot for caching."
42+
- name: Apply Android licenses
43+
run: ./gradlew ciSdkManagerLicenses
4044
- name: Run Android Instrumented Tests
41-
uses: reactivecircus/android-emulator-runner@v2
42-
with:
43-
api-level: ${{ matrix.api-level }}
44-
arch: x86_64
45-
target: google_apis
46-
avd-name: pixel6_API${{ matrix.api-level }}
47-
force-avd-creation: false
48-
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
49-
disable-animations: true
50-
script: ./gradlew connectedAndroidTest
45+
run: ./gradlew gradleManagedDeviceDebugAndroidTest
5146
- name: Upload Android test artifact
5247
uses: actions/upload-artifact@v3
5348
if: failure()

‎.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Project exclude paths
2-
/.gradle/
2+
/**/.gradle/
33
/**/build/
44
/.idea/
55
local.properties

‎build.gradle.kts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
22
import org.gradle.api.tasks.testing.logging.TestLogEvent
3+
import java.io.InputStream
34

45
plugins {
56
alias(libs.plugins.android.application) apply false
@@ -9,6 +10,8 @@ plugins {
910
alias(libs.plugins.test.logger.plugin) apply false
1011
alias(libs.plugins.ben.manes.versions) apply false
1112
id("base")
13+
id("testOptionsConvention")
14+
1215
}
1316

1417
val compileSdkVersion by extra(34)
@@ -201,3 +204,32 @@ tasks.withType<com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask
201204
reportfileName = "dependency-updates"
202205
}
203206
// check for latest dependencies - ./gradlew dependencyUpdates -Drevision=release
207+
208+
tasks.register("ciEmulatorJobsMatrixSetup") {
209+
doLast {
210+
EmulatorJobsMatrix().createMatrixJsonFile(rootProject = rootProject)
211+
}
212+
}
213+
tasks.register("ciSdkManagerLicenses") {
214+
doLast {
215+
val sdkDirPath = getAndroidSdkPath(rootDir = rootDir)
216+
getSdkmanagerFile(rootDir = rootDir)?.let { sdkmanagerFile ->
217+
val yesInputStream = object : InputStream() {
218+
private val yesString = "y\n"
219+
private var counter = 0
220+
override fun read(): Int = yesString[counter % 2].also { counter++ }.code
221+
}
222+
exec {
223+
executable = sdkmanagerFile.absolutePath
224+
args = listOf("--list", "--sdk_root=$sdkDirPath")
225+
println("exec: ${this.commandLine.joinToString(separator = " ")}")
226+
}.apply { println("ExecResult: $this") }
227+
exec {
228+
executable = sdkmanagerFile.absolutePath
229+
args = listOf("--licenses", "--sdk_root=$sdkDirPath")
230+
standardInput = yesInputStream
231+
println("exec: ${this.commandLine.joinToString(separator = " ")}")
232+
}.apply { println("ExecResult: $this") }
233+
}
234+
}
235+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
plugins {
2+
`kotlin-dsl`
3+
}
4+
5+
dependencies {
6+
compileOnly(libs.android.gradle.plugin)
7+
compileOnly(libs.gson)
8+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
dependencyResolutionManagement {
2+
repositories {
3+
google()
4+
mavenCentral()
5+
}
6+
versionCatalogs {
7+
create("libs") {
8+
from(files("../gradle/libs.versions.toml"))
9+
}
10+
}
11+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import com.google.gson.GsonBuilder
2+
import org.gradle.api.Project
3+
import java.io.File
4+
import java.util.Properties
5+
6+
class EmulatorJobsMatrix {
7+
8+
private val gson by lazy {
9+
GsonBuilder()
10+
.disableHtmlEscaping()
11+
.setPrettyPrinting()
12+
.create()
13+
}
14+
15+
fun createMatrixJsonFile(rootProject: Project) {
16+
val matrix = mapOf("gradle_tasks" to getTaskList(rootProject = rootProject))
17+
val jsonText = gson.toJson(matrix)
18+
rootProject.layout.buildDirectory.asFile.get().also { buildDir ->
19+
buildDir.mkdirs()
20+
File(buildDir, "emulator_jobs_matrix.json").writeText(jsonText)
21+
}
22+
}
23+
24+
fun getTaskList(rootProject: Project): List<String> =
25+
rootProject.subprojects.filter { subProject ->
26+
File(subProject.projectDir, "src${File.separator}androidInstrumentedTest").exists()
27+
}.map { subProject ->
28+
"${subProject.path}:gradleManagedDeviceDebugAndroidTest"
29+
}.map { taskName ->
30+
mutableListOf(taskName).also {
31+
it.add("--no-parallel")
32+
it.add("--max-workers=1")
33+
it.add("-Pandroid.testoptions.manageddevices.emulator.gpu=swiftshader_indirect")
34+
it.add("-Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true")
35+
}.also {
36+
if (!true.toString().equals(other = System.getenv("CI"), ignoreCase = true)) {
37+
it.add("--enable-display")
38+
}
39+
}.joinToString(separator = " ")
40+
}.sorted()
41+
}
42+
43+
fun getAndroidSdkPath(rootDir: File): String? =
44+
Properties().apply {
45+
val propertiesFile = File(rootDir, "local.properties")
46+
if (propertiesFile.exists()) {
47+
load(propertiesFile.inputStream())
48+
}
49+
}.getProperty("sdk.dir").let { propertiesSdkDirPath ->
50+
(propertiesSdkDirPath ?: System.getenv("ANDROID_HOME"))
51+
}
52+
53+
fun getSdkmanagerFile(rootDir: File): File? =
54+
getAndroidSdkPath(rootDir = rootDir)?.let { sdkDirPath ->
55+
println("sdkDirPath: $sdkDirPath")
56+
val files = File(sdkDirPath).walk().filter { file ->
57+
file.path.contains("cmdline-tools") && file.path.endsWith("sdkmanager")
58+
}
59+
files.forEach { println("walk: ${it.absolutePath}") }
60+
val sdkmanagerFile = files.firstOrNull()
61+
println("sdkmanagerFile: $sdkmanagerFile")
62+
sdkmanagerFile
63+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import com.android.build.api.dsl.ManagedVirtualDevice
2+
import com.android.build.api.dsl.TestOptions
3+
import org.gradle.kotlin.dsl.create
4+
5+
fun TestOptions.configureTestOptions() {
6+
unitTests {
7+
isIncludeAndroidResources = true
8+
all { test: org.gradle.api.tasks.testing.Test ->
9+
test.testLogging {
10+
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
11+
events = setOf(
12+
org.gradle.api.tasks.testing.logging.TestLogEvent.PASSED,
13+
org.gradle.api.tasks.testing.logging.TestLogEvent.SKIPPED,
14+
org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED,
15+
org.gradle.api.tasks.testing.logging.TestLogEvent.STANDARD_OUT,
16+
org.gradle.api.tasks.testing.logging.TestLogEvent.STANDARD_ERROR,
17+
org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED
18+
)
19+
}
20+
}
21+
}
22+
animationsDisabled = true
23+
emulatorSnapshots {
24+
enableForTestFailures = false
25+
}
26+
managedDevices.devices.create<ManagedVirtualDevice>("gradleManagedDevice") {
27+
device = "Pixel 2"
28+
apiLevel = 34
29+
systemImageSource = "google-atd"
30+
require64Bit = true
31+
}
32+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
plugins {
2+
}

‎firebase-app/build.gradle.kts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ plugins {
1111
id("com.android.library")
1212
kotlin("native.cocoapods")
1313
kotlin("multiplatform")
14+
id("testOptionsConvention")
1415
}
1516

1617
android {
@@ -30,11 +31,7 @@ android {
3031
targetCompatibility = JavaVersion.VERSION_11
3132
}
3233

33-
testOptions {
34-
unitTests.apply {
35-
isIncludeAndroidResources = true
36-
}
37-
}
34+
testOptions.configureTestOptions()
3835
packaging {
3936
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")
4037
resources.pickFirsts.add("META-INF/AL2.0")

‎firebase-auth/build.gradle.kts

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ plugins {
1010
id("com.android.library")
1111
kotlin("multiplatform")
1212
kotlin("native.cocoapods")
13-
//id("com.quittle.android-emulator") version "0.2.0"
13+
id("testOptionsConvention")
1414
}
1515

1616
android {
@@ -30,11 +30,7 @@ android {
3030
targetCompatibility = JavaVersion.VERSION_11
3131
}
3232

33-
testOptions {
34-
unitTests.apply {
35-
isIncludeAndroidResources = true
36-
}
37-
}
33+
testOptions.configureTestOptions()
3834
packaging {
3935
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")
4036
resources.pickFirsts.add("META-INF/AL2.0")
@@ -45,19 +41,6 @@ android {
4541
}
4642
}
4743

48-
// Optional configuration
49-
//androidEmulator {
50-
// emulator {
51-
// name("givlive_emulator")
52-
// sdkVersion(28)
53-
// abi("x86_64")
54-
// includeGoogleApis(true) // Defaults to false
55-
//
56-
// }
57-
// headless(false)
58-
// logEmulatorOutput(false)
59-
//}
60-
6144
val supportIosTarget = project.property("skipIosTarget") != "true"
6245

6346
kotlin {

‎firebase-common-internal/build.gradle.kts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ plugins {
1010
id("com.android.library")
1111
kotlin("multiplatform")
1212
kotlin("plugin.serialization")
13+
id("testOptionsConvention")
1314
}
1415

1516
android {
@@ -28,11 +29,7 @@ android {
2829
targetCompatibility = JavaVersion.VERSION_11
2930
}
3031

31-
testOptions {
32-
unitTests.apply {
33-
isIncludeAndroidResources = true
34-
}
35-
}
32+
testOptions.configureTestOptions()
3633

3734
packaging {
3835
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")

‎firebase-common/build.gradle.kts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ plugins {
1010
id("com.android.library")
1111
kotlin("multiplatform")
1212
kotlin("plugin.serialization")
13+
id("testOptionsConvention")
1314
}
1415

1516
android {
@@ -28,11 +29,7 @@ android {
2829
targetCompatibility = JavaVersion.VERSION_11
2930
}
3031

31-
testOptions {
32-
unitTests.apply {
33-
isIncludeAndroidResources = true
34-
}
35-
}
32+
testOptions.configureTestOptions()
3633

3734
packaging {
3835
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")

‎firebase-config/build.gradle.kts

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ plugins {
1010
id("com.android.library")
1111
kotlin("multiplatform")
1212
kotlin("native.cocoapods")
13-
//id("com.quittle.android-emulator") version "0.2.0"
13+
id("testOptionsConvention")
1414
}
1515

1616
android {
@@ -30,11 +30,7 @@ android {
3030
targetCompatibility = JavaVersion.VERSION_11
3131
}
3232

33-
testOptions {
34-
unitTests.apply {
35-
isIncludeAndroidResources = true
36-
}
37-
}
33+
testOptions.configureTestOptions()
3834
packaging {
3935
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")
4036
resources.pickFirsts.add("META-INF/AL2.0")
@@ -45,19 +41,6 @@ android {
4541
}
4642
}
4743

48-
// Optional configuration
49-
//androidEmulator {
50-
// emulator {
51-
// name("givlive_emulator")
52-
// sdkVersion(28)
53-
// abi("x86_64")
54-
// includeGoogleApis(true) // Defaults to false
55-
//
56-
// }
57-
// headless(false)
58-
// logEmulatorOutput(false)
59-
//}
60-
6144
val supportIosTarget = project.property("skipIosTarget") != "true"
6245

6346
kotlin {

‎firebase-crashlytics/build.gradle.kts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ plugins {
1010
id("com.android.library")
1111
kotlin("multiplatform")
1212
kotlin("native.cocoapods")
13+
id("testOptionsConvention")
1314
}
1415

1516
android {
@@ -30,11 +31,7 @@ android {
3031
targetCompatibility = JavaVersion.VERSION_11
3132
}
3233

33-
testOptions {
34-
unitTests.apply {
35-
isIncludeAndroidResources = true
36-
}
37-
}
34+
testOptions.configureTestOptions()
3835
packaging {
3936
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")
4037
resources.pickFirsts.add("META-INF/AL2.0")

‎firebase-database/build.gradle.kts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ plugins {
1111
kotlin("native.cocoapods")
1212
kotlin("multiplatform")
1313
kotlin("plugin.serialization")
14+
id("testOptionsConvention")
1415
}
1516

1617
repositories {
@@ -35,11 +36,7 @@ android {
3536
targetCompatibility = JavaVersion.VERSION_11
3637
}
3738

38-
testOptions {
39-
unitTests.apply {
40-
isIncludeAndroidResources = true
41-
}
42-
}
39+
testOptions.configureTestOptions()
4340
packaging {
4441
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")
4542
resources.pickFirsts.add("META-INF/AL2.0")

‎firebase-firestore/build.gradle.kts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ plugins {
1111
kotlin("native.cocoapods")
1212
kotlin("multiplatform")
1313
kotlin("plugin.serialization")
14+
id("testOptionsConvention")
1415
}
1516

1617
android {
@@ -31,11 +32,7 @@ android {
3132
targetCompatibility = JavaVersion.VERSION_11
3233
}
3334

34-
testOptions {
35-
unitTests.apply {
36-
isIncludeAndroidResources = true
37-
}
38-
}
35+
testOptions.configureTestOptions()
3936
packaging {
4037
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")
4138
resources.pickFirsts.add("META-INF/AL2.0")

‎firebase-functions/build.gradle.kts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ plugins {
1010
id("com.android.library")
1111
kotlin("native.cocoapods")
1212
kotlin("multiplatform")
13+
id("testOptionsConvention")
1314
}
1415

1516
android {
@@ -29,11 +30,7 @@ android {
2930
targetCompatibility = JavaVersion.VERSION_11
3031
}
3132

32-
testOptions {
33-
unitTests.apply {
34-
isIncludeAndroidResources = true
35-
}
36-
}
33+
testOptions.configureTestOptions()
3734
packaging {
3835
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")
3936
resources.pickFirsts.add("META-INF/AL2.0")

‎firebase-installations/build.gradle.kts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ plugins {
1010
id("com.android.library")
1111
kotlin("native.cocoapods")
1212
kotlin("multiplatform")
13+
id("testOptionsConvention")
1314
}
1415

1516
android {
@@ -29,11 +30,7 @@ android {
2930
targetCompatibility = JavaVersion.VERSION_11
3031
}
3132

32-
testOptions {
33-
unitTests.apply {
34-
isIncludeAndroidResources = true
35-
}
36-
}
33+
testOptions.configureTestOptions()
3734
packaging {
3835
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")
3936
resources.pickFirsts.add("META-INF/AL2.0")

‎firebase-messaging/build.gradle.kts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ plugins {
1010
id("com.android.library")
1111
kotlin("multiplatform")
1212
kotlin("native.cocoapods")
13+
id("testOptionsConvention")
1314
}
1415

1516
android {
@@ -29,11 +30,7 @@ android {
2930
targetCompatibility = JavaVersion.VERSION_11
3031
}
3132

32-
testOptions {
33-
unitTests.apply {
34-
isIncludeAndroidResources = true
35-
}
36-
}
33+
testOptions.configureTestOptions()
3734
packaging {
3835
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")
3936
resources.pickFirsts.add("META-INF/AL2.0")

‎firebase-perf/build.gradle.kts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ plugins {
1010
id("com.android.library")
1111
kotlin("multiplatform")
1212
kotlin("native.cocoapods")
13+
id("testOptionsConvention")
1314
}
1415

1516
android {
@@ -30,11 +31,7 @@ android {
3031
targetCompatibility = JavaVersion.VERSION_11
3132
}
3233

33-
testOptions {
34-
unitTests.apply {
35-
isIncludeAndroidResources = true
36-
}
37-
}
34+
testOptions.configureTestOptions()
3835
packaging {
3936
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")
4037
resources.pickFirsts.add("META-INF/AL2.0")

‎firebase-storage/build.gradle.kts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ plugins {
1010
id("com.android.library")
1111
kotlin("native.cocoapods")
1212
kotlin("multiplatform")
13+
id("testOptionsConvention")
1314
}
1415

1516
android {
@@ -29,11 +30,7 @@ android {
2930
targetCompatibility = JavaVersion.VERSION_11
3031
}
3132

32-
testOptions {
33-
unitTests.apply {
34-
isIncludeAndroidResources = true
35-
}
36-
}
33+
testOptions.configureTestOptions()
3734
packaging {
3835
resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module")
3936
resources.pickFirsts.add("META-INF/AL2.0")

‎gradle/libs.versions.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ androidx-test-runner = "1.5.2"
66
ben-manes-versions = "0.42.0"
77
firebase-bom = "33.0.0"
88
gitlive-firebase-java-sdk = "0.4.3"
9+
gson = "2.11.0"
910
junit = "4.13.2"
1011
kotlin = "1.9.23"
1112
kotlinx-coroutines = "1.7.3"
@@ -15,6 +16,7 @@ settings-language = "1.9"
1516
test-logger-plugin = "3.2.0"
1617

1718
[libraries]
19+
android-gradle-plugin = { module = "com.android.tools.build:gradle", version.ref = "agp" }
1820
androidx-test-core = { module = "androidx.test:core", version.ref = "androidx-test-core" }
1921
androidx-test-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-test-junit" }
2022
androidx-test-runner = { module = "androidx.test:runner", version.ref = "androidx-test-runner" }
@@ -32,6 +34,7 @@ google-firebase-installations-ktx = { module = "com.google.firebase:firebase-ins
3234
google-firebase-messaging = { module = "com.google.firebase:firebase-messaging"}
3335
google-firebase-perf-ktx = { module = "com.google.firebase:firebase-perf-ktx"}
3436
google-firebase-storage = { module = "com.google.firebase:firebase-storage"}
37+
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
3538
junit = { module = "junit:junit", version.ref = "junit" }
3639
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
3740
kotlinx-coroutines-play-services = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-play-services", version.ref = "kotlinx-coroutines" }

‎settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ include(
1717
)
1818

1919
pluginManagement {
20+
includeBuild("convention-plugin-test-option")
2021
repositories {
2122
google()
2223
mavenCentral()

0 commit comments

Comments
 (0)
Please sign in to comment.