From 49fbfe6811d46c2dcfb6d0a0c50442f14ce0220c Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 3 Mar 2022 10:40:11 +0000 Subject: [PATCH 01/10] Better codecov based on ouchadam's suggestion --- build.gradle | 10 ++++ coverage.gradle | 97 ++++++++++++++++++++++++++++++++++++++ dependencies_groups.gradle | 1 + 3 files changed, 108 insertions(+) create mode 100644 coverage.gradle diff --git a/build.gradle b/build.gradle index 0a41ac3625..42d2abe2ce 100644 --- a/build.gradle +++ b/build.gradle @@ -105,6 +105,16 @@ task clean(type: Delete) { delete rootProject.buildDir } +def launchTask = getGradle() + .getStartParameter() + .getTaskRequests() + .toString() + .toLowerCase() + +if (launchTask.contains("codeCoverageReport".toLowerCase())) { + apply from: 'coverage.gradle' +} + apply plugin: 'org.sonarqube' // To run a sonar analysis: diff --git a/coverage.gradle b/coverage.gradle new file mode 100644 index 0000000000..098c67c26f --- /dev/null +++ b/coverage.gradle @@ -0,0 +1,97 @@ +def excludes = [ + // DI graph + '**/*Module.*', + '**/*Module*.*', + + // Android composables + '**/*Screen*', + '**/components/*', + '**/*Compose*.*', + + // Android framework + '**/*Activity*', + '**/*AndroidService*', + '**/*Application*', + + // Generated + '**/*serializer*', + '**/*Serializer*', + "**/*request/*Companion*.*", + '**/*QueriesImpl*', + '**/*Db*', + '**/Select*', + + // Tmp until serializationx can ignore generated + '**/Api*', +] + +def initializeReport(report, projects, classExcludes) { + projects.each { project -> project.apply plugin: 'jacoco' } + report.executionData { fileTree(rootProject.rootDir.absolutePath).include("**/build/jacoco/*.exec") } + + report.reports { + xml.enabled true + html.enabled true + csv.enabled false + } + + gradle.projectsEvaluated { + def androidSourceDirs = [] + def androidClassDirs = [] + + projects.each { project -> + switch (project) { + case { project.plugins.hasPlugin("com.android.application") }: + androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/debug") + androidSourceDirs.add("${project.projectDir}/src/main/kotlin") + androidSourceDirs.add("${project.projectDir}/src/main/java") + break + case { project.plugins.hasPlugin("com.android.library") }: + androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/release") + androidSourceDirs.add("${project.projectDir}/src/main/kotlin") + androidSourceDirs.add("${project.projectDir}/src/main/java") + break + default: + report.sourceSets project.sourceSets.main + } + } + + report.sourceDirectories.setFrom(report.sourceDirectories + files(androidSourceDirs)) + def classFiles = androidClassDirs.collect { files(it).files }.flatten() + report.classDirectories.setFrom(files((report.classDirectories.files + classFiles).collect { + fileTree(dir: it, excludes: classExcludes) + })) + } +} + +def collectProjects(predicate) { + return subprojects.findAll { it.buildFile.isFile() && predicate(it) } +} + +//task unitCodeCoverageReport(type: JacocoReport) { +// outputs.upToDateWhen { false } +// rootProject.apply plugin: 'jacoco' +// def excludedProjects = [ +// 'olm-stub', +// 'test-harness' +// ] +// def projects = collectProjects { !excludedProjects.contains(it.name) } +// dependsOn { ["app:assembleDebug"] + projects*.test } +// initializeReport(it, projects, excludes) +//} +// +//task harnessCodeCoverageReport(type: JacocoReport) { +// outputs.upToDateWhen { false } +// rootProject.apply plugin: 'jacoco' +// def projects = collectProjects { true } +// dependsOn { ["app:assembleDebug", project(":test-harness").test] } +// initializeReport(it, projects, excludes) +//} + +task allCodeCoverageReport(type: JacocoReport) { + outputs.upToDateWhen { false } + rootProject.apply plugin: 'jacoco' + def projects = collectProjects { true } + dependsOn { projects*.test } + initializeReport(it, projects, excludes) +} diff --git a/dependencies_groups.gradle b/dependencies_groups.gradle index 7de8100469..4c976faa7c 100644 --- a/dependencies_groups.gradle +++ b/dependencies_groups.gradle @@ -150,6 +150,7 @@ ext.groups = [ 'org.ec4j.core', 'org.glassfish.jaxb', 'org.hamcrest', + 'org.jacoco', 'org.jetbrains', 'org.jetbrains.intellij.deps', 'org.jetbrains.kotlin', From 76844b15721aaf26747a39cf9d3b94d9532a33ab Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 3 Mar 2022 15:41:09 +0000 Subject: [PATCH 02/10] Run codecoverage and pass to sonarqube upload for processing. --- .github/workflows/nightly.yml | 34 +++++++++++++++++++++++++++++----- build.gradle | 4 +++- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index ebad9b7bc7..d90dafd93b 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -308,15 +308,36 @@ jobs: emulator.log failure_screenshots/ + codecov-units: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-java@v2 + with: + distribution: 'adopt' + java-version: '11' + - uses: action/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + - run: ./gradlew allCodeCoverageReport $CI_GRADLE_ARG_PROPERTIES + - name: Upload Codecov data + uses: actions/upload-artifact@v2 + if: always() + with: + name: codecov-xml + path: | + build/jacoco/*.xml + sonarqube: runs-on: macos-latest if: always() needs: - - integration-tests - - ui-tests -# - unit-tests TODO: code coverage from here too - - build-android-test-matrix-sdk - - build-android-test-app + - codecov-units steps: - uses: actions/checkout@v2 - uses: actions/setup-java@v2 @@ -331,6 +352,9 @@ jobs: key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} restore-keys: | ${{ runner.os }}-gradle- + - uses: actions/download-artifact@v3 + with: + artifact: codecov-xml # will restore to build/ as a local run would do - run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES env: ORG_GRADLE_PROJECT_SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }} diff --git a/build.gradle b/build.gradle index 42d2abe2ce..23cb479296 100644 --- a/build.gradle +++ b/build.gradle @@ -129,10 +129,12 @@ sonarqube { property "sonar.projectVersion", project(":vector").android.defaultConfig.versionName property "sonar.sourceEncoding", "UTF-8" property "sonar.links.homepage", "https://github.com/vector-im/element-android/" - property "sonar.links.ci", "https://buildkite.com/matrix-dot-org/element-android" + property "sonar.links.ci", "https://github.com/vector-im/element-android/actions" property "sonar.links.scm", "https://github.com/vector-im/element-android/" property "sonar.links.issue", "https://github.com/vector-im/element-android/issues" property "sonar.organization", "new_vector_ltd_organization" + property "sonar.java.coveragePlugin", "jacoco" + property "sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/jacoco/allCodeCoverageReport/allCodeCoverageReport.xml" property "sonar.login", project.hasProperty("SONAR_LOGIN") ? SONAR_LOGIN : "invalid" } } From cb32124fd409a32a89bc1a9458b93c0d2f3fcb29 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 3 Mar 2022 18:28:13 +0000 Subject: [PATCH 03/10] Fix typo in name of action --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index d90dafd93b..b93258112e 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -316,7 +316,7 @@ jobs: with: distribution: 'adopt' java-version: '11' - - uses: action/cache@v2 + - uses: actions/cache@v2 with: path: | ~/.gradle/caches From 9fe04ac5b85fef09a05935ab8efeae18fabe73b2 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 3 Mar 2022 20:26:33 +0000 Subject: [PATCH 04/10] Remove exclusions (for now). We can merge this PR without and re-add afterwards the only ones we want. --- coverage.gradle | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/coverage.gradle b/coverage.gradle index 098c67c26f..7cc87baad9 100644 --- a/coverage.gradle +++ b/coverage.gradle @@ -1,29 +1,4 @@ -def excludes = [ - // DI graph - '**/*Module.*', - '**/*Module*.*', - - // Android composables - '**/*Screen*', - '**/components/*', - '**/*Compose*.*', - - // Android framework - '**/*Activity*', - '**/*AndroidService*', - '**/*Application*', - - // Generated - '**/*serializer*', - '**/*Serializer*', - "**/*request/*Companion*.*", - '**/*QueriesImpl*', - '**/*Db*', - '**/Select*', - - // Tmp until serializationx can ignore generated - '**/Api*', -] +def excludes = [ ] def initializeReport(report, projects, classExcludes) { projects.each { project -> project.apply plugin: 'jacoco' } From 662f72fde807b5be006cd00c9a0643448d03267c Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Fri, 4 Mar 2022 15:01:24 +0000 Subject: [PATCH 05/10] Remove unneeded code, retaining a comment for how to exclude certain projects --- coverage.gradle | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/coverage.gradle b/coverage.gradle index 7cc87baad9..545b93f93b 100644 --- a/coverage.gradle +++ b/coverage.gradle @@ -43,29 +43,12 @@ def collectProjects(predicate) { return subprojects.findAll { it.buildFile.isFile() && predicate(it) } } -//task unitCodeCoverageReport(type: JacocoReport) { -// outputs.upToDateWhen { false } -// rootProject.apply plugin: 'jacoco' -// def excludedProjects = [ -// 'olm-stub', -// 'test-harness' -// ] -// def projects = collectProjects { !excludedProjects.contains(it.name) } -// dependsOn { ["app:assembleDebug"] + projects*.test } -// initializeReport(it, projects, excludes) -//} -// -//task harnessCodeCoverageReport(type: JacocoReport) { -// outputs.upToDateWhen { false } -// rootProject.apply plugin: 'jacoco' -// def projects = collectProjects { true } -// dependsOn { ["app:assembleDebug", project(":test-harness").test] } -// initializeReport(it, projects, excludes) -//} - task allCodeCoverageReport(type: JacocoReport) { outputs.upToDateWhen { false } rootProject.apply plugin: 'jacoco' + // to limit projects in a specific report, add + // def excludedProjects = [ ... ] + // def projects = collectProjects { !excludedProjects.contains(it.name) } def projects = collectProjects { true } dependsOn { projects*.test } initializeReport(it, projects, excludes) From 2dedad1cf237d3d314e1c38bbe2c325997541a95 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Fri, 4 Mar 2022 15:03:12 +0000 Subject: [PATCH 06/10] Address review points from adam --- coverage.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coverage.gradle b/coverage.gradle index 545b93f93b..96881dfff2 100644 --- a/coverage.gradle +++ b/coverage.gradle @@ -22,7 +22,7 @@ def initializeReport(report, projects, classExcludes) { androidSourceDirs.add("${project.projectDir}/src/main/java") break case { project.plugins.hasPlugin("com.android.library") }: - androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/release") + androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/debug") androidSourceDirs.add("${project.projectDir}/src/main/kotlin") androidSourceDirs.add("${project.projectDir}/src/main/java") break From 96168929fff42d8d968e0347bb381e99418dc5f1 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Fri, 4 Mar 2022 15:15:52 +0000 Subject: [PATCH 07/10] Tweak upload/download of codecov xml file --- .github/workflows/nightly.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index b93258112e..37797129bb 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -331,7 +331,7 @@ jobs: with: name: codecov-xml path: | - build/jacoco/*.xml + build/reports/jacoco/allCodeCoverageReport/allCodeCoverageReport.xml sonarqube: runs-on: macos-latest @@ -354,7 +354,8 @@ jobs: ${{ runner.os }}-gradle- - uses: actions/download-artifact@v3 with: - artifact: codecov-xml # will restore to build/ as a local run would do + name: codecov-xml # will restore to build/reports/jacoco/allCodeCoverageReport/allCodeCoverageReport.xml by default + - run: ls -R build/reports # temporary check to see if the report is actually downloading correctly. - run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES env: ORG_GRADLE_PROJECT_SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }} From 1ad3e7cc9d69d08550644cca773e34400241f090 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Fri, 4 Mar 2022 16:35:46 +0000 Subject: [PATCH 08/10] Frustration at artifact handling vs what's in docs. --- .github/workflows/nightly.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 37797129bb..f80dd10c69 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -354,8 +354,9 @@ jobs: ${{ runner.os }}-gradle- - uses: actions/download-artifact@v3 with: - name: codecov-xml # will restore to build/reports/jacoco/allCodeCoverageReport/allCodeCoverageReport.xml by default - - run: ls -R build/reports # temporary check to see if the report is actually downloading correctly. + name: codecov-xml # will restore to codecov-xml/allCodeCoverageReport.xml by default; we restore to the same location in following tasks + - run: mkdir -P build/reports/jacoco/allCodeCoverageReport/ + - run: mv codecov-xml/allCodeCoverageReport.xml build/reports/jacoco/allCodeCoverageReport/ - run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES env: ORG_GRADLE_PROJECT_SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }} From 8e39247c4d39e148cbb1bdee664a785e23669a8d Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Fri, 4 Mar 2022 18:00:20 +0000 Subject: [PATCH 09/10] I give up for the weekend --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index f80dd10c69..427589f95e 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -355,7 +355,7 @@ jobs: - uses: actions/download-artifact@v3 with: name: codecov-xml # will restore to codecov-xml/allCodeCoverageReport.xml by default; we restore to the same location in following tasks - - run: mkdir -P build/reports/jacoco/allCodeCoverageReport/ + - run: mkdir -p build/reports/jacoco/allCodeCoverageReport/ - run: mv codecov-xml/allCodeCoverageReport.xml build/reports/jacoco/allCodeCoverageReport/ - run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES env: From 2b7b7521a9682bcc1b5a8943409784ba8c4b2b7b Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Mon, 7 Mar 2022 10:26:25 +0000 Subject: [PATCH 10/10] Maybe the file is here? --- .github/workflows/nightly.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 427589f95e..52c63d595a 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -354,9 +354,9 @@ jobs: ${{ runner.os }}-gradle- - uses: actions/download-artifact@v3 with: - name: codecov-xml # will restore to codecov-xml/allCodeCoverageReport.xml by default; we restore to the same location in following tasks + name: codecov-xml # will restore to allCodeCoverageReport.xml by default; we restore to the same location in following tasks - run: mkdir -p build/reports/jacoco/allCodeCoverageReport/ - - run: mv codecov-xml/allCodeCoverageReport.xml build/reports/jacoco/allCodeCoverageReport/ + - run: mv allCodeCoverageReport.xml build/reports/jacoco/allCodeCoverageReport/ - run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES env: ORG_GRADLE_PROJECT_SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }}