From ba109a486f68fdb78282182624e5157c854e5df8 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Wed, 25 May 2022 12:38:37 +0100 Subject: [PATCH] Update to build scripts to enable sonarqube reporting including coverage. --- .github/workflows/post-pr.yml | 223 -------------------------------- .github/workflows/sonarqube.yml | 81 ------------ .github/workflows/tests.yml | 102 ++++++--------- build.gradle | 6 +- coverage.gradle | 23 +++- matrix-sdk-android/build.gradle | 1 + vector/build.gradle | 1 + 7 files changed, 64 insertions(+), 373 deletions(-) delete mode 100644 .github/workflows/sonarqube.yml diff --git a/.github/workflows/post-pr.yml b/.github/workflows/post-pr.yml index 8fe51eb8d5..49669e4201 100644 --- a/.github/workflows/post-pr.yml +++ b/.github/workflows/post-pr.yml @@ -29,200 +29,6 @@ jobs: steps: - run: echo "Run those tests!" # no-op success - # Run Android Tests - integration-tests: - name: Matrix SDK - Running Integration Tests - needs: should-i-run - runs-on: macos-latest - strategy: - fail-fast: false - matrix: - api-level: [ 28 ] - steps: - - uses: actions/checkout@v3 - - uses: gradle/wrapper-validation-action@v1 - - uses: actions/setup-java@v3 - with: - distribution: 'adopt' - java-version: 11 - - name: Set up Python 3.8 - uses: actions/setup-python@v3 - with: - python-version: 3.8 - - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - name: Start synapse server - uses: michaelkaye/setup-matrix-synapse@v1.0.3 - with: - uploadLogs: true - httpPort: 8080 - disableRateLimiting: true - public_baseurl: "http://10.0.2.2:8080/" - # package: org.matrix.android.sdk.session - - name: Run integration tests for Matrix SDK [org.matrix.android.sdk.session] API[${{ matrix.api-level }}] - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ matrix.api-level }} - arch: x86 - profile: Nexus 5X - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - emulator-build: 7425822 - script: | - adb root - adb logcat -c - touch emulator-session.log - chmod 777 emulator-session.log - adb logcat >> emulator-session.log & - ./gradlew $CI_GRADLE_ARG_PROPERTIES -Pandroid.testInstrumentationRunnerArguments.package='org.matrix.android.sdk.session' matrix-sdk-android:connectedDebugAndroidTest - - name: Read Results [org.matrix.android.sdk.session] - if: always() - id: get-comment-body-session - run: python3 ./tools/ci/render_test_output.py session ./matrix-sdk-android/build/outputs/androidTest-results/connected/*.xml - - name: Remove adb logcat - if: always() - run: pkill -9 adb - - name: Run integration tests for Matrix SDK [org.matrix.android.sdk.account] API[${{ matrix.api-level }}] - if: always() - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ matrix.api-level }} - arch: x86 - profile: Nexus 5X - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - emulator-build: 7425822 - script: | - adb root - adb logcat -c - touch emulator-account.log - chmod 777 emulator-account.log - adb logcat >> emulator-account.log & - ./gradlew $CI_GRADLE_ARG_PROPERTIES -Pandroid.testInstrumentationRunnerArguments.package='org.matrix.android.sdk.account' matrix-sdk-android:connectedDebugAndroidTest - - name: Read Results [org.matrix.android.sdk.account] - if: always() - id: get-comment-body-account - run: python3 ./tools/ci/render_test_output.py account ./matrix-sdk-android/build/outputs/androidTest-results/connected/*.xml - - name: Remove adb logcat - if: always() - run: pkill -9 adb - # package: org.matrix.android.sdk.internal - - name: Run integration tests for Matrix SDK [org.matrix.android.sdk.internal] API[${{ matrix.api-level }}] - if: always() - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ matrix.api-level }} - arch: x86 - profile: Nexus 5X - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - emulator-build: 7425822 - script: | - adb root - adb logcat -c - touch emulator-internal.log - chmod 777 emulator-internal.log - adb logcat >> emulator-internal.log & - ./gradlew $CI_GRADLE_ARG_PROPERTIES -Pandroid.testInstrumentationRunnerArguments.package='org.matrix.android.sdk.internal' matrix-sdk-android:connectedDebugAndroidTest - - name: Read Results [org.matrix.android.sdk.internal] - if: always() - id: get-comment-body-internal - run: python3 ./tools/ci/render_test_output.py internal ./matrix-sdk-android/build/outputs/androidTest-results/connected/*.xml - - name: Remove adb logcat - if: always() - run: pkill -9 adb - # package: org.matrix.android.sdk.ordering - - name: Run integration tests for Matrix SDK [org.matrix.android.sdk.ordering] API[${{ matrix.api-level }}] - if: always() - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ matrix.api-level }} - arch: x86 - profile: Nexus 5X - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - emulator-build: 7425822 - script: | - adb root - adb logcat -c - touch emulator-ordering.log - chmod 777 emulator-ordering.log - adb logcat >> emulator-ordering.log & - ./gradlew $CI_GRADLE_ARG_PROPERTIES -Pandroid.testInstrumentationRunnerArguments.package='org.matrix.android.sdk.ordering' matrix-sdk-android:connectedDebugAndroidTest - - name: Read Results [org.matrix.android.sdk.ordering] - if: always() - id: get-comment-body-ordering - run: python3 ./tools/ci/render_test_output.py ordering ./matrix-sdk-android/build/outputs/androidTest-results/connected/*.xml - - name: Remove adb logcat - if: always() - run: pkill -9 adb - # package: class PermalinkParserTest - - name: Run integration tests for Matrix SDK class [org.matrix.android.sdk.PermalinkParserTest] API[${{ matrix.api-level }}] - if: always() - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ matrix.api-level }} - arch: x86 - profile: Nexus 5X - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - emulator-build: 7425822 - script: | - adb root - adb logcat -c - touch emulator-permalink.log - chmod 777 emulator-permalink.log - adb logcat >> emulator-permalink.log & - ./gradlew $CI_GRADLE_ARG_PROPERTIES -Pandroid.testInstrumentationRunnerArguments.class='org.matrix.android.sdk.PermalinkParserTest' matrix-sdk-android:connectedDebugAndroidTest - - name: Read Results [org.matrix.android.sdk.PermalinkParserTest] - if: always() - id: get-comment-body-permalink - run: python3 ./tools/ci/render_test_output.py permalink ./matrix-sdk-android/build/outputs/androidTest-results/connected/*.xml - - name: Remove adb logcat - if: always() - run: pkill -9 adb - # package: class PermalinkParserTest - - name: Find Comment - if: always() && github.event_name == 'pull_request' - uses: peter-evans/find-comment@v2 - id: fc - with: - issue-number: ${{ github.event.pull_request.number }} - comment-author: 'github-actions[bot]' - body-includes: Integration Tests Results - - name: Publish results to PR - if: always() && github.event_name == 'pull_request' - uses: peter-evans/create-or-update-comment@v2 - with: - comment-id: ${{ steps.fc.outputs.comment-id }} - issue-number: ${{ github.event.pull_request.number }} - body: | - ### Matrix SDK - ## Integration Tests Results: - - `[org.matrix.android.sdk.session]`
${{ steps.get-comment-body-session.outputs.session }} - - `[org.matrix.android.sdk.account]`
${{ steps.get-comment-body-account.outputs.account }} - - `[org.matrix.android.sdk.internal]`
${{ steps.get-comment-body-internal.outputs.internal }} - - `[org.matrix.android.sdk.ordering]`
${{ steps.get-comment-body-ordering.outputs.ordering }} - - `[org.matrix.android.sdk.PermalinkParserTest]`
${{ steps.get-comment-body-permalink.outputs.permalink }} - edit-mode: replace - - name: Upload Test Report Log - uses: actions/upload-artifact@v3 - if: always() - with: - name: integrationtest-error-results - path: | - emulator-permalink.log - emulator-internal.log - emulator-ordering.log - emulator-account.log - emulator-session.log - ui-tests: name: UI Tests (Synapse) needs: should-i-run @@ -282,42 +88,13 @@ jobs: emulator.log failure_screenshots/ - codecov-units: - name: Unit tests with code coverage - needs: should-i-run - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 - with: - distribution: 'adopt' - java-version: '11' - - uses: actions/cache@v3 - 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@v3 - if: always() - with: - name: codecov-xml - path: | - build/reports/jacoco/allCodeCoverageReport/allCodeCoverageReport.xml - # Notify the channel about delayed failures notify: name: Notify matrix runs-on: ubuntu-latest needs: - should-i-run - - integration-tests - ui-tests - - codecov-units if: always() && (needs.should-i-run.result == 'success' ) && ((needs.codecov-units.result != 'success' ) || (needs.ui-tests.result != 'success') || (needs.integration-tests.result != 'success')) # No concurrency required, runs every time on a schedule. steps: diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml deleted file mode 100644 index 6809751d91..0000000000 --- a/.github/workflows/sonarqube.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: Sonarqube nightly - -on: - schedule: - - cron: '0 20 * * *' - -# Enrich gradle.properties for CI/CD -env: - CI_GRADLE_ARG_PROPERTIES: > - -Porg.gradle.jvmargs=-Xmx4g - -Porg.gradle.parallel=false -jobs: - codecov-units: - name: Unit tests with code coverage - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 - with: - distribution: 'adopt' - java-version: '11' - - uses: actions/cache@v3 - 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@v3 - if: always() - with: - name: codecov-xml - path: | - build/reports/jacoco/allCodeCoverageReport/allCodeCoverageReport.xml - - sonarqube: - name: Sonarqube upload - runs-on: ubuntu-latest - needs: - - codecov-units - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 - with: - distribution: 'adopt' - java-version: '11' - - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - uses: actions/download-artifact@v3 - with: - 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 allCodeCoverageReport.xml build/reports/jacoco/allCodeCoverageReport/ - - run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES - env: - ORG_GRADLE_PROJECT_SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }} - -# Notify the channel about sonarqube failures - notify: - name: Notify matrix - runs-on: ubuntu-latest - needs: - - sonarqube - - codecov-units - if: always() && (needs.sonarqube.result != 'success' || needs.codecov-units.result != 'success') - steps: - - uses: michaelkaye/matrix-hookshot-action@v1.0.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - hookshot_url: ${{ secrets.ELEMENT_ANDROID_HOOKSHOT_URL }} - text_template: "Sonarqube run (on ${{ github.ref }}): {{#each job_statuses }}{{#with this }}{{#if completed }} {{name}} {{conclusion}} at {{completed_at}}, {{/if}}{{/with}}{{/each}}" - html_template: "Sonarqube run (on ${{ github.ref }}): {{#each job_statuses }}{{#with this }}{{#if completed }}
{{icon conclusion}} {{name}} {{conclusion}} at {{completed_at}} [details]{{/if}}{{/with}}{{/each}}" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3e8de8979c..f1a801dce6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,73 +12,57 @@ env: -Porg.gradle.parallel=false jobs: - # Build Android Tests - build-android-tests: - name: Build Android Tests - runs-on: ubuntu-latest - concurrency: - group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('build-android-tests-{0}', github.ref) }} - cancel-in-progress: true - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 - with: - distribution: 'adopt' - java-version: 11 - - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - name: Build Android Tests - run: ./gradlew clean assembleAndroidTest $CI_GRADLE_ARG_PROPERTIES --stacktrace - - unit-tests: - name: Run Unit Tests - runs-on: ubuntu-latest + tests: + name: Runs all tests + runs-on: macos-latest # for the emulator # Allow all jobs on main and develop. Just one per PR. concurrency: group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('unit-tests-{0}', github.ref) }} cancel-in-progress: true steps: - uses: actions/checkout@v3 - - uses: actions/cache@v3 with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - name: Run unit tests - run: ./gradlew clean test $CI_GRADLE_ARG_PROPERTIES --stacktrace + fetch-depth: 0 + - uses: actions/setup-java@v3 + with: + distribution: 'adopt' + java-version: '11' + - uses: gradle/gradle-build-action@v2 + - uses: actions/setup-python@v3 + with: + python-version: 3.8 + - uses: michaelkaye/setup-matrix-synapse@v1.0.3 + with: + uploadLogs: true + httpPort: 8080 + disableRateLimiting: true + public_baseurl: "http://10.0.2.2:8080/" + - name: Run all the codecoverage tests at once + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 28 + arch: x86 + profile: Nexus 5X + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + emulator-build: 7425822 + script: ./gradlew theCodeCoverageReport --stacktrace $CI_GRADLE_ARG_PROPERTIES + - run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + ORG_GRADLE_PROJECT_SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }} + - name: Format unit test results if: always() run: python3 ./tools/ci/render_test_output.py unit ./**/build/test-results/**/*.xml - - name: Publish Unit Test Results - uses: EnricoMi/publish-unit-test-result-action@v1 - if: always() && - github.event.sender.login != 'dependabot[bot]' && - ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository ) - with: - files: ./**/build/test-results/**/*.xml - -# Notify the channel about runs against develop or main that have failures, as PRs should have caught these first. - notify: - runs-on: ubuntu-latest - needs: - - unit-tests - - build-android-tests - if: ${{ (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main' ) && failure() }} - steps: - - uses: michaelkaye/matrix-hookshot-action@v0.3.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - matrix_access_token: ${{ secrets.ELEMENT_ANDROID_NOTIFICATION_ACCESS_TOKEN }} - matrix_room_id: ${{ secrets.ELEMENT_ANDROID_INTERNAL_ROOM_ID }} - text_template: "Build is broken for ${{ github.ref }}: {{#each job_statuses }}{{#with this }}{{#if completed }}{{name}} {{conclusion}} at {{completed_at}}, {{/if}}{{/with}}{{/each}}" - html_template: "Build is broken for ${{ github.ref }}: {{#each job_statuses }}{{#with this }}{{#if completed }}
{{icon conclusion }} {{name}} {{conclusion}} at {{completed_at}} [details]{{/if}}{{/with}}{{/each}}" +# - can't be run on macos :| +# - name: Publish Unit Test Results +# uses: EnricoMi/publish-unit-test-result-action@v1 +# if: always() && +# github.event.sender.login != 'dependabot[bot]' && +# ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository ) +# with: +# files: ./**/build/test-results/**/*.xml diff --git a/build.gradle b/build.gradle index 25ff8b91c0..56ad6a69fe 100644 --- a/build.gradle +++ b/build.gradle @@ -177,8 +177,8 @@ apply plugin: 'org.sonarqube' sonarqube { properties { - property "sonar.projectName", "Element-Android" - property "sonar.projectKey", "im.vector.app.android" + property "sonar.projectName", "element-android" + property "sonar.projectKey", "vector-im_element-android" property "sonar.host.url", "https://sonarcloud.io" property "sonar.projectVersion", project(":vector").android.defaultConfig.versionName property "sonar.sourceEncoding", "UTF-8" @@ -188,7 +188,7 @@ sonarqube { 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.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/jacoco/theCodeCoverageReport/theCodeCoverageReport.xml" property "sonar.login", project.hasProperty("SONAR_LOGIN") ? SONAR_LOGIN : "invalid" } } diff --git a/coverage.gradle b/coverage.gradle index b62ce0b4a0..fb2352f47f 100644 --- a/coverage.gradle +++ b/coverage.gradle @@ -2,7 +2,10 @@ def excludes = [ ] def initializeReport(report, projects, classExcludes) { projects.each { project -> project.apply plugin: 'jacoco' } - report.executionData { fileTree(rootProject.rootDir.absolutePath).include("**/build/jacoco/*.exec") } + report.executionData { fileTree(rootProject.rootDir.absolutePath).include( + "**/build/outputs/unit_test_code_coverage/**/*.exec", + "**/build/outputs/code_coverage/**/coverage.ec" + ) } report.reports { xml.enabled true @@ -18,11 +21,13 @@ def initializeReport(report, projects, classExcludes) { switch (project) { case { project.plugins.hasPlugin("com.android.application") }: androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/gplayDebug") + androidSourceDirs.add("${project.buildDir}/generated/source/kapt/gplayDebug") 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/debug") + androidSourceDirs.add("${project.buildDir}/generated/source/kapt/debug") androidSourceDirs.add("${project.projectDir}/src/main/kotlin") androidSourceDirs.add("${project.projectDir}/src/main/java") break @@ -43,13 +48,17 @@ def collectProjects(predicate) { return subprojects.findAll { it.buildFile.isFile() && predicate(it) } } -task allCodeCoverageReport(type: JacocoReport) { +task theCodeCoverageReport(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 } + tasks.withType(Test) { + jacoco.includeNoLocationClasses = true + } + def projects = collectProjects { ['vector','matrix-sdk-android'].contains(it.name) } + dependsOn { + [':matrix-sdk-android:testDebugUnitTest'] + + [':vector:testGplayDebugUnitTest'] + + [':matrix-sdk-android:connectedDebugAndroidTest'] + } initializeReport(it, projects, excludes) } diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 33798d1357..29573b0714 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -74,6 +74,7 @@ android { buildTypes { debug { + testCoverageEnabled true // Set to true to log privacy or sensible data, such as token buildConfigField "boolean", "LOG_PRIVATE_DATA", project.property("vector.debugPrivateData") // Set to BODY instead of NONE to enable logging diff --git a/vector/build.gradle b/vector/build.gradle index 51dfc2f962..30be9425ab 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -244,6 +244,7 @@ android { buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false" signingConfig signingConfigs.debug + testCoverageEnabled true } release {