Skip to content

Commit ac94eab

Browse files
Split tests by modules in Github Actions
1 parent 5b0c17b commit ac94eab

File tree

20 files changed

+110
-322
lines changed

20 files changed

+110
-322
lines changed

.github/workflows/pull_request.yml

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,26 @@ on:
88
branches: [ master ]
99

1010
jobs:
11-
jobEmulatorMatrixSetup:
11+
lint:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- name: Set up JDK
16+
uses: actions/setup-java@v4
17+
with:
18+
distribution: 'zulu'
19+
java-version: '17'
20+
- name: ktLint
21+
run: ./gradlew lintKotlin
22+
- name: run apiCheck
23+
run: ./gradlew apiCheck
24+
jobMatrixSetup:
1225
runs-on: ubuntu-latest
1326
outputs:
1427
emulator_jobs_matrix: ${{ steps.dataStep.outputs.emulator_jobs_matrix }}
28+
ios_test_jobs_matrix: ${{ steps.dataStep.outputs.ios_test_jobs_matrix }}
29+
js_test_jobs_matrix: ${{ steps.dataStep.outputs.js_test_jobs_matrix }}
30+
jvm_test_jobs_matrix: ${{ steps.dataStep.outputs.jvm_test_jobs_matrix }}
1531
steps:
1632
- uses: actions/checkout@v4
1733
- name: Set up JDK
@@ -21,15 +37,21 @@ jobs:
2137
java-version: '17'
2238
cache: gradle
2339
- name: Prepare the matrix JSON
24-
run: ./gradlew ciEmulatorJobsMatrixSetup
40+
run: ./gradlew ciJobsMatrixSetup
2541
- id: dataStep
26-
run: echo "emulator_jobs_matrix=$(jq -c . < ./build/emulator_jobs_matrix.json)" >> $GITHUB_OUTPUT
42+
run: |
43+
echo "
44+
emulator_jobs_matrix=$(jq -c . < ./build/emulator_jobs_matrix.json)
45+
ios_test_jobs_matrix=$(jq -c . < ./build/ios_test_jobs_matrix.json)
46+
js_test_jobs_matrix=$(jq -c . < ./build/js_test_jobs_matrix.json)
47+
jvm_test_jobs_matrix=$(jq -c . < ./build/jvm_test_jobs_matrix.json)
48+
" >> $GITHUB_OUTPUT
2749
build-android:
28-
needs: jobEmulatorMatrixSetup
50+
needs: jobMatrixSetup
2951
runs-on: ubuntu-latest
3052
strategy:
3153
fail-fast: false
32-
matrix: ${{ fromJson(needs.jobEmulatorMatrixSetup.outputs.emulator_jobs_matrix) }}
54+
matrix: ${{ fromJson(needs.jobMatrixSetup.outputs.emulator_jobs_matrix) }}
3355
steps:
3456
- uses: actions/checkout@v4
3557
- name: Enable KVM group perms
@@ -59,14 +81,18 @@ jobs:
5981
name: Android ${{ env.ARCHIVE_KEY }} Firebase Debug Log
6082
path: "**/firebase-debug.log"
6183
build-js:
84+
needs: jobMatrixSetup
6285
runs-on: ubuntu-latest
86+
strategy:
87+
fail-fast: false
88+
matrix: ${{ fromJson(needs.jobMatrixSetup.outputs.js_test_jobs_matrix) }}
6389
steps:
6490
- uses: actions/checkout@v4
6591
- name: Setup test environment
6692
uses: ./.github/actions/setup_test_action
6793
timeout-minutes: 10
6894
- name: Run JS Tests
69-
run: ./gradlew cleanTest jsTest
95+
run: ./gradlew ${{ matrix.gradle_tasks }}
7096
- name: Upload JS test artifact
7197
uses: actions/upload-artifact@v4
7298
if: failure()
@@ -83,7 +109,11 @@ jobs:
83109
name: "JS Firebase Debug Log"
84110
path: "**/firebase-debug.log"
85111
build-ios:
112+
needs: jobMatrixSetup
86113
runs-on: macos-latest
114+
strategy:
115+
fail-fast: false
116+
matrix: ${{ fromJson(needs.jobMatrixSetup.outputs.ios_test_jobs_matrix) }}
87117
steps:
88118
- uses: actions/checkout@v4
89119
- name: Cocoapods cache
@@ -97,10 +127,8 @@ jobs:
97127
key: cocoapods-cache-v2
98128
- name: Setup test environment
99129
uses: ./.github/actions/setup_test_action
100-
- name: ktLint
101-
run: ./gradlew lintKotlin
102130
- name: Run iOS Tests
103-
run: ./gradlew cleanTest iosSimulatorArm64Test
131+
run: ./gradlew ${{ matrix.gradle_tasks }}
104132
- name: Upload iOS test artifact
105133
uses: actions/upload-artifact@v4
106134
if: failure()
@@ -114,16 +142,18 @@ jobs:
114142
name: "iOS Firebase Debug Log"
115143
path: "**/firebase-debug.log"
116144
build-jvm:
145+
needs: jobMatrixSetup
117146
runs-on: ubuntu-latest
147+
strategy:
148+
fail-fast: false
149+
matrix: ${{ fromJson(needs.jobMatrixSetup.outputs.jvm_test_jobs_matrix) }}
118150
steps:
119151
- uses: actions/checkout@v4
120152
- name: Setup test environment
121153
uses: ./.github/actions/setup_test_action
122154
timeout-minutes: 10
123-
- name: run apiCheck
124-
run: ./gradlew apiCheck
125155
- name: Run JVM Tests
126-
run: ./gradlew cleanTest jvmTest
156+
run: ./gradlew ${{ matrix.gradle_tasks }}
127157
- name: Upload JVM test artifact
128158
uses: actions/upload-artifact@v4
129159
if: failure()

build.gradle.kts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ tasks {
4343
"firebase-database:updateVersion", "firebase-database:updateDependencyVersion",
4444
"firebase-firestore:updateVersion", "firebase-firestore:updateDependencyVersion",
4545
"firebase-functions:updateVersion", "firebase-functions:updateDependencyVersion",
46-
"firebase-messaging:updateVersion", "firebase-messaging:updateDependencyVersion",
4746
"firebase-installations:updateVersion", "firebase-installations:updateDependencyVersion",
47+
"firebase-messaging:updateVersion", "firebase-messaging:updateDependencyVersion",
4848
"firebase-perf:updateVersion", "firebase-perf:updateDependencyVersion",
4949
"firebase-storage:updateVersion", "firebase-storage:updateDependencyVersion"
5050
)
@@ -271,26 +271,32 @@ tasks.withType<com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask
271271
}
272272
// check for latest dependencies - ./gradlew dependencyUpdates -Drevision=release
273273

274-
tasks.register("devRunEmulatorTests") {
274+
tasks.register("devRunAllTests") {
275275
doLast {
276-
EmulatorJobsMatrix().getTaskList(rootProject = rootProject).forEach { gradleTasks ->
276+
val gradleTasks = mutableListOf<List<String>>()
277+
gradleTasks.addAll(EmulatorJobsMatrix().getJvmTestTaskList(rootProject = rootProject))
278+
gradleTasks.addAll(EmulatorJobsMatrix().getJsTestTaskList(rootProject = rootProject))
279+
gradleTasks.addAll(EmulatorJobsMatrix().getIosTestTaskList(rootProject = rootProject))
280+
gradleTasks.add(listOf("ciSdkManagerLicenses"))
281+
gradleTasks.addAll(EmulatorJobsMatrix().getEmulatorTaskList(rootProject = rootProject))
282+
gradleTasks.forEach {
277283
exec {
278284
executable = File(
279285
project.rootDir,
280286
if (Os.isFamily(Os.FAMILY_WINDOWS)) "gradlew.bat" else "gradlew",
281287
)
282288
.also { it.setExecutable(true) }
283289
.absolutePath
284-
args = gradleTasks
290+
args = it
285291
println("exec: ${this.commandLine.joinToString(separator = " ")}")
286292
}.apply { println("ExecResult: $this") }
287293
}
288294
}
289295
}
290296

291-
tasks.register("ciEmulatorJobsMatrixSetup") {
297+
tasks.register("ciJobsMatrixSetup") {
292298
doLast {
293-
EmulatorJobsMatrix().createMatrixJsonFile(rootProject = rootProject)
299+
EmulatorJobsMatrix().createMatrixJsonFiles(rootProject = rootProject)
294300
}
295301
}
296302

convention-plugin-test-option/src/main/kotlin/EmulatorJobsMatrix.kt

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,63 @@ class EmulatorJobsMatrix {
1212
.create()
1313
}
1414

15-
fun createMatrixJsonFile(rootProject: Project) {
16-
val taskList = getTaskList(rootProject = rootProject).map { it.joinToString(separator = " ") }
17-
val matrix = mapOf("gradle_tasks" to taskList)
18-
val jsonText = gson.toJson(matrix)
19-
rootProject.layout.buildDirectory.asFile.get().also { buildDir ->
20-
buildDir.mkdirs()
21-
File(buildDir, "emulator_jobs_matrix.json").writeText(jsonText)
22-
}
15+
fun createMatrixJsonFiles(rootProject: Project) {
16+
mapOf(
17+
"emulator_jobs_matrix.json" to getEmulatorTaskList(rootProject = rootProject),
18+
"ios_test_jobs_matrix.json" to getIosTestTaskList(rootProject = rootProject),
19+
"js_test_jobs_matrix.json" to getJsTestTaskList(rootProject = rootProject),
20+
"jvm_test_jobs_matrix.json" to getJvmTestTaskList(rootProject = rootProject)
21+
)
22+
.mapValues { entry -> entry.value.map { it.joinToString(separator = " ") } }
23+
.forEach { (fileName: String, taskList: List<String>) ->
24+
val matrix = mapOf("gradle_tasks" to taskList)
25+
val jsonText = gson.toJson(matrix)
26+
rootProject.layout.buildDirectory.asFile.get().also { buildDir ->
27+
buildDir.mkdirs()
28+
File(buildDir, fileName).writeText(jsonText)
29+
}
30+
}
2331
}
2432

25-
fun getTaskList(rootProject: Project): List<List<String>> =
33+
fun getIosTestTaskList(rootProject: Project): List<List<String>> =
34+
rootProject.subprojects.filter { subProject ->
35+
listOf(
36+
"firebase-analytics"
37+
).contains(subProject.name).not()
38+
}.map { subProject ->
39+
"${subProject.path}:iosSimulatorArm64Test"
40+
}.map { listOf("cleanTest", it) }
41+
42+
fun getJsTestTaskList(rootProject: Project): List<List<String>> =
43+
rootProject.subprojects.filter { subProject ->
44+
listOf(
45+
"firebase-crashlytics"
46+
).contains(subProject.name).not()
47+
}.map { subProject ->
48+
"${subProject.path}:jsTest"
49+
}.map { listOf("cleanTest", it) }
50+
51+
fun getJvmTestTaskList(rootProject: Project): List<List<String>> =
52+
rootProject.subprojects.filter { subProject ->
53+
listOf(
54+
"firebase-analytics",
55+
"firebase-auth",
56+
"firebase-config",
57+
"firebase-crashlytics",
58+
"firebase-perf",
59+
"firebase-storage"
60+
).contains(subProject.name).not()
61+
}.map { subProject ->
62+
"${subProject.path}:jvmTest"
63+
}.map { listOf("cleanTest", it) }
64+
65+
fun getEmulatorTaskList(rootProject: Project): List<List<String>> =
2666
rootProject.subprojects.filter { subProject ->
27-
File(subProject.projectDir, "src${File.separator}androidInstrumentedTest").exists()
67+
File(subProject.projectDir, "src${File.separator}commonTest").exists() ||
68+
File(
69+
subProject.projectDir,
70+
"src${File.separator}androidInstrumentedTest"
71+
).exists()
2872
}.map { subProject ->
2973
"${subProject.path}:gradleManagedDeviceDebugAndroidTest"
3074
}.map { taskName ->

firebase-analytics/build.gradle.kts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -143,24 +143,6 @@ kotlin {
143143
}
144144
}
145145

146-
if (project.property("firebase-analytics.skipIosTests") == "true") {
147-
tasks.forEach {
148-
if (it.name.contains("ios", true) && it.name.contains("test", true)) { it.enabled = false }
149-
}
150-
}
151-
152-
if (project.property("firebase-analytics.skipJvmTests") == "true") {
153-
tasks.forEach {
154-
if (it.name.contains("jvm", true) && it.name.contains("test", true)) { it.enabled = false }
155-
}
156-
}
157-
158-
if (project.property("firebase-analytics.skipJsTests") == "true") {
159-
tasks.forEach {
160-
if (it.name.contains("js", true) && it.name.contains("test", true)) { it.enabled = false }
161-
}
162-
}
163-
164146
signing {
165147
val signingKey: String? by project
166148
val signingPassword: String? by project

firebase-analytics/src/jvmTest/kotlin/dev/gitlive/firebase/analytics/analytics.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
@file:JvmName("tests")
6+
67
package dev.gitlive.firebase.analytics
78

89
import dev.gitlive.firebase.testContext

firebase-app/build.gradle.kts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -146,24 +146,6 @@ kotlin {
146146
}
147147
}
148148

149-
if (project.property("firebase-app.skipIosTests") == "true") {
150-
tasks.forEach {
151-
if (it.name.contains("ios", true) && it.name.contains("test", true)) { it.enabled = false }
152-
}
153-
}
154-
155-
if (project.property("firebase-app.skipJvmTests") == "true") {
156-
tasks.forEach {
157-
if (it.name.contains("jvm", true) && it.name.contains("test", true)) { it.enabled = false }
158-
}
159-
}
160-
161-
if (project.property("firebase-app.skipJsTests") == "true") {
162-
tasks.forEach {
163-
if (it.name.contains("js", true) && it.name.contains("test", true)) { it.enabled = false }
164-
}
165-
}
166-
167149
signing {
168150
val signingKey: String? by project
169151
val signingPassword: String? by project

firebase-auth/build.gradle.kts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -146,24 +146,6 @@ kotlin {
146146
}
147147
}
148148

149-
if (project.property("firebase-auth.skipIosTests") == "true") {
150-
tasks.forEach {
151-
if (it.name.contains("ios", true) && it.name.contains("test", true)) { it.enabled = false }
152-
}
153-
}
154-
155-
if (project.property("firebase-auth.skipJvmTests") == "true") {
156-
tasks.forEach {
157-
if (it.name.contains("jvm", true) && it.name.contains("test", true)) { it.enabled = false }
158-
}
159-
}
160-
161-
if (project.property("firebase-auth.skipJsTests") == "true") {
162-
tasks.forEach {
163-
if (it.name.contains("js", true) && it.name.contains("test", true)) { it.enabled = false }
164-
}
165-
}
166-
167149
if (supportIosTarget) {
168150
tasks.create<Exec>("launchIosSimulator") {
169151
commandLine("open", "-a", "Simulator")

firebase-common-internal/build.gradle.kts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -149,24 +149,6 @@ kotlin {
149149
}
150150
}
151151

152-
if (project.property("firebase-common.skipIosTests") == "true") {
153-
tasks.forEach {
154-
if (it.name.contains("ios", true) && it.name.contains("test", true)) { it.enabled = false }
155-
}
156-
}
157-
158-
if (project.property("firebase-common.skipJvmTests") == "true") {
159-
tasks.forEach {
160-
if (it.name.contains("jvm", true) && it.name.contains("test", true)) { it.enabled = false }
161-
}
162-
}
163-
164-
if (project.property("firebase-common.skipJsTests") == "true") {
165-
tasks.forEach {
166-
if (it.name.contains("js", true) && it.name.contains("test", true)) { it.enabled = false }
167-
}
168-
}
169-
170152
signing {
171153
val signingKey: String? by project
172154
val signingPassword: String? by project

firebase-common/build.gradle.kts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -148,24 +148,6 @@ kotlin {
148148
}
149149
}
150150

151-
if (project.property("firebase-common.skipIosTests") == "true") {
152-
tasks.forEach {
153-
if (it.name.contains("ios", true) && it.name.contains("test", true)) { it.enabled = false }
154-
}
155-
}
156-
157-
if (project.property("firebase-common.skipJvmTests") == "true") {
158-
tasks.forEach {
159-
if (it.name.contains("jvm", true) && it.name.contains("test", true)) { it.enabled = false }
160-
}
161-
}
162-
163-
if (project.property("firebase-common.skipJsTests") == "true") {
164-
tasks.forEach {
165-
if (it.name.contains("js", true) && it.name.contains("test", true)) { it.enabled = false }
166-
}
167-
}
168-
169151
signing {
170152
val signingKey: String? by project
171153
val signingPassword: String? by project

firebase-config/build.gradle.kts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -147,24 +147,6 @@ kotlin {
147147
}
148148
}
149149

150-
if (project.property("firebase-config.skipIosTests") == "true") {
151-
tasks.forEach {
152-
if (it.name.contains("ios", true) && it.name.contains("test", true)) { it.enabled = false }
153-
}
154-
}
155-
156-
if (project.property("firebase-config.skipJvmTests") == "true") {
157-
tasks.forEach {
158-
if (it.name.contains("jvm", true) && it.name.contains("test", true)) { it.enabled = false }
159-
}
160-
}
161-
162-
if (project.property("firebase-config.skipJsTests") == "true") {
163-
tasks.forEach {
164-
if (it.name.contains("js", true) && it.name.contains("test", true)) { it.enabled = false }
165-
}
166-
}
167-
168150
signing {
169151
val signingKey: String? by project
170152
val signingPassword: String? by project

0 commit comments

Comments
 (0)