diff --git a/build.gradle.kts b/build.gradle.kts index 93f0c52619..c3e881c748 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -55,17 +55,6 @@ subprojects { } } - // Skip qa for: main app, pure Java/Kotlin libs, and implicit parent projects from hierarchical naming - val skipQa = setOf("Signal-Android", "libsignal-service", "lintchecks", "benchmark", "util-jvm", "models", "logging", "core", "lib", "demo", "feature") - - if (project.name !in skipQa && !project.name.endsWith("-app")) { - tasks.register("qa") { - group = "Verification" - description = "Quality Assurance. Run before pushing" - dependsOn("clean", "testReleaseUnitTest", "lintRelease") - } - } - tasks.withType().configureEach { maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1) } @@ -84,21 +73,47 @@ tasks.register("buildQa") { tasks.register("qa") { group = "Verification" description = "Quality Assurance. Run before pushing." - dependsOn( - "clean", - "checkStopship", - "buildQa", - ":Signal-Android:testPlayProdPerfUnitTest", - ":Signal-Android:lintPlayProdRelease", - "Signal-Android:ktlintCheck", - ":lib:libsignal-service:test", - ":lib:libsignal-service:ktlintCheck", - ":Signal-Android:assemblePlayProdRelease", - ":Signal-Android:compilePlayProdInstrumentationAndroidTestSources", - ":microbenchmark:compileReleaseAndroidTestSources", - ":core:util-jvm:test", - ":core:util-jvm:ktlintCheck" - ) + dependsOn("clean") +} + +// Wire up QA dependencies after all projects are evaluated +gradle.projectsEvaluated { + val appTestTask = tasks.findByPath(":Signal-Android:testPlayProdPerfUnitTest") + val appLintTask = tasks.findByPath(":Signal-Android:lintPlayProdRelease") + + tasks.named("qa") { + dependsOn("ktlintCheck") + dependsOn("buildQa") + dependsOn("checkStopship") + + // Main app tasks + appTestTask?.let { dependsOn(it) } + appLintTask?.let { dependsOn(it) } + + // Library module tasks + subprojects.filter { it.name != "Signal-Android" }.forEach { subproject -> + val testTask = subproject.tasks.findByName("testDebugUnitTest") + ?: subproject.tasks.findByName("test") + testTask?.let { dependsOn(it) } + + subproject.tasks.findByName("lintDebug")?.let { dependsOn(it) } + } + } + + // Ensure clean runs before everything else + rootProject.allprojects.forEach { project -> + project.tasks.matching { it.name != "clean" }.configureEach { + mustRunAfter("clean") + } + } + + // If you let all of these things run in parallel, gradle will likely OOM. + // To avoid this, we put non-app tests and lints behind the much heavier app tests and lints. + subprojects.filter { it.name != "Signal-Android" }.forEach { subproject -> + subproject.tasks.findByName("testDebugUnitTest")?.mustRunAfter(appTestTask) + subproject.tasks.findByName("test")?.mustRunAfter(appTestTask) + subproject.tasks.findByName("lintDebug")?.mustRunAfter(appLintTask) + } } tasks.register("clean", Delete::class) { diff --git a/core/ui/src/main/java/org/signal/core/ui/compose/SignalPreviews.kt b/core/ui/src/main/java/org/signal/core/ui/compose/SignalPreviews.kt index 8c69544fa0..b52389e6c8 100644 --- a/core/ui/src/main/java/org/signal/core/ui/compose/SignalPreviews.kt +++ b/core/ui/src/main/java/org/signal/core/ui/compose/SignalPreviews.kt @@ -45,4 +45,4 @@ annotation class AllNightPreviews annotation class AllDevicePreviews @Preview(name = "large font", fontScale = 2f) -annotation class LargeFontPreviews \ No newline at end of file +annotation class LargeFontPreviews diff --git a/lintchecks/src/test/java/org/signal/lint/SystemOutPrintLnDetectorTest.kt b/lintchecks/src/test/java/org/signal/lint/SystemOutPrintLnDetectorTest.kt index f163a2e3d8..4e089c76a7 100644 --- a/lintchecks/src/test/java/org/signal/lint/SystemOutPrintLnDetectorTest.kt +++ b/lintchecks/src/test/java/org/signal/lint/SystemOutPrintLnDetectorTest.kt @@ -30,7 +30,7 @@ class SystemOutPrintLnDetectorTest { .run() .expect( """ - src/foo/Example.java:4: Error: Using 'System.out.println' instead of proper logging [SystemOutPrintLnUsage] + src/foo/Example.java:4: Error: Using 'System.out.println' instead of Signal Logger [SystemOutPrintLnUsage] System.out.println("Hello World"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 errors, 0 warnings @@ -66,7 +66,7 @@ class SystemOutPrintLnDetectorTest { .run() .expect( """ - src/foo/Example.java:4: Error: Using 'System.out.print' instead of proper logging [SystemOutPrintLnUsage] + src/foo/Example.java:4: Error: Using 'System.out.print' instead of Signal Logger [SystemOutPrintLnUsage] System.out.print("Hello"); ~~~~~~~~~~~~~~~~~~~~~~~~~ 1 errors, 0 warnings @@ -104,7 +104,7 @@ class SystemOutPrintLnDetectorTest { .run() .expect( """ - src/foo/Example.kt:5: Error: Using 'kotlin.io.println' instead of proper logging [KotlinIOPrintLnUsage] + src/foo/Example.kt:5: Error: Using 'kotlin.io.println' instead of Signal Logger. [KotlinIOPrintLnUsage] println("Hello World") ~~~~~~~~~~~~~~~~~~~~~~ 1 errors, 0 warnings @@ -139,7 +139,7 @@ class SystemOutPrintLnDetectorTest { .run() .expect( """ - src/foo/test.kt:3: Error: Using 'kotlin.io.println' instead of proper logging [KotlinIOPrintLnUsage] + src/foo/test.kt:3: Error: Using 'kotlin.io.println' instead of Signal Logger. [KotlinIOPrintLnUsage] println("Hello World") ~~~~~~~~~~~~~~~~~~~~~~ 1 errors, 0 warnings @@ -175,7 +175,7 @@ class SystemOutPrintLnDetectorTest { .run() .expect( """ - src/foo/Example.java:4: Error: Using 'System.out.println' instead of proper logging [SystemOutPrintLnUsage] + src/foo/Example.java:4: Error: Using 'System.out.println' instead of Signal Logger [SystemOutPrintLnUsage] System.out.println(); ~~~~~~~~~~~~~~~~~~~~ 1 errors, 0 warnings