Skip to content

Commit 1abbb9b

Browse files
authored
Merge pull request GitLiveApp#558 from siarhei-luskanau/github-actions-matrix
Split tests by modules in Github Actions
2 parents 101869c + 2401330 commit 1abbb9b

File tree

8 files changed

+149
-52
lines changed

8 files changed

+149
-52
lines changed

.github/workflows/pull_request.yml

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

1010
jobs:
11-
jobEmulatorMatrixSetup:
11+
lint:
1212
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:
25+
runs-on: macos-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,19 +81,26 @@ 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
94+
- name: Set Artifact Name
95+
run: |
96+
echo "ARCHIVE_KEY=$(echo ${{ matrix.gradle_tasks }} | cut -d: -f2)" >> $GITHUB_ENV
6897
- name: Run JS Tests
69-
run: ./gradlew cleanTest jsTest
98+
run: ./gradlew ${{ matrix.gradle_tasks }}
7099
- name: Upload JS test artifact
71100
uses: actions/upload-artifact@v4
72101
if: failure()
73102
with:
74-
name: "JS Test Report HTML"
103+
name: JS ${{ env.ARCHIVE_KEY }} Test Report HTML
75104
path: |
76105
**/build/reports/tests/jsTest/
77106
**/build/reports/tests/jsBrowserTest/
@@ -80,10 +109,14 @@ jobs:
80109
uses: actions/upload-artifact@v4
81110
if: failure()
82111
with:
83-
name: "JS Firebase Debug Log"
112+
name: JS ${{ env.ARCHIVE_KEY }} Firebase Debug Log
84113
path: "**/firebase-debug.log"
85114
build-ios:
115+
needs: jobMatrixSetup
86116
runs-on: macos-latest
117+
strategy:
118+
fail-fast: false
119+
matrix: ${{ fromJson(needs.jobMatrixSetup.outputs.ios_test_jobs_matrix) }}
87120
steps:
88121
- uses: actions/checkout@v4
89122
- name: Cocoapods cache
@@ -97,43 +130,49 @@ jobs:
97130
key: cocoapods-cache-v2
98131
- name: Setup test environment
99132
uses: ./.github/actions/setup_test_action
100-
- name: ktLint
101-
run: ./gradlew lintKotlin
133+
- name: Set Artifact Name
134+
run: |
135+
echo "ARCHIVE_KEY=$(echo ${{ matrix.gradle_tasks }} | cut -d: -f2)" >> $GITHUB_ENV
102136
- name: Run iOS Tests
103-
run: ./gradlew cleanTest iosSimulatorArm64Test
137+
run: ./gradlew ${{ matrix.gradle_tasks }}
104138
- name: Upload iOS test artifact
105139
uses: actions/upload-artifact@v4
106140
if: failure()
107141
with:
108-
name: "iOS Test Report HTML"
142+
name: iOS ${{ env.ARCHIVE_KEY }} Test Report HTML
109143
path: "**/build/reports/tests/iosSimulatorArm64Test/"
110144
- name: Upload Firebase Debug Log
111145
uses: actions/upload-artifact@v4
112146
if: failure()
113147
with:
114-
name: "iOS Firebase Debug Log"
148+
name: iOS ${{ env.ARCHIVE_KEY }} Firebase Debug Log
115149
path: "**/firebase-debug.log"
116150
build-jvm:
151+
needs: jobMatrixSetup
117152
runs-on: ubuntu-latest
153+
strategy:
154+
fail-fast: false
155+
matrix: ${{ fromJson(needs.jobMatrixSetup.outputs.jvm_test_jobs_matrix) }}
118156
steps:
119157
- uses: actions/checkout@v4
120158
- name: Setup test environment
121159
uses: ./.github/actions/setup_test_action
122160
timeout-minutes: 10
123-
- name: run apiCheck
124-
run: ./gradlew apiCheck
161+
- name: Set Artifact Name
162+
run: |
163+
echo "ARCHIVE_KEY=$(echo ${{ matrix.gradle_tasks }} | cut -d: -f2)" >> $GITHUB_ENV
125164
- name: Run JVM Tests
126-
run: ./gradlew cleanTest jvmTest
165+
run: ./gradlew ${{ matrix.gradle_tasks }}
127166
- name: Upload JVM test artifact
128167
uses: actions/upload-artifact@v4
129168
if: failure()
130169
with:
131-
name: "JVM Test Report HTML"
170+
name: JVM ${{ env.ARCHIVE_KEY }} Test Report HTML
132171
path: |
133172
**/build/reports/tests/jvmTest/
134173
- name: Upload Firebase Debug Log
135174
uses: actions/upload-artifact@v4
136175
if: failure()
137176
with:
138-
name: "JVM Firebase Debug Log"
177+
name: JVM ${{ env.ARCHIVE_KEY }} Firebase Debug Log
139178
path: "**/firebase-debug.log"

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: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,62 @@ 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+
subProject.name == "test-utils" ||
36+
(rootProject.property("${subProject.name}.skipIosTests") == "true").not()
37+
}.map { subProject ->
38+
when (val osArch = System.getProperty("os.arch")) {
39+
"x86", "i386", "ia-32", "i686" -> "${subProject.path}:iosX86Test"
40+
"x86_64", "amd64", "x64", "x86-64" -> "${subProject.path}:iosX64Test"
41+
"arm", "arm-v7", "armv7", "arm32",
42+
"arm64", "arm-v8", "aarch64" -> "${subProject.path}:iosSimulatorArm64Test"
43+
44+
else -> throw Error("Unexpected System.getProperty(\"os.arch\") = $osArch")
45+
}
46+
}.map { listOf("cleanTest", it) }
47+
48+
fun getJsTestTaskList(rootProject: Project): List<List<String>> =
49+
rootProject.subprojects.filter { subProject ->
50+
subProject.name == "test-utils" ||
51+
(rootProject.property("${subProject.name}.skipJsTests") == "true").not()
52+
}.map { subProject ->
53+
"${subProject.path}:jsTest"
54+
}.map { listOf("cleanTest", it) }
55+
56+
fun getJvmTestTaskList(rootProject: Project): List<List<String>> =
57+
rootProject.subprojects.filter { subProject ->
58+
subProject.name == "test-utils" ||
59+
(rootProject.property("${subProject.name}.skipJvmTests") == "true").not()
60+
}.map { subProject ->
61+
"${subProject.path}:jvmTest"
62+
}.map { listOf("cleanTest", it) }
63+
64+
fun getEmulatorTaskList(rootProject: Project): List<List<String>> =
2665
rootProject.subprojects.filter { subProject ->
27-
File(subProject.projectDir, "src${File.separator}androidInstrumentedTest").exists()
66+
File(subProject.projectDir, "src${File.separator}commonTest").exists() ||
67+
File(
68+
subProject.projectDir,
69+
"src${File.separator}androidInstrumentedTest"
70+
).exists()
2871
}.map { subProject ->
2972
"${subProject.path}:gradleManagedDeviceDebugAndroidTest"
3073
}.map { taskName ->

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-crashlytics/build.gradle.kts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,18 @@ if (project.property("firebase-crashlytics.skipIosTests") == "true") {
136136
}
137137
}
138138

139+
if (project.property("firebase-crashlytics.skipJvmTests") == "true") {
140+
tasks.forEach {
141+
if (it.name.contains("jvm", true) && it.name.contains("test", true)) { it.enabled = false }
142+
}
143+
}
144+
145+
if (project.property("firebase-crashlytics.skipJsTests") == "true") {
146+
tasks.forEach {
147+
if (it.name.contains("js", true) && it.name.contains("test", true)) { it.enabled = false }
148+
}
149+
}
150+
139151
signing {
140152
val signingKey: String? by project
141153
val signingPassword: String? by project

firebase-database/build.gradle.kts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,6 @@ plugins {
1717
id("testOptionsConvention")
1818
}
1919

20-
repositories {
21-
google()
22-
mavenCentral()
23-
}
24-
2520
android {
2621
val minSdkVersion: Int by project
2722
val compileSdkVersion: Int by project

firebase-storage/src/jvmTest/kotlin/dev/gitlive/firebase/storage/storage.jvm.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ package dev.gitlive.firebase.storage
22

33
actual fun createTestData(): Data {
44
TODO("Not yet implemented")
5-
}
5+
}

0 commit comments

Comments
 (0)