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

Setup codecov #284

Merged
merged 21 commits into from
Jun 14, 2024
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
49 changes: 48 additions & 1 deletion .github/workflows/branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ on:
env:
APP_SIGN_KEYSTORE_PATH: /tmp/keystore
CACHE_BUNDLER: ~/.bundler
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
api-level: [ 30 ]
steps:
- name: Write key file
env:
Expand Down Expand Up @@ -89,4 +93,47 @@ jobs:
options: '{ "conf": "debug" }'
skip-tracking: false
subdirectory: fastlane
bundle-install-path: CACHE_BUNDLER
bundle-install-path: CACHE_BUNDLER


- name: Ensure android directory exists
run: mkdir -p android

- name: Setup Gradle cache
uses: gradle/gradle-build-action@v2

- name: List root diretory contents
run: ls -la

- name: List android directory contents
Raynafs marked this conversation as resolved.
Show resolved Hide resolved
run: ls -la android

- name: Grant execute permission for gradlew
run: chmod +x gradlew

kibettheophilus marked this conversation as resolved.
Show resolved Hide resolved
- name: Run local tests for the combined coverage report (only API 30)
if: matrix.api-level == 30
run: ./gradlew testDebugUnitTest

- name: Generate coverage reports for Debug variants (only API 30)
if: matrix.api-level == 30
run: ./gradlew createDebugCombinedCoverageReport

- name: Upload App module test coverage report to Codecov
if: matrix.api-level == 30 # Only upload coverage on API level 30
working-directory: android
run: bash <(curl -s https://codecov.io/bash) -F app -f "**/build/reports/jacoco/"

kibettheophilus marked this conversation as resolved.
Show resolved Hide resolved
- name: Run DataSource remote module unit and instrumentation tests and generate coverage report
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
arch: x86_64
force-avd-creation: true
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: ./gradlew :datasource:remote:clean :datasource:remote:createDebugCombinedCoverageReport --stacktrace

- name: Upload DataSource module test coverage report to Codecov
if: matrix.api-level == 30 # Only upload coverage on API level 30
run: bash <(curl -s https://codecov.io/bash) -F datasource -f "**/build/reports/jacoco/"
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ plugins {
alias(libs.plugins.droidconke.android.hilt)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.droidconke.android.application.firebase)
alias(libs.plugins.droidconke.android.application.jacoco)
}

android {
Expand Down
8 changes: 8 additions & 0 deletions build-logic/convention/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ gradlePlugin {
id = "droidconke.android.application"
implementationClass = "AndroidApplicationConventionPlugin"
}
register("androidApplicationJacoco") {
id = "droidconke.android.application.jacoco"
implementationClass = "AndroidApplicationJacocoConventionPlugin"
}
register("androidLibraryJacoco") {
id = "droidconke.android.library.jacoco"
implementationClass = "AndroidLibraryJacocoConventionPlugin"
}
register("multiplatform") {
id = "droidconke.multiplatform"
implementationClass = "MultiplaftormConventionPlugin"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
import com.android254.configureJacoco
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType

class AndroidApplicationJacocoConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply("jacoco")
val androidExtension = extensions.getByType<BaseAppModuleExtension>()

androidExtension.buildTypes.configureEach {
enableAndroidTestCoverage = true
enableUnitTestCoverage = true
}

configureJacoco(extensions.getByType<ApplicationAndroidComponentsExtension>())
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.variant.LibraryAndroidComponentsExtension
import com.android254.configureJacoco
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType

class AndroidLibraryJacocoConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply("jacoco")
val androidExtension = extensions.getByType<LibraryExtension>()

androidExtension.buildTypes.configureEach {
enableAndroidTestCoverage = true
enableUnitTestCoverage = true
}

configureJacoco(extensions.getByType<LibraryAndroidComponentsExtension>())
}
}
}
100 changes: 100 additions & 0 deletions build-logic/convention/src/main/kotlin/com/android254/Jacoco.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package com.android254

import com.android.build.api.artifact.ScopedArtifact
import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.api.variant.ScopedArtifacts
import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.testing.Test
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.register
import org.gradle.kotlin.dsl.withType
import org.gradle.testing.jacoco.plugins.JacocoPluginExtension
import org.gradle.testing.jacoco.plugins.JacocoTaskExtension
import org.gradle.testing.jacoco.tasks.JacocoReport
import java.util.Locale

private val coverageExclusions = listOf(
// Android
"**/R.class",
"**/R\$*.class",
"**/BuildConfig.*",
"**/Manifest*.*",
"**/*_Hilt*.class",
"**/Hilt_*.class",
)

private fun String.capitalize() = replaceFirstChar {
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
}

/**
* Creates a new task that generates a combined coverage report with data from local and
* instrumented tests.
*
* `create{variant}CombinedCoverageReport`
*
* Note that coverage data must exist before running the task. This allows us to run device
* tests on CI using a different Github Action or an external device.
*/
internal fun Project.configureJacoco(
androidComponentsExtension: AndroidComponentsExtension<*, *, *>,
) {
configure<JacocoPluginExtension> {
toolVersion = "0.8.11"
}

androidComponentsExtension.onVariants { variant ->
val myObjFactory = project.objects
val buildDir = layout.buildDirectory.get().asFile
val allJars: ListProperty<RegularFile> = myObjFactory.listProperty(RegularFile::class.java)
val allDirectories: ListProperty<Directory> = myObjFactory.listProperty(Directory::class.java)
val reportTask =
tasks.register("create${variant.name.capitalize()}CombinedCoverageReport", JacocoReport::class) {

classDirectories.setFrom(
allJars,
allDirectories.map { dirs ->
dirs.map { dir ->
myObjFactory.fileTree().setDir(dir).exclude(coverageExclusions)
}
}
)
reports {
xml.required.set(true)
html.required.set(true)
}


sourceDirectories.setFrom(files("$projectDir/src/main/java", "$projectDir/src/main/kotlin"))

executionData.setFrom(
project.fileTree("$buildDir/outputs/unit_test_code_coverage/${variant.name}UnitTest")
.matching { include("**/*.exec") },

project.fileTree("$buildDir/outputs/code_coverage/${variant.name}AndroidTest")
.matching { include("**/*.ec") }
)
}


variant.artifacts.forScope(ScopedArtifacts.Scope.PROJECT)
.use(reportTask)
.toGet(
ScopedArtifact.CLASSES,
{ _ -> allJars },
{ _ -> allDirectories },
)
}

tasks.withType<Test>().configureEach {
configure<JacocoTaskExtension> {

isIncludeNoLocationClasses = true

excludes = listOf("jdk.internal.*")
}
}
}
1 change: 1 addition & 0 deletions chai/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
plugins {
alias(libs.plugins.droidconke.android.library)
alias(libs.plugins.droidconke.android.library.compose)
alias(libs.plugins.droidconke.android.library.jacoco)
alias(libs.plugins.compose.compiler)
}

Expand Down
23 changes: 23 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
codecov:
notify:
wait_for_ci: true
max_report_age: off
require_ci_to_pass: true
comment:
behavior: default
layout: "reach, diff, flags, files"
show_carryforward_flags: false
coverage:
precision: 1
status:
changes: false
patch:
default:
target: 60.0
project:
default:
enabled: true
target: 25.0
flag_management:
default_rules:
carryforward: true
1 change: 1 addition & 0 deletions data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ plugins {
alias(libs.plugins.droidconke.android.hilt)
alias(libs.plugins.droidconke.android.library.firebase)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.droidconke.android.library.jacoco)
}

android {
Expand Down
1 change: 1 addition & 0 deletions datasource/local/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ plugins {
alias(libs.plugins.droidconke.android.room)
alias(libs.plugins.droidconke.android.hilt)
alias(libs.plugins.droidconke.android.library.firebase)
alias(libs.plugins.droidconke.android.library.jacoco)
}

android {
Expand Down
1 change: 1 addition & 0 deletions datasource/remote/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ plugins {
alias(libs.plugins.droidconke.android.hilt)
alias(libs.plugins.droidconke.android.library.firebase)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.droidconke.android.library.jacoco)
}

android {
Expand Down
1 change: 1 addition & 0 deletions domain/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
plugins {
alias(libs.plugins.droidconke.android.library)
alias(libs.plugins.droidconke.android.library.jacoco)
}

android {
Expand Down
Loading
Loading