Skip to content

Commit

Permalink
[CI] Implement SonarCloud
Browse files Browse the repository at this point in the history
  • Loading branch information
testableapple committed Dec 11, 2024
1 parent 47f7df2 commit a8948b3
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 10 deletions.
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
6 changes: 6 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ 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_PR_NUM: ${{ github.event.pull_request.number }}

concurrency:
group: ${{ github.head_ref }}
Expand Down Expand Up @@ -73,6 +74,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
3 changes: 3 additions & 0 deletions .github/workflows/snapshot-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ on:
required: false
default: false

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

jobs:
run_snapshot_tests:
name: Run
Expand Down
8 changes: 5 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ apply plugin: "com.github.ben-manes.versions"
apply plugin: 'io.github.gradle-nexus.publish-plugin'
apply plugin: 'binary-compatibility-validator'
apply plugin: 'org.jetbrains.dokka'
apply from: "${rootDir}/sonar.gradle"
apply from: "${rootDir}/scripts/sample-app-versioner.gradle"
apply plugin: UnitTestsPlugin
apply plugin: ReleasePlugin
Expand Down Expand Up @@ -73,15 +74,16 @@ buildscript {
classpath Dependencies.spotlessGradlePlugin
classpath Dependencies.ksp
classpath Dependencies.detektPlugin
classpath Dependencies.sonarQubePlugin
}
}

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

versionPrint {
Expand Down Expand Up @@ -134,4 +136,4 @@ apiValidation {
]
}

apply from: "${rootDir}/scripts/publish-root.gradle"
apply from: "${rootDir}/scripts/publish-root.gradle"
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ object Versions {
internal const val SHIMMER = "0.5.0"
internal const val SHIMMER_COMPOSE = "1.3.1"
internal const val SHOT = "6.1.0"
internal const val SONARQUBE_PLUGIN = "6.0.1.5171"
internal const val SPOTLESS = "6.20.0"
internal const val STREAM_LOG = "1.3.1"
internal const val STREAM_PUSH = "1.1.9"
Expand Down Expand Up @@ -252,6 +253,7 @@ object Dependencies {
const val allureKotlinCommons = "io.qameta.allure:allure-kotlin-commons:${Versions.ALLURE_KOTLIN}"
const val allureKotlinJunit = "io.qameta.allure:allure-kotlin-junit4:${Versions.ALLURE_KOTLIN}"
const val allureKotlinAndroid = "io.qameta.allure:allure-kotlin-android:${Versions.ALLURE_KOTLIN}"
const val sonarQubePlugin = "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:${Versions.SONARQUBE_PLUGIN}"

@JvmStatic
fun isNonStable(version: String): Boolean = isStable(version).not()
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"),
}
88 changes: 88 additions & 0 deletions coverage.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
apply plugin: 'jacoco'

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 {
html.required.set(false)
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 excludeFilter = [
'**/test/**',
'**/androidTest/**',
'**/R.class',
'**/R2.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Test*.*'
]

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: excludeFilter
),
fileTree(
dir: "${buildDir}/classes/kotlin/main",
excludes: excludeFilter
)
]))
}
}

def ignoredModules = [
'stream-chat-android-docs',
'stream-chat-android-benchmark',
'stream-chat-android-compose-sample',
'stream-chat-android-e2e-test',
'stream-chat-android-previewdata',
'stream-chat-android-test',
'stream-chat-android-ui-guides',
'stream-chat-android-ui-components-sample',
'stream-chat-android-pushprovider-firebase',
'stream-chat-android-ai-assistant',
'stream-chat-android-client-test',
'stream-chat-android-ui-uitests'
]
if (!ignoredModules.contains(name)) {
apply plugin: "org.sonarqube"

sonarqube {
properties {
property "sonar.junit.reportPaths", "${buildDir}/test-results/${testTask}"
property "sonar.coverage.jacoco.xmlReportPaths", jacocoResults
}
}
}
7 changes: 7 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[:unit], 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,6 +134,7 @@ end

private_lane :sources_matrix do
{
unit: ['stream-chat-android-client/', 'stream-chat-android-client-test/', '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'],
ruby: ['fastlane', 'Gemfile', 'Gemfile.lock']
Expand Down
15 changes: 15 additions & 0 deletions sonar.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apply plugin: "org.sonarqube"

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", "**/test/**,**/androidTest/**,**/R.class,**/R2.class,**/R\$*.class,**/BuildConfig.*,**/Manifest*.*,**/*Test*.*"
}
}
1 change: 0 additions & 1 deletion stream-chat-android-client/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ android {
consumerProguardFiles 'consumer-proguard-rules.pro'
}
debug {
testCoverageEnabled false
consumerProguardFiles 'consumer-proguard-rules.pro'
}
}
Expand Down
3 changes: 0 additions & 3 deletions stream-chat-android-offline/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ android {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
testCoverageEnabled false
}
}
}

Expand Down

0 comments on commit a8948b3

Please sign in to comment.