Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split tests by modules in Github Actions #558

Merged
merged 1 commit into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 57 additions & 18 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,26 @@ on:
branches: [ master ]

jobs:
jobEmulatorMatrixSetup:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '17'
- name: ktLint
run: ./gradlew lintKotlin
- name: run apiCheck
run: ./gradlew apiCheck
jobMatrixSetup:
runs-on: macos-latest
outputs:
emulator_jobs_matrix: ${{ steps.dataStep.outputs.emulator_jobs_matrix }}
ios_test_jobs_matrix: ${{ steps.dataStep.outputs.ios_test_jobs_matrix }}
js_test_jobs_matrix: ${{ steps.dataStep.outputs.js_test_jobs_matrix }}
jvm_test_jobs_matrix: ${{ steps.dataStep.outputs.jvm_test_jobs_matrix }}
steps:
- uses: actions/checkout@v4
- name: Set up JDK
Expand All @@ -21,15 +37,21 @@ jobs:
java-version: '17'
cache: gradle
- name: Prepare the matrix JSON
run: ./gradlew ciEmulatorJobsMatrixSetup
run: ./gradlew ciJobsMatrixSetup
- id: dataStep
run: echo "emulator_jobs_matrix=$(jq -c . < ./build/emulator_jobs_matrix.json)" >> $GITHUB_OUTPUT
run: |
echo "
emulator_jobs_matrix=$(jq -c . < ./build/emulator_jobs_matrix.json)
ios_test_jobs_matrix=$(jq -c . < ./build/ios_test_jobs_matrix.json)
js_test_jobs_matrix=$(jq -c . < ./build/js_test_jobs_matrix.json)
jvm_test_jobs_matrix=$(jq -c . < ./build/jvm_test_jobs_matrix.json)
" >> $GITHUB_OUTPUT
build-android:
needs: jobEmulatorMatrixSetup
needs: jobMatrixSetup
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.jobEmulatorMatrixSetup.outputs.emulator_jobs_matrix) }}
matrix: ${{ fromJson(needs.jobMatrixSetup.outputs.emulator_jobs_matrix) }}
steps:
- uses: actions/checkout@v4
- name: Enable KVM group perms
Expand Down Expand Up @@ -59,19 +81,26 @@ jobs:
name: Android ${{ env.ARCHIVE_KEY }} Firebase Debug Log
path: "**/firebase-debug.log"
build-js:
needs: jobMatrixSetup
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.jobMatrixSetup.outputs.js_test_jobs_matrix) }}
steps:
- uses: actions/checkout@v4
- name: Setup test environment
uses: ./.github/actions/setup_test_action
timeout-minutes: 10
- name: Set Artifact Name
run: |
echo "ARCHIVE_KEY=$(echo ${{ matrix.gradle_tasks }} | cut -d: -f2)" >> $GITHUB_ENV
- name: Run JS Tests
run: ./gradlew cleanTest jsTest
run: ./gradlew ${{ matrix.gradle_tasks }}
- name: Upload JS test artifact
uses: actions/upload-artifact@v4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All artifacts should have a unique name, so it should derive the name of the artifact from the gradle task. E.g "JS firebase-firestore Firebase Debug Log"

if: failure()
with:
name: "JS Test Report HTML"
name: JS ${{ env.ARCHIVE_KEY }} Test Report HTML
path: |
**/build/reports/tests/jsTest/
**/build/reports/tests/jsBrowserTest/
Expand All @@ -80,10 +109,14 @@ jobs:
uses: actions/upload-artifact@v4
if: failure()
with:
name: "JS Firebase Debug Log"
name: JS ${{ env.ARCHIVE_KEY }} Firebase Debug Log
path: "**/firebase-debug.log"
build-ios:
needs: jobMatrixSetup
runs-on: macos-latest
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.jobMatrixSetup.outputs.ios_test_jobs_matrix) }}
steps:
- uses: actions/checkout@v4
- name: Cocoapods cache
Expand All @@ -97,43 +130,49 @@ jobs:
key: cocoapods-cache-v2
- name: Setup test environment
uses: ./.github/actions/setup_test_action
- name: ktLint
run: ./gradlew lintKotlin
- name: Set Artifact Name
run: |
echo "ARCHIVE_KEY=$(echo ${{ matrix.gradle_tasks }} | cut -d: -f2)" >> $GITHUB_ENV
- name: Run iOS Tests
run: ./gradlew cleanTest iosSimulatorArm64Test
run: ./gradlew ${{ matrix.gradle_tasks }}
- name: Upload iOS test artifact
uses: actions/upload-artifact@v4
if: failure()
with:
name: "iOS Test Report HTML"
name: iOS ${{ env.ARCHIVE_KEY }} Test Report HTML
path: "**/build/reports/tests/iosSimulatorArm64Test/"
- name: Upload Firebase Debug Log
uses: actions/upload-artifact@v4
if: failure()
with:
name: "iOS Firebase Debug Log"
name: iOS ${{ env.ARCHIVE_KEY }} Firebase Debug Log
path: "**/firebase-debug.log"
build-jvm:
needs: jobMatrixSetup
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.jobMatrixSetup.outputs.jvm_test_jobs_matrix) }}
steps:
- uses: actions/checkout@v4
- name: Setup test environment
uses: ./.github/actions/setup_test_action
timeout-minutes: 10
- name: run apiCheck
run: ./gradlew apiCheck
- name: Set Artifact Name
run: |
echo "ARCHIVE_KEY=$(echo ${{ matrix.gradle_tasks }} | cut -d: -f2)" >> $GITHUB_ENV
- name: Run JVM Tests
run: ./gradlew cleanTest jvmTest
run: ./gradlew ${{ matrix.gradle_tasks }}
- name: Upload JVM test artifact
uses: actions/upload-artifact@v4
if: failure()
with:
name: "JVM Test Report HTML"
name: JVM ${{ env.ARCHIVE_KEY }} Test Report HTML
path: |
**/build/reports/tests/jvmTest/
- name: Upload Firebase Debug Log
uses: actions/upload-artifact@v4
if: failure()
with:
name: "JVM Firebase Debug Log"
name: JVM ${{ env.ARCHIVE_KEY }} Firebase Debug Log
path: "**/firebase-debug.log"
18 changes: 12 additions & 6 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ tasks {
"firebase-database:updateVersion", "firebase-database:updateDependencyVersion",
"firebase-firestore:updateVersion", "firebase-firestore:updateDependencyVersion",
"firebase-functions:updateVersion", "firebase-functions:updateDependencyVersion",
"firebase-messaging:updateVersion", "firebase-messaging:updateDependencyVersion",
"firebase-installations:updateVersion", "firebase-installations:updateDependencyVersion",
"firebase-messaging:updateVersion", "firebase-messaging:updateDependencyVersion",
"firebase-perf:updateVersion", "firebase-perf:updateDependencyVersion",
"firebase-storage:updateVersion", "firebase-storage:updateDependencyVersion"
)
Expand Down Expand Up @@ -271,26 +271,32 @@ tasks.withType<com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask
}
// check for latest dependencies - ./gradlew dependencyUpdates -Drevision=release

tasks.register("devRunEmulatorTests") {
tasks.register("devRunAllTests") {
doLast {
EmulatorJobsMatrix().getTaskList(rootProject = rootProject).forEach { gradleTasks ->
val gradleTasks = mutableListOf<List<String>>()
gradleTasks.addAll(EmulatorJobsMatrix().getJvmTestTaskList(rootProject = rootProject))
gradleTasks.addAll(EmulatorJobsMatrix().getJsTestTaskList(rootProject = rootProject))
gradleTasks.addAll(EmulatorJobsMatrix().getIosTestTaskList(rootProject = rootProject))
gradleTasks.add(listOf("ciSdkManagerLicenses"))
gradleTasks.addAll(EmulatorJobsMatrix().getEmulatorTaskList(rootProject = rootProject))
gradleTasks.forEach {
exec {
executable = File(
project.rootDir,
if (Os.isFamily(Os.FAMILY_WINDOWS)) "gradlew.bat" else "gradlew",
)
.also { it.setExecutable(true) }
.absolutePath
args = gradleTasks
args = it
println("exec: ${this.commandLine.joinToString(separator = " ")}")
}.apply { println("ExecResult: $this") }
}
}
}

tasks.register("ciEmulatorJobsMatrixSetup") {
tasks.register("ciJobsMatrixSetup") {
doLast {
EmulatorJobsMatrix().createMatrixJsonFile(rootProject = rootProject)
EmulatorJobsMatrix().createMatrixJsonFiles(rootProject = rootProject)
}
}

Expand Down
63 changes: 53 additions & 10 deletions convention-plugin-test-option/src/main/kotlin/EmulatorJobsMatrix.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,62 @@ class EmulatorJobsMatrix {
.create()
}

fun createMatrixJsonFile(rootProject: Project) {
val taskList = getTaskList(rootProject = rootProject).map { it.joinToString(separator = " ") }
val matrix = mapOf("gradle_tasks" to taskList)
val jsonText = gson.toJson(matrix)
rootProject.layout.buildDirectory.asFile.get().also { buildDir ->
buildDir.mkdirs()
File(buildDir, "emulator_jobs_matrix.json").writeText(jsonText)
}
fun createMatrixJsonFiles(rootProject: Project) {
mapOf(
"emulator_jobs_matrix.json" to getEmulatorTaskList(rootProject = rootProject),
"ios_test_jobs_matrix.json" to getIosTestTaskList(rootProject = rootProject),
"js_test_jobs_matrix.json" to getJsTestTaskList(rootProject = rootProject),
"jvm_test_jobs_matrix.json" to getJvmTestTaskList(rootProject = rootProject)
)
.mapValues { entry -> entry.value.map { it.joinToString(separator = " ") } }
.forEach { (fileName: String, taskList: List<String>) ->
val matrix = mapOf("gradle_tasks" to taskList)
val jsonText = gson.toJson(matrix)
rootProject.layout.buildDirectory.asFile.get().also { buildDir ->
buildDir.mkdirs()
File(buildDir, fileName).writeText(jsonText)
}
}
}

fun getTaskList(rootProject: Project): List<List<String>> =
fun getIosTestTaskList(rootProject: Project): List<List<String>> =
rootProject.subprojects.filter { subProject ->
subProject.name == "test-utils" ||
(rootProject.property("${subProject.name}.skipIosTests") == "true").not()
}.map { subProject ->
when (val osArch = System.getProperty("os.arch")) {
"x86", "i386", "ia-32", "i686" -> "${subProject.path}:iosX86Test"
"x86_64", "amd64", "x64", "x86-64" -> "${subProject.path}:iosX64Test"
"arm", "arm-v7", "armv7", "arm32",
"arm64", "arm-v8", "aarch64" -> "${subProject.path}:iosSimulatorArm64Test"

else -> throw Error("Unexpected System.getProperty(\"os.arch\") = $osArch")
}
}.map { listOf("cleanTest", it) }

fun getJsTestTaskList(rootProject: Project): List<List<String>> =
rootProject.subprojects.filter { subProject ->
subProject.name == "test-utils" ||
(rootProject.property("${subProject.name}.skipJsTests") == "true").not()
}.map { subProject ->
"${subProject.path}:jsTest"
}.map { listOf("cleanTest", it) }

fun getJvmTestTaskList(rootProject: Project): List<List<String>> =
rootProject.subprojects.filter { subProject ->
subProject.name == "test-utils" ||
(rootProject.property("${subProject.name}.skipJvmTests") == "true").not()
}.map { subProject ->
"${subProject.path}:jvmTest"
}.map { listOf("cleanTest", it) }

fun getEmulatorTaskList(rootProject: Project): List<List<String>> =
rootProject.subprojects.filter { subProject ->
File(subProject.projectDir, "src${File.separator}androidInstrumentedTest").exists()
File(subProject.projectDir, "src${File.separator}commonTest").exists() ||
File(
subProject.projectDir,
"src${File.separator}androidInstrumentedTest"
).exists()
}.map { subProject ->
"${subProject.path}:gradleManagedDeviceDebugAndroidTest"
}.map { taskName ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

@file:JvmName("tests")

package dev.gitlive.firebase.analytics

import dev.gitlive.firebase.testContext
Expand Down
12 changes: 12 additions & 0 deletions firebase-crashlytics/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,18 @@ if (project.property("firebase-crashlytics.skipIosTests") == "true") {
}
}

if (project.property("firebase-crashlytics.skipJvmTests") == "true") {
tasks.forEach {
if (it.name.contains("jvm", true) && it.name.contains("test", true)) { it.enabled = false }
}
}

if (project.property("firebase-crashlytics.skipJsTests") == "true") {
tasks.forEach {
if (it.name.contains("js", true) && it.name.contains("test", true)) { it.enabled = false }
}
}

signing {
val signingKey: String? by project
val signingPassword: String? by project
Expand Down
5 changes: 0 additions & 5 deletions firebase-database/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ plugins {
id("testOptionsConvention")
}

repositories {
google()
mavenCentral()
}

android {
val minSdkVersion: Int by project
val compileSdkVersion: Int by project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ package dev.gitlive.firebase.storage

actual fun createTestData(): Data {
TODO("Not yet implemented")
}
}
Loading
Loading