From 5d5bc25a457b8dc5a2b560a5a64246c7e03a8a28 Mon Sep 17 00:00:00 2001 From: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com> Date: Mon, 31 Mar 2025 16:46:19 -0400 Subject: [PATCH] [PM-19652] Consolidate check configurations (#4937) --- .github/workflows/build-authenticator.yml | 2 +- .github/workflows/test-authenticator.yml | 82 ------------ .github/workflows/test.yml | 26 ++-- app/build.gradle.kts | 96 -------------- .../ui/platform/util/BuildConfigTest.kt | 7 +- authenticator/build.gradle.kts | 86 ------------- authenticatorbridge/build.gradle.kts | 4 +- build.gradle.kts | 117 +++++++++++++++++- fastlane/Fastfile | 16 +-- 9 files changed, 140 insertions(+), 296 deletions(-) delete mode 100644 .github/workflows/test-authenticator.yml diff --git a/.github/workflows/build-authenticator.yml b/.github/workflows/build-authenticator.yml index 0412d1109a..f363586d9a 100644 --- a/.github/workflows/build-authenticator.yml +++ b/.github/workflows/build-authenticator.yml @@ -78,7 +78,7 @@ jobs: bundle install --jobs 4 --retry 3 - name: Check Authenticator - run: bundle exec fastlane checkAuthenticator + run: bundle exec fastlane check - name: Build Authenticator run: bundle exec fastlane buildAuthenticatorDebug diff --git a/.github/workflows/test-authenticator.yml b/.github/workflows/test-authenticator.yml deleted file mode 100644 index a389ba2d48..0000000000 --- a/.github/workflows/test-authenticator.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: Test Authenticator - -on: - push: - branches: - - "main" - - "rc" - - "hotfix-rc" - pull_request_target: - types: [opened, synchronize] - -env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - JAVA_VERSION: 17 - -jobs: - check-run: - name: Check PR run - uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main - - test: - name: Test - runs-on: ubuntu-24.04 - needs: check-run - permissions: - contents: read - packages: read - pull-requests: write - - steps: - - name: Check out repo - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - ref: ${{ github.event.pull_request.head.sha }} - - - name: Validate Gradle wrapper - uses: gradle/actions/wrapper-validation@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2 - - - name: Cache Gradle files - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-v2-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/libs.versions.toml') }} - restore-keys: | - ${{ runner.os }}-gradle-v2- - - - name: Cache build output - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 - with: - path: | - ${{ github.workspace }}/build-cache - key: ${{ runner.os }}-build-cache-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-build- - - - name: Configure Ruby - uses: ruby/setup-ruby@28c4deda893d5a96a6b2d958c5b47fc18d65c9d3 # v1.213.0 - with: - bundler-cache: true - - - name: Configure JDK - uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0 - with: - distribution: "temurin" - java-version: ${{ env.JAVA_VERSION }} - - - name: Install Fastlane - run: | - gem install bundler:2.2.27 - bundle config path vendor/bundle - bundle install --jobs 4 --retry 3 - - - name: Build and test Authenticator - run: | - bundle exec fastlane checkAuthenticator - - - name: Upload to codecov.io - uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2 - with: - files: authenticator/build/reports/kover/reportDebug.xml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1f75c36daa..7e6b478aa3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,6 +23,7 @@ jobs: runs-on: ubuntu-24.04 permissions: packages: read + pull-requests: write steps: - name: Check out repo @@ -79,25 +80,11 @@ jobs: with: name: test-reports path: | + build/reports/kover/reportMergedCoverage.xml app/build/reports/tests/ - app/build/reports/kover/reportStandardDebug.xml - - report: - name: Process Test Reports - needs: test - runs-on: ubuntu-24.04 - permissions: - contents: read - issues: write - pull-requests: write - if: success() - - steps: - - name: Download test artifacts - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 - if: github.event_name == 'push' || github.event_name == 'pull_request' - with: - name: test-reports + authenticator/build/reports/tests/ + authenticatorbridge/build/reports/tests/ + core/build/reports/tests/ - name: Upload to codecov.io id: upload-to-codecov @@ -106,8 +93,9 @@ jobs: continue-on-error: true with: os: linux - files: kover/reportStandardDebug.xml + files: build/reports/kover/reportMergedCoverage.xml fail_ci_if_error: true + disable_search: true - name: Comment PR if tests failed if: steps.upload-to-codecov.outcome == 'failure' && (github.event_name == 'push' || github.event_name == 'pull_request') diff --git a/app/build.gradle.kts b/app/build.gradle.kts index d92f97ad7a..2286b6f24d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,16 +13,13 @@ plugins { // Crashlytics is enabled for all builds initially but removed for FDroid builds in gradle and // standardDebug builds in the merged manifest. alias(libs.plugins.crashlytics) - alias(libs.plugins.detekt) alias(libs.plugins.hilt) alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.compose.compiler) alias(libs.plugins.kotlin.parcelize) alias(libs.plugins.kotlin.serialization) - alias(libs.plugins.kotlinx.kover) alias(libs.plugins.ksp) alias(libs.plugins.google.services) - alias(libs.plugins.sonarqube) } /** @@ -283,90 +280,9 @@ dependencies { testImplementation(libs.robolectric.robolectric) testImplementation(libs.square.okhttp.mockwebserver) testImplementation(libs.square.turbine) - - detektPlugins(libs.detekt.detekt.formatting) - detektPlugins(libs.detekt.detekt.rules) -} - -detekt { - autoCorrect = true - config.from(files("$rootDir/detekt-config.yml")) -} - -kover { - currentProject { - sources { - excludeJava = true - } - } - reports { - filters { - excludes { - androidGeneratedClasses() - annotatedBy( - // Compose previews - "androidx.compose.ui.tooling.preview.Preview", - "androidx.compose.ui.tooling.preview.PreviewScreenSizes", - // Manually excluded classes/files/etc. - "com.bitwarden.core.annotation.OmitFromCoverage", - ) - classes( - // Navigation helpers - "*.*NavigationKt*", - // Composable singletons - "*.*ComposableSingletons*", - // Generated classes related to interfaces with default values - "*.*DefaultImpls*", - // Databases - "*.database.*Database*", - "*.dao.*Dao*", - // Dagger Hilt - "dagger.hilt.*", - "hilt_aggregated_deps.*", - "*_Factory", - "*_Factory\$*", - "*_*Factory", - "*_*Factory\$*", - "*.Hilt_*", - "*_HiltModules", - "*_HiltModules*", - "*_HiltModules\$*", - "*_Impl", - "*_Impl\$*", - "*_MembersInjector", - ) - packages( - // Dependency injection - "*.di", - // Models - "*.model", - // Custom UI components - "com.x8bit.bitwarden.ui.platform.components", - // Theme-related code - "com.x8bit.bitwarden.ui.platform.theme", - ) - } - } - } } tasks { - getByName("check") { - // Add detekt with type resolution to check - dependsOn("detekt") - } - - getByName("sonar") { - dependsOn("check") - } - - withType().configureEach { - jvmTarget = libs.versions.jvmTarget.get() - } - withType().configureEach { - jvmTarget = libs.versions.jvmTarget.get() - } - withType { useJUnitPlatform() maxHeapSize = "2g" @@ -386,18 +302,6 @@ afterEvaluate { .forEach { it.enabled = false } } -sonar { - properties { - property("sonar.projectKey", "bitwarden_android") - property("sonar.organization", "bitwarden") - property("sonar.host.url", "https://sonarcloud.io") - property("sonar.sources", "app/src/") - property("sonar.tests", "app/src/") - property("sonar.test.inclusions", "app/src/test/") - property("sonar.exclusions", "app/src/test/") - } -} - private fun renameFile(path: String, newName: String) { val originalFile = File(path) if (!originalFile.exists()) { diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/platform/util/BuildConfigTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/platform/util/BuildConfigTest.kt index 3c79457602..5eec61a1c5 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/platform/util/BuildConfigTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/platform/util/BuildConfigTest.kt @@ -3,6 +3,7 @@ package com.x8bit.bitwarden.ui.platform.util import android.os.Build import com.x8bit.bitwarden.BuildConfig import com.x8bit.bitwarden.data.platform.util.deviceData +import com.x8bit.bitwarden.data.platform.util.isFdroid import com.x8bit.bitwarden.data.platform.util.versionData import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test @@ -14,7 +15,11 @@ class BuildConfigTest { val osInfo = "\uD83E\uDD16 ${Build.VERSION.RELEASE}@${Build.VERSION.SDK_INT}" val buildInfo = "\uD83D\uDCE6 dev" - assertEquals("$deviceBrandModel $osInfo $buildInfo", deviceData) + if (isFdroid) { + assertEquals("$deviceBrandModel $osInfo $buildInfo -fdroid", deviceData) + } else { + assertEquals("$deviceBrandModel $osInfo $buildInfo", deviceData) + } } @Test diff --git a/authenticator/build.gradle.kts b/authenticator/build.gradle.kts index 153168def3..a2bd66fe72 100644 --- a/authenticator/build.gradle.kts +++ b/authenticator/build.gradle.kts @@ -6,13 +6,11 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.android.application) alias(libs.plugins.crashlytics) - alias(libs.plugins.detekt) alias(libs.plugins.hilt) alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.compose.compiler) alias(libs.plugins.kotlin.parcelize) alias(libs.plugins.kotlin.serialization) - alias(libs.plugins.kotlinx.kover) alias(libs.plugins.ksp) alias(libs.plugins.google.protobuf) alias(libs.plugins.google.services) @@ -217,69 +215,6 @@ dependencies { testImplementation(libs.robolectric.robolectric) testImplementation(libs.square.okhttp.mockwebserver) testImplementation(libs.square.turbine) - - detektPlugins(libs.detekt.detekt.formatting) - detektPlugins(libs.detekt.detekt.rules) -} - -detekt { - autoCorrect = true - config.from(files("$rootDir/detekt-config.yml")) -} - -kover { - currentProject { - sources { - excludeJava = true - } - } - reports { - filters { - excludes { - androidGeneratedClasses() - annotatedBy( - // Compose previews - "androidx.compose.ui.tooling.preview.Preview", - // Manually excluded classes/files/etc. - "com.bitwarden.core.annotation.OmitFromCoverage", - ) - classes( - // Navigation helpers - "*.*NavigationKt*", - // Composable singletons - "*.*ComposableSingletons*", - // Generated classes related to interfaces with default values - "*.*DefaultImpls*", - // Databases - "*.database.*Database*", - "*.dao.*Dao*", - // Dagger Hilt - "dagger.hilt.*", - "hilt_aggregated_deps.*", - "*_Factory", - "*_Factory\$*", - "*_*Factory", - "*_*Factory\$*", - "*.Hilt_*", - "*_HiltModules", - "*_HiltModules\$*", - "*_Impl", - "*_Impl\$*", - "*_MembersInjector", - ) - packages( - // Dependency injection - "*.di", - // Models - "*.model", - // Custom UI components - "com.bitwarden.authenticator.ui.platform.components", - // Theme-related code - "com.bitwarden.authenticator.ui.platform.theme", - ) - } - } - } } protobuf { @@ -295,31 +230,10 @@ protobuf { } } -sonar { - properties { - property("sonar.projectKey", "bitwarden_authenticator-android") - property("sonar.organization", "bitwarden") - property("sonar.host.url", "https://sonarcloud.io") - property("sonar.sources", "authenticator/src/") - property("sonar.tests", "authenticator/src/") - property("sonar.test.inclusions", "authenticator/src/test/") - property("sonar.exclusions", "authenticator/src/test/") - } -} - tasks { withType { useJUnitPlatform() } - getByName("sonar") { - dependsOn("check") - } - withType().configureEach { - jvmTarget = libs.versions.jvmTarget.get() - } - withType().configureEach { - jvmTarget = libs.versions.jvmTarget.get() - } } private fun renameFile(path: String, newName: String) { diff --git a/authenticatorbridge/build.gradle.kts b/authenticatorbridge/build.gradle.kts index 32da3b2683..d0cedc8bd6 100644 --- a/authenticatorbridge/build.gradle.kts +++ b/authenticatorbridge/build.gradle.kts @@ -28,7 +28,7 @@ android { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" + "proguard-rules.pro", ) } } @@ -46,7 +46,7 @@ android { outputs .map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl } .forEach { output -> - val outputFileName = "authenticatorbridge-${version}-${variant.baseName}.aar" + val outputFileName = "authenticatorbridge-$version-${variant.baseName}.aar" output.outputFileName = outputFileName } } diff --git a/build.gradle.kts b/build.gradle.kts index a64f6bd682..da31dd913e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,12 +1,125 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.android.library) apply false + alias(libs.plugins.detekt) apply true alias(libs.plugins.hilt) apply false alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.kotlin.compose.compiler) apply false alias(libs.plugins.kotlin.parcelize) apply false - alias(libs.plugins.kotlinx.kover) apply false + alias(libs.plugins.kotlinx.kover) apply true alias(libs.plugins.ksp) apply false alias(libs.plugins.google.services) apply false - alias(libs.plugins.sonarqube) apply false + alias(libs.plugins.sonarqube) apply true +} + +dependencies { + detektPlugins(libs.detekt.detekt.formatting) + detektPlugins(libs.detekt.detekt.rules) + + kover(project(":app")) + kover(project(":authenticator")) + kover(project(":authenticatorbridge")) + kover(project(":core")) +} + +detekt { + autoCorrect = true + config.from(files("detekt-config.yml")) + source.from( + "app/src", + "authenticator/src", + "authenticatorbridge/src", + "core/src", + ) +} + +kover { + merge { + allProjects() + createVariant("mergedCoverage") { + // Only run tests on the `StandardDebug` variant of the :app module. + add("standardDebug", optional = true) + + // Only run tests on the `debug` variants in all other modules. + add("debug", optional = true) + } + } + currentProject { + sources { + excludeJava = true + } + } + reports { + filters { + excludes { + androidGeneratedClasses() + annotatedBy( + // Compose previews + "androidx.compose.ui.tooling.preview.Preview", + "androidx.compose.ui.tooling.preview.PreviewScreenSizes", + // Manually excluded classes/files/etc. + "com.bitwarden.core.annotation.OmitFromCoverage", + ) + classes( + // Navigation helpers + "*.*NavigationKt*", + // Composable singletons + "*.*ComposableSingletons*", + // Generated classes related to interfaces with default values + "*.*DefaultImpls*", + // Databases + "*.database.*Database*", + "*.dao.*Dao*", + // Dagger Hilt + "dagger.hilt.*", + "hilt_aggregated_deps.*", + "*_Factory", + "*_Factory\$*", + "*_*Factory", + "*_*Factory\$*", + "*.Hilt_*", + "*_HiltModules", + "*_HiltModules\$*", + "*_Impl", + "*_Impl\$*", + "*_MembersInjector", + ) + packages( + // Dependency injection + "*.di", + // Models + "*.model", + // Custom UI components + "*.ui.platform.components", + // Theme-related code + "*.ui.platform.theme", + ) + } + } + } +} + +sonar { + properties { + property("sonar.projectKey", "bitwarden_android") + property("sonar.organization", "bitwarden") + property("sonar.host.url", "https://sonarcloud.io") + property("sonar.sources", "*/src/") + property("sonar.tests", "*/src/") + property("sonar.test.inclusions", "*/src/test/") + property("sonar.exclusions", "*/src/test/") + } +} + +tasks { + getByName("sonar") { + dependsOn("koverXmlReportMergedCoverage") + } + + withType().configureEach { + jvmTarget = libs.versions.jvmTarget.get() + } + withType().configureEach { + jvmTarget = libs.versions.jvmTarget.get() + } } diff --git a/fastlane/Fastfile b/fastlane/Fastfile index a60938ffa9..082d810057 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -105,10 +105,17 @@ platform :android do ) end - desc "Runs Standard Debug tests and generates Kover report" + desc "Runs lint, tests and generates Kover reports for all project modules" lane :check do gradle( - tasks: ["app:testStandardDebug", "app:lintStandardDebug", "app:detekt", "app:koverXmlReportStandardDebug"] + tasks: [ + "detekt", + "lintStandardDebug", + "lintDebug", + "testStandardDebug", + "testDebug", + "koverXmlReportMergedCoverage", + ] ) end @@ -259,11 +266,6 @@ platform :android do end # Authenticator - desc "Runs tests" - lane :checkAuthenticator do - gradle(tasks: ["authenticator:testDebug", "authenticator:lintDebug", "authenticator:detekt","authenticator:koverXmlReportDebug"]) - end - desc "Apply build version information" fastlane_require "time" lane :setAuthenticatorBuildVersionInfo do |options|