diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index d73a0c00c..754e1ff2d 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -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 @@ -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 @@ -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 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/ @@ -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 @@ -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" \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index e1a50f727..3d3116f37 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -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" ) @@ -271,9 +271,15 @@ tasks.withType + val gradleTasks = mutableListOf>() + 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, @@ -281,16 +287,16 @@ tasks.register("devRunEmulatorTests") { ) .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) } } diff --git a/convention-plugin-test-option/src/main/kotlin/EmulatorJobsMatrix.kt b/convention-plugin-test-option/src/main/kotlin/EmulatorJobsMatrix.kt index f173f8f3e..5f216f4c6 100644 --- a/convention-plugin-test-option/src/main/kotlin/EmulatorJobsMatrix.kt +++ b/convention-plugin-test-option/src/main/kotlin/EmulatorJobsMatrix.kt @@ -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) -> + 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> = + fun getIosTestTaskList(rootProject: Project): List> = + 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> = + 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> = + 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> = 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 -> diff --git a/firebase-analytics/src/jvmTest/kotlin/dev/gitlive/firebase/analytics/analytics.kt b/firebase-analytics/src/jvmTest/kotlin/dev/gitlive/firebase/analytics/analytics.kt index d0efecbd4..ed8644cac 100644 --- a/firebase-analytics/src/jvmTest/kotlin/dev/gitlive/firebase/analytics/analytics.kt +++ b/firebase-analytics/src/jvmTest/kotlin/dev/gitlive/firebase/analytics/analytics.kt @@ -3,6 +3,7 @@ */ @file:JvmName("tests") + package dev.gitlive.firebase.analytics import dev.gitlive.firebase.testContext diff --git a/firebase-crashlytics/build.gradle.kts b/firebase-crashlytics/build.gradle.kts index 4c59074a0..4312f5a28 100644 --- a/firebase-crashlytics/build.gradle.kts +++ b/firebase-crashlytics/build.gradle.kts @@ -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 diff --git a/firebase-database/build.gradle.kts b/firebase-database/build.gradle.kts index 09ec59fc4..76f9c916e 100644 --- a/firebase-database/build.gradle.kts +++ b/firebase-database/build.gradle.kts @@ -17,11 +17,6 @@ plugins { id("testOptionsConvention") } -repositories { - google() - mavenCentral() -} - android { val minSdkVersion: Int by project val compileSdkVersion: Int by project diff --git a/firebase-storage/src/jvmTest/kotlin/dev/gitlive/firebase/storage/storage.jvm.kt b/firebase-storage/src/jvmTest/kotlin/dev/gitlive/firebase/storage/storage.jvm.kt index 8a8c266b6..605cfaddb 100644 --- a/firebase-storage/src/jvmTest/kotlin/dev/gitlive/firebase/storage/storage.jvm.kt +++ b/firebase-storage/src/jvmTest/kotlin/dev/gitlive/firebase/storage/storage.jvm.kt @@ -2,4 +2,4 @@ package dev.gitlive.firebase.storage actual fun createTestData(): Data { TODO("Not yet implemented") -} \ No newline at end of file +} diff --git a/gradle.properties b/gradle.properties index 40a407d2c..f6781cbdb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,36 +20,36 @@ kotlin.native.cacheKind=none # Set to true to skip tests and even compilation of the iOS target. skipIosTarget=false + # Skip iOS Tests -# We are skipping analytics ios tests due to an issue with cocoapods not working as expected with binary distributed dependencies firebase-analytics.skipIosTests=true firebase-app.skipIosTests=false -# We are skipping auth ios tests due to an issue with keychain and simulator. firebase-auth.skipIosTests=false -firebase-common.skipIosTests=false firebase-common-internal.skipIosTests=false +firebase-common.skipIosTests=false firebase-config.skipIosTests=false +firebase-crashlytics.skipIosTests=false firebase-database.skipIosTests=false firebase-firestore.skipIosTests=false firebase-functions.skipIosTests=false -firebase-messaging.skipIosTests=false firebase-installations.skipIosTests=false +firebase-messaging.skipIosTests=false firebase-perf.skipIosTests=false -firebase-crashlytics.skipIosTests=false firebase-storage.skipIosTests=false # We can have the functionality to skip jvm tests, due to compatibility issues. firebase-analytics.skipJvmTests=true firebase-app.skipJvmTests=false firebase-auth.skipJvmTests=true -firebase-common.skipJvmTests=false firebase-common-internal.skipJvmTests=false +firebase-common.skipJvmTests=false firebase-config.skipJvmTests=true +firebase-crashlytics.skipJvmTests=true firebase-database.skipJvmTests=false firebase-firestore.skipJvmTests=false firebase-functions.skipJvmTests=false -firebase-messaging.skipJvmTests=false firebase-installations.skipJvmTests=false +firebase-messaging.skipJvmTests=false firebase-perf.skipJvmTests=true firebase-storage.skipJvmTests=true @@ -57,14 +57,15 @@ firebase-storage.skipJvmTests=true firebase-analytics.skipJsTests=false firebase-app.skipJsTests=false firebase-auth.skipJsTests=false -firebase-common.skipJsTests=false firebase-common-internal.skipJsTests=false +firebase-common.skipJsTests=false firebase-config.skipJsTests=false +firebase-crashlytics.skipJsTests=true firebase-database.skipJsTests=false firebase-firestore.skipJsTests=false firebase-functions.skipJsTests=false -firebase-messaging.skipJsTests=false firebase-installations.skipJsTests=false +firebase-messaging.skipJsTests=false firebase-perf.skipJsTests=false firebase-storage.skipJsTests=false @@ -72,14 +73,14 @@ firebase-storage.skipJsTests=false firebase-analytics.version=1.13.0 firebase-app.version=1.13.0 firebase-auth.version=1.13.0 -firebase-common.version=1.13.0 firebase-common-internal.version=1.13.0 +firebase-common.version=1.13.0 firebase-config.version=1.13.0 +firebase-crashlytics.version=1.13.0 firebase-database.version=1.13.0 firebase-firestore.version=1.13.0 firebase-functions.version=1.13.0 -firebase-messaging.version=1.13.0 firebase-installations.version=1.13.0 +firebase-messaging.version=1.13.0 firebase-perf.version=1.13.0 -firebase-crashlytics.version=1.13.0 firebase-storage.version=1.13.0