diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 11004c8f3..3a8becf60 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -9,12 +9,17 @@ on: jobs: build-android: - runs-on: macos-13 + runs-on: ubuntu-latest strategy: matrix: api-level: [ 34 ] steps: - uses: actions/checkout@v3 + - name: Enable KVM group perms + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm - name: Setup test environment uses: ./.github/actions/setup_test_action - name: AVD cache @@ -25,29 +30,8 @@ jobs: ~/.android/avd/* ~/.android/adb* key: avd-${{ matrix.api-level }}-${{ runner.os }}-${{ runner.arch }} - - name: create AVD and generate snapshot for caching - if: steps.avd-cache.outputs.cache-hit != 'true' - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ matrix.api-level }} - arch: x86_64 - target: google_apis - avd-name: pixel6_API${{ matrix.api-level }} - force-avd-creation: false - emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: false - script: echo "Generated AVD snapshot for caching." - name: Run Android Instrumented Tests - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ matrix.api-level }} - arch: x86_64 - target: google_apis - avd-name: pixel6_API${{ matrix.api-level }} - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: true - script: ./gradlew connectedAndroidTest + run: ./gradlew gradleManagedDeviceDebugAndroidTest - name: Upload Android test artifact uses: actions/upload-artifact@v3 if: failure() diff --git a/.gitignore b/.gitignore index adbab484d..4feaf670b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # Project exclude paths -/.gradle/ +/**/.gradle/ /**/build/ /.idea/ local.properties diff --git a/convention-plugin-test-option/build.gradle.kts b/convention-plugin-test-option/build.gradle.kts new file mode 100644 index 000000000..0a8de4623 --- /dev/null +++ b/convention-plugin-test-option/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + `kotlin-dsl` +} + +dependencies { + compileOnly(libs.android.gradle.plugin) +} diff --git a/convention-plugin-test-option/settings.gradle.kts b/convention-plugin-test-option/settings.gradle.kts new file mode 100644 index 000000000..20b0bdf67 --- /dev/null +++ b/convention-plugin-test-option/settings.gradle.kts @@ -0,0 +1,19 @@ +pluginManagement { + repositories { + google() + gradlePluginPortal() + mavenCentral() + } +} + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + } + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} diff --git a/convention-plugin-test-option/src/main/kotlin/TestOptionsConfig.kt b/convention-plugin-test-option/src/main/kotlin/TestOptionsConfig.kt new file mode 100644 index 000000000..8632437ff --- /dev/null +++ b/convention-plugin-test-option/src/main/kotlin/TestOptionsConfig.kt @@ -0,0 +1,31 @@ +import com.android.build.api.dsl.ManagedVirtualDevice +import com.android.build.api.dsl.TestOptions +import org.gradle.kotlin.dsl.create + +fun TestOptions.configureTestOptions() { + unitTests { + isIncludeAndroidResources = true + all { test: org.gradle.api.tasks.testing.Test -> + test.testLogging { + exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL + events = setOf( + org.gradle.api.tasks.testing.logging.TestLogEvent.PASSED, + org.gradle.api.tasks.testing.logging.TestLogEvent.SKIPPED, + org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED, + org.gradle.api.tasks.testing.logging.TestLogEvent.STANDARD_OUT, + org.gradle.api.tasks.testing.logging.TestLogEvent.STANDARD_ERROR, + org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED + ) + } + } + } + animationsDisabled = true + emulatorSnapshots { + enableForTestFailures = false + } + managedDevices.devices.create("gradleManagedDevice") { + device = "Pixel 2" + apiLevel = 33 + systemImageSource = "google-atd" + } +} diff --git a/convention-plugin-test-option/src/main/kotlin/testOptionsConvention.gradle.kts b/convention-plugin-test-option/src/main/kotlin/testOptionsConvention.gradle.kts new file mode 100644 index 000000000..4f298e665 --- /dev/null +++ b/convention-plugin-test-option/src/main/kotlin/testOptionsConvention.gradle.kts @@ -0,0 +1,2 @@ +plugins { +} diff --git a/firebase-app/build.gradle.kts b/firebase-app/build.gradle.kts index 0a4a68f8a..a4454500d 100644 --- a/firebase-app/build.gradle.kts +++ b/firebase-app/build.gradle.kts @@ -1,4 +1,3 @@ -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree /* @@ -11,6 +10,7 @@ plugins { id("com.android.library") kotlin("native.cocoapods") kotlin("multiplatform") + id("testOptionsConvention") } android { @@ -30,11 +30,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") resources.pickFirsts.add("META-INF/AL2.0") diff --git a/firebase-auth/build.gradle.kts b/firebase-auth/build.gradle.kts index 83dd8d287..4e897b973 100644 --- a/firebase-auth/build.gradle.kts +++ b/firebase-auth/build.gradle.kts @@ -10,7 +10,7 @@ plugins { id("com.android.library") kotlin("multiplatform") kotlin("native.cocoapods") - //id("com.quittle.android-emulator") version "0.2.0" + id("testOptionsConvention") } android { @@ -30,11 +30,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") resources.pickFirsts.add("META-INF/AL2.0") @@ -45,19 +41,6 @@ android { } } -// Optional configuration -//androidEmulator { -// emulator { -// name("givlive_emulator") -// sdkVersion(28) -// abi("x86_64") -// includeGoogleApis(true) // Defaults to false -// -// } -// headless(false) -// logEmulatorOutput(false) -//} - val supportIosTarget = project.property("skipIosTarget") != "true" kotlin { diff --git a/firebase-common-internal/build.gradle.kts b/firebase-common-internal/build.gradle.kts index d92abf29a..1f2f0d714 100644 --- a/firebase-common-internal/build.gradle.kts +++ b/firebase-common-internal/build.gradle.kts @@ -10,6 +10,7 @@ plugins { id("com.android.library") kotlin("multiplatform") kotlin("plugin.serialization") + id("testOptionsConvention") } android { @@ -28,11 +29,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") diff --git a/firebase-common/build.gradle.kts b/firebase-common/build.gradle.kts index 329b42905..5531ada19 100644 --- a/firebase-common/build.gradle.kts +++ b/firebase-common/build.gradle.kts @@ -10,6 +10,7 @@ plugins { id("com.android.library") kotlin("multiplatform") kotlin("plugin.serialization") + id("testOptionsConvention") } android { @@ -28,11 +29,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") diff --git a/firebase-config/build.gradle.kts b/firebase-config/build.gradle.kts index 5d60db729..e9e896237 100644 --- a/firebase-config/build.gradle.kts +++ b/firebase-config/build.gradle.kts @@ -10,7 +10,7 @@ plugins { id("com.android.library") kotlin("multiplatform") kotlin("native.cocoapods") - //id("com.quittle.android-emulator") version "0.2.0" + id("testOptionsConvention") } android { @@ -30,11 +30,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") resources.pickFirsts.add("META-INF/AL2.0") @@ -45,19 +41,6 @@ android { } } -// Optional configuration -//androidEmulator { -// emulator { -// name("givlive_emulator") -// sdkVersion(28) -// abi("x86_64") -// includeGoogleApis(true) // Defaults to false -// -// } -// headless(false) -// logEmulatorOutput(false) -//} - val supportIosTarget = project.property("skipIosTarget") != "true" kotlin { diff --git a/firebase-crashlytics/build.gradle.kts b/firebase-crashlytics/build.gradle.kts index b218d27f2..6a3e503a6 100644 --- a/firebase-crashlytics/build.gradle.kts +++ b/firebase-crashlytics/build.gradle.kts @@ -10,6 +10,7 @@ plugins { id("com.android.library") kotlin("multiplatform") kotlin("native.cocoapods") + id("testOptionsConvention") } android { @@ -30,11 +31,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") resources.pickFirsts.add("META-INF/AL2.0") diff --git a/firebase-crashlytics/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/crashlytics/crashlytics.kt b/firebase-crashlytics/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/crashlytics/crashlytics.kt index aa0ff306f..9049d1d7a 100644 --- a/firebase-crashlytics/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/crashlytics/crashlytics.kt +++ b/firebase-crashlytics/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/crashlytics/crashlytics.kt @@ -1,3 +1,4 @@ + /* * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. */ diff --git a/firebase-database/build.gradle.kts b/firebase-database/build.gradle.kts index 26e7f4dd1..2c67ef315 100644 --- a/firebase-database/build.gradle.kts +++ b/firebase-database/build.gradle.kts @@ -11,6 +11,7 @@ plugins { kotlin("native.cocoapods") kotlin("multiplatform") kotlin("plugin.serialization") + id("testOptionsConvention") } repositories { @@ -35,11 +36,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") resources.pickFirsts.add("META-INF/AL2.0") diff --git a/firebase-firestore/build.gradle.kts b/firebase-firestore/build.gradle.kts index c5f769786..1f01fb95d 100644 --- a/firebase-firestore/build.gradle.kts +++ b/firebase-firestore/build.gradle.kts @@ -11,6 +11,7 @@ plugins { kotlin("native.cocoapods") kotlin("multiplatform") kotlin("plugin.serialization") + id("testOptionsConvention") } android { @@ -31,11 +32,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") resources.pickFirsts.add("META-INF/AL2.0") diff --git a/firebase-functions/build.gradle.kts b/firebase-functions/build.gradle.kts index a3c8309a9..b148115c2 100644 --- a/firebase-functions/build.gradle.kts +++ b/firebase-functions/build.gradle.kts @@ -10,6 +10,7 @@ plugins { id("com.android.library") kotlin("native.cocoapods") kotlin("multiplatform") + id("testOptionsConvention") } android { @@ -29,11 +30,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") resources.pickFirsts.add("META-INF/AL2.0") diff --git a/firebase-installations/build.gradle.kts b/firebase-installations/build.gradle.kts index 66ed3e5e6..c731db721 100644 --- a/firebase-installations/build.gradle.kts +++ b/firebase-installations/build.gradle.kts @@ -10,6 +10,7 @@ plugins { id("com.android.library") kotlin("native.cocoapods") kotlin("multiplatform") + id("testOptionsConvention") } android { @@ -29,11 +30,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") resources.pickFirsts.add("META-INF/AL2.0") diff --git a/firebase-messaging/build.gradle.kts b/firebase-messaging/build.gradle.kts index ce13c9fc0..2257ba918 100644 --- a/firebase-messaging/build.gradle.kts +++ b/firebase-messaging/build.gradle.kts @@ -10,6 +10,7 @@ plugins { id("com.android.library") kotlin("multiplatform") kotlin("native.cocoapods") + id("testOptionsConvention") } android { @@ -29,11 +30,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") resources.pickFirsts.add("META-INF/AL2.0") diff --git a/firebase-perf/build.gradle.kts b/firebase-perf/build.gradle.kts index 357208b00..874041c85 100644 --- a/firebase-perf/build.gradle.kts +++ b/firebase-perf/build.gradle.kts @@ -10,6 +10,7 @@ plugins { id("com.android.library") kotlin("multiplatform") kotlin("native.cocoapods") + id("testOptionsConvention") } android { @@ -30,11 +31,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") resources.pickFirsts.add("META-INF/AL2.0") diff --git a/firebase-storage/build.gradle.kts b/firebase-storage/build.gradle.kts index 450e15bd3..a8048aa14 100644 --- a/firebase-storage/build.gradle.kts +++ b/firebase-storage/build.gradle.kts @@ -10,6 +10,7 @@ plugins { id("com.android.library") kotlin("native.cocoapods") kotlin("multiplatform") + id("testOptionsConvention") } android { @@ -29,11 +30,7 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - } - } + testOptions.configureTestOptions() packaging { resources.pickFirsts.add("META-INF/kotlinx-serialization-core.kotlin_module") resources.pickFirsts.add("META-INF/AL2.0") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9fb634421..9f2f30add 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,7 @@ settings-language = "1.9" test-logger-plugin = "3.2.0" [libraries] +android-gradle-plugin = { module = "com.android.tools.build:gradle", version.ref = "agp" } androidx-test-core = { module = "androidx.test:core", version.ref = "androidx-test-core" } androidx-test-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-test-junit" } androidx-test-runner = { module = "androidx.test:runner", version.ref = "androidx-test-runner" } diff --git a/settings.gradle.kts b/settings.gradle.kts index 0ae283968..d81db266c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,6 +16,7 @@ include( ) pluginManagement { + includeBuild("convention-plugin-test-option") repositories { google() mavenCentral()