Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CI] Implement SonarCloud #5511

Merged
merged 10 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ jobs:
with:
name: testDebugUnitTest
path: ./**/build/reports/tests/testDebugUnitTest
- uses: ./.github/actions/setup-ruby
- name: Sonar
run: bundle exec fastlane run_sonar_analysis
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

size_check_xml:
name: Size Check XML
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ env:
BUILD_CACHE_AWS_BUCKET: ${{ secrets.BUILD_CACHE_AWS_BUCKET }}
BUILD_CACHE_AWS_ACCESS_KEY_ID: ${{ secrets.BUILD_CACHE_AWS_ACCESS_KEY_ID }}
BUILD_CACHE_AWS_SECRET_KEY: ${{ secrets.BUILD_CACHE_AWS_SECRET_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_PR_NUM: ${{ github.event.pull_request.number }}

concurrency:
group: ${{ github.head_ref }}
Expand Down Expand Up @@ -73,6 +75,11 @@ jobs:
with:
name: testDebugUnitTest
path: ./**/build/reports/tests/testDebugUnitTest
- uses: ./.github/actions/setup-ruby
- name: Sonar
run: bundle exec fastlane run_sonar_analysis
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

rubocop:
name: Rubocop
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/snapshot-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ on:
required: false
default: false

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_PR_NUM: ${{ github.event.pull_request.number }}

JcMinarro marked this conversation as resolved.
Show resolved Hide resolved
jobs:
run_snapshot_tests:
name: Run
Expand Down
13 changes: 13 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ plugins {
alias(libs.plugins.detekt) apply false
alias(libs.plugins.shot) apply false
alias(libs.plugins.androidx.navigation) apply false
alias(libs.plugins.sonarqube) apply false
id("io.getstream.chat.UnitTestsPlugin")
id("io.getstream.chat.ReleasePlugin")
id("io.getstream.chat.ChangelogReleaseSectionPlugin")
Expand All @@ -44,14 +45,26 @@ plugins {
alias(libs.plugins.dokka)
}

buildscript {
dependencies {
// TODO: Remove this workaround after AGP 8.9.0 is released
// Workaround for integrate sonarqube plugin with AGP
// It looks like will be fixed after AGP 8.9.0-alpha04 is released
// https://issuetracker.google.com/issues/380600747?pli=1
classpath("org.bouncycastle:bcutil-jdk18on:1.79")
}
}

apply(from = "${rootDir}/scripts/sample-app-versioner.gradle")
apply(from = "${rootDir}/scripts/sonar.gradle")

subprojects {
if (name != "stream-chat-android-docs"
&& buildFile.exists()) {
apply(from = "${rootDir}/spotless/spotless.gradle")
}
apply(plugin = "io.gitlab.arturbosch.detekt")
apply(from = "${rootDir}/scripts/coverage.gradle")
}

tasks.withType<DependencyUpdatesTask> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ fun List<String>.selectedUnitTestCommand(rootProject: Project): String {

return filterUnitTestableModules(rootProject)
.filter { (testableModule, _) -> modulesWithTest.contains(testableModule) }
.generateGradleCommand { (module, testType) -> "$module:${testType.testCommand}" }
.generateGradleCommand { (module, testType) ->
"$module:${testType.testCommand} $module:${TestType.JACOCO_TEST_COVERAGE.testCommand}"
}
}

private fun List<String>.filterModulesWithTests(): List<String> {
Expand All @@ -24,7 +26,7 @@ private fun List<String>.filterUnitTestableModules(rootProject: Project): List<P
.filter { project -> project.hasUnitTest() && this.contains(project.name) }
.map { project ->
val testType = when {
project.tasks.any { task -> task.name == "testDebugUnitTest" } -> {
project.tasks.any { task -> task.name == TestType.ANDROID_LIBRARY_TEST.testCommand } -> {
TestType.ANDROID_LIBRARY_TEST
}

Expand All @@ -38,5 +40,5 @@ private fun List<String>.filterUnitTestableModules(rootProject: Project): List<P
}

private fun Project.hasUnitTest(): Boolean = this.tasks.any { task ->
task.name == "testDebugUnitTest" || task.name == "test"
task.name == TestType.ANDROID_LIBRARY_TEST.testCommand || task.name == TestType.JAVA_LIBRARY_TEST.testCommand
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ package io.getstream.chat.android.command.unittest.model
enum class TestType(val testCommand: String) {
JAVA_LIBRARY_TEST("test"),
ANDROID_LIBRARY_TEST("testDebugUnitTest"),
JACOCO_TEST_COVERAGE("testCoverage"),
}
8 changes: 8 additions & 0 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ lane :stop_mock_server do
Net::HTTP.get_response(URI("http://localhost:#{mock_server_driver_port}/stop")) rescue nil
end

lane :run_sonar_analysis do |options|
next unless is_check_required(sources: sources_matrix[:sonar], force_check: @force_check)

Dir.chdir('..') { sh('./gradlew sonar') }
end

lane :run_snapshot_test do |options|
next unless is_check_required(sources: sources_matrix[:ui], force_check: @force_check)

Expand Down Expand Up @@ -128,8 +134,10 @@ end

private_lane :sources_matrix do
{
unit: ['stream-chat-android-test', 'stream-chat-android-client', 'stream-chat-android-compose/', 'stream-chat-android-core', 'stream-chat-android-markdown-transformer', 'stream-chat-android-offline', 'stream-chat-android-state', 'stream-chat-android-ui-common', 'stream-chat-android-ui-components/', 'stream-chat-android-ui-utils/'],
ui: ['stream-chat-android-ui', '.github/workflows/snapshot-test'],
e2e: ['buildSrc', 'stream-chat-android', '.github/workflows/e2e-test'],
sonar: ['stream-chat-android-client/', 'stream-chat-android-compose/', 'stream-chat-android-core/', 'stream-chat-android-markdown-transformer/', 'stream-chat-android-offline/', 'stream-chat-android-state/', 'stream-chat-android-ui-common/', 'stream-chat-android-ui-components/', 'stream-chat-android-ui-utils/'],
ruby: ['fastlane', 'Gemfile', 'Gemfile.lock']
}
end
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ room = "2.6.1"
shimmer = "0.5.0"
shimmerCompose = "1.3.1"
shot = "6.1.0"
sonarqube = "6.0.1.5171"
spotless = "6.20.0"
streamLog = "1.3.1"
streamPush = "1.1.9"
Expand Down Expand Up @@ -238,5 +239,6 @@ kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "ko
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp"}
nexus-publish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "gradleNexusPublishPlugin"}
shot = { id = "shot", version.ref = "shot"}
sonarqube = { id = "org.sonarqube", version.ref = "sonarqube"}
spotless = { id = "com.diffplug.spotless", version.ref = "spotless"}
paparazzi = { id = "app.cash.paparazzi", version.ref = "paparazzi"}
61 changes: 61 additions & 0 deletions scripts/coverage.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
if (!rootProject.ext.sonar.ignoreModules.contains(name)) {
apply plugin: 'jacoco'
apply plugin: "org.sonarqube"

def isCore = (name == 'stream-chat-android-core')
def testTask = isCore ? "test" : "testDebugUnitTest"
def jacocoResults = "${buildDir}/reports/jacoco/report.xml"

if (hasProperty('android')) {
android {
buildTypes {
debug {
testCoverageEnabled = true
enableUnitTestCoverage = true
enableAndroidTestCoverage true
}
}
}
}

afterEvaluate {
tasks.withType(Test).configureEach {
jacoco.includeNoLocationClasses = true
jacoco.excludes = ['jdk.internal.*']
}

tasks.register("testCoverage", JacocoReport) {
dependsOn testTask

reports {
xml.required.set(true)
xml.outputLocation.set(file(jacocoResults))
}

executionData.setFrom(fileTree(dir: buildDir, includes: [
"outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec",
"jacoco/test.exec"
]))

def sources = isCore ? sourceSets.main.java.srcDirs : android.sourceSets.main.java.srcDirs
sourceDirectories.setFrom(files(sources))
classDirectories.setFrom(files([
fileTree(
dir: "${buildDir}/tmp/kotlin-classes/debug",
excludes: rootProject.ext.sonar.excludeFilter
),
fileTree(
dir: "${buildDir}/classes/kotlin/main",
excludes: rootProject.ext.sonar.excludeFilter
)
]))
}
}

sonarqube {
properties {
property "sonar.junit.reportPaths", "${buildDir}/test-results/${testTask}"
property "sonar.coverage.jacoco.xmlReportPaths", jacocoResults
}
}
}
46 changes: 46 additions & 0 deletions scripts/sonar.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
apply plugin: "org.sonarqube"

ext.sonar = [
ignoreModules : [
'stream-chat-android-ai-assistant',
'stream-chat-android-previewdata',
'stream-chat-android-docs',
'stream-chat-android-benchmark',
'stream-chat-android-compose-sample',
'stream-chat-android-e2e-test',
'stream-chat-android-test',
'stream-chat-android-ui-guides',
'stream-chat-android-ui-components-sample',
'stream-chat-android-client-test',
'stream-chat-android-ui-uitests',
'metrics'
],
excludeFilter : [
'**/test/**',
'**/androidTest/**',
'**/R.class',
'**/R2.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Test*.*'
]
]

ext.sonar.ignoreModules.each {
ext.sonar.excludeFilter << "**/${it}/**"
}

sonarqube {
properties {
property("sonar.host.url", "https://sonarcloud.io")
property("sonar.token", "${System.getenv("SONAR_TOKEN")}")
property("sonar.organization", "getstream")
property("sonar.projectKey", "GetStream_stream-chat-android")
property("sonar.projectName", "stream-chat-android")
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.sourceEncoding", "UTF-8"
property "sonar.java.binaries", "${rootDir}/**/build/tmp/kotlin-classes/debug,${rootDir}/**/build/classes/kotlin/main"
property "sonar.coverage.exclusions", rootProject.ext.sonar.excludeFilter
}
}

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion stream-chat-android-client/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ android {
consumerProguardFiles("consumer-proguard-rules.pro")
}
getByName("debug") {
enableUnitTestCoverage = false
consumerProguardFiles("consumer-proguard-rules.pro")
}
}
Expand Down
3 changes: 0 additions & 3 deletions stream-chat-android-offline/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ android {
"proguard-rules.pro",
)
}
debug {
enableUnitTestCoverage = false
}
}
}

Expand Down
Loading