diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a53969c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,38 @@ +name: Android CI + +on: + push: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v5 + + - name: set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Run Unit Tests and Generate Coverage + run: ./gradlew testFreeVersionDebugUnitTest jacocoTestReport --continue + + - name: Upload Coverage Report + uses: actions/upload-artifact@v4 + if: always() + with: + name: coverage-report + path: app/build/reports/jacoco/jacocoTestReport/html/ + + - name: Upload Test Results + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-results + path: app/build/reports/tests/ diff --git a/app/build.gradle b/app/build.gradle index 46c0f33..7748743 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,6 +4,7 @@ plugins { id 'org.jetbrains.kotlin.plugin.serialization' id 'com.google.devtools.ksp' id 'org.jetbrains.kotlin.plugin.compose' + id 'jacoco' } kotlin { @@ -36,6 +37,9 @@ android { shrinkResources = true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } + debug { + enableUnitTestCoverage = true + } } flavorDimensions += "version" productFlavors { @@ -101,3 +105,23 @@ dependencies { implementation 'ru.gildor.coroutines:kotlin-coroutines-okhttp:1.0' implementation 'io.github.rburgst:okhttp-digest:3.1.1' } + +tasks.register('jacocoTestReport', JacocoReport) { + dependsOn 'testFreeVersionDebugUnitTest' + + reports { + xml.required = true + html.required = true + } + + def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*'] + def debugTree = fileTree(dir: "${project.layout.buildDirectory.get().asFile}/intermediates/javac/freeVersionDebug/classes", excludes: fileFilter) + def kotlinDebugTree = fileTree(dir: "${project.layout.buildDirectory.get().asFile}/tmp/kotlin-classes/freeVersionDebug", excludes: fileFilter) + def mainSrc = "${project.projectDir}/src/main/java" + + sourceDirectories.setFrom(files([mainSrc])) + classDirectories.setFrom(files([debugTree, kotlinDebugTree])) + executionData.setFrom(fileTree(dir: project.layout.buildDirectory.get().asFile, includes: [ + "outputs/unit_test_code_coverage/freeVersionDebugUnitTest/testFreeVersionDebugUnitTest.exec" + ])) +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e43e1e8..7536e9e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -5,4 +5,4 @@ distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists # https://docs.gradle.org/current/userguide/gradle_wrapper.html#sec:verification -distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab \ No newline at end of file +distributionSha256Sum=20f1b1176237254a6fc204d8434196fa11a4cfb387567519c61556e8710aed78 \ No newline at end of file