diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml new file mode 100644 index 000000000..4c3ba695b --- /dev/null +++ b/.github/workflows/sonar.yml @@ -0,0 +1,35 @@ +name: Sonar Analysis + +on: + push: + branches: + - main + - v3-next + pull_request: + types: [opened, synchronize, reopened] +jobs: + build: + name: Build and analyze + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: 'temurin' + - name: Cache SonarCloud packages + uses: actions/cache@v3 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + - name: Build and analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: ./gradlew clean build test codeCoverageReport \ No newline at end of file diff --git a/build.gradle b/build.gradle index 2e53adecb..80e79873f 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,8 @@ plugins { id 'java' id 'org.springframework.boot' version '3.1.5' apply false id 'io.spring.dependency-management' version '1.1.4' apply false + id 'jacoco' + id "org.sonarqube" version "4.4.1.3373" } allprojects { @@ -12,6 +14,17 @@ allprojects { } subprojects { + apply plugin: 'org.sonarqube' + sonar { + properties { + property 'sonar.coverage.jacoco.xmlReportPaths', "$projectDir.parentFile.path/build/reports/jacoco/codeCoverageReport/codeCoverageReport.xml" + } + } + + tasks.withType(Test).configureEach { + useJUnitPlatform() + } + compileJava { options.release = 17 } @@ -22,6 +35,47 @@ subprojects { } } +apply from: "$project.rootDir/sonar.gradle" + +// See here for more info: https://docs.gradle.org/6.4-rc-1/samples/sample_jvm_multi_project_with_code_coverage.html +// +// task to gather code coverage from multiple subprojects +// NOTE: the `JacocoReport` tasks do *not* depend on the `test` task by default. Meaning you have to ensure +// that `test` (or other tasks generating code coverage) run before generating the report. +// You can achieve this by calling the `test` lifecycle task manually +// $ ./gradlew test codeCoverageReport +tasks.register("codeCoverageReport", JacocoReport) { + // If a subproject applies the 'jacoco' plugin, add the result it to the report + subprojects { subproject -> + subproject.plugins.withType(JacocoPlugin).configureEach { + subproject.tasks.matching({ t -> t.extensions.findByType(JacocoTaskExtension) }).configureEach { testTask -> + //the jacoco extension may be disabled for some projects + if (testTask.extensions.getByType(JacocoTaskExtension).isEnabled()) { + sourceSets subproject.sourceSets.main + executionData(testTask) + } else { + logger.warn('Jacoco extension is disabled for test task \'{}\' in project \'{}\'. this test task will be excluded from jacoco report.',testTask.getName(),subproject.getName()) + } + } + + // To automatically run `test` every time `./gradlew codeCoverageReport` is called, + // you may want to set up a task dependency between them as shown below. + // Note that this requires the `test` tasks to be resolved eagerly (see `forEach`) which + // may have a negative effect on the configuration time of your build. + subproject.tasks.matching({ t -> t.extensions.findByType(JacocoTaskExtension) }).forEach { + rootProject.tasks.codeCoverageReport.dependsOn(it) + } + } + } + + // enable the different report types (html, xml, csv) + reports { + xml.required = true + html.required = true + html.outputLocation = layout.buildDirectory.dir('jacocoHtml') + } +} + tasks.register('printVersion') { doLast { println project.version diff --git a/eno-core/build.gradle b/eno-core/build.gradle index 373e5d5a2..17029d8d8 100644 --- a/eno-core/build.gradle +++ b/eno-core/build.gradle @@ -3,6 +3,7 @@ plugins { id 'io.spring.dependency-management' id 'java-library' id 'maven-publish' + id 'jacoco' } // https://stackoverflow.com/a/61671513/13425151 diff --git a/eno-treatments/build.gradle b/eno-treatments/build.gradle index d8ac9508a..319c2ce45 100644 --- a/eno-treatments/build.gradle +++ b/eno-treatments/build.gradle @@ -3,6 +3,7 @@ plugins { id 'io.spring.dependency-management' id 'java-library' id 'maven-publish' + id 'jacoco' } // https://stackoverflow.com/a/61671513/13425151 diff --git a/eno-ws/build.gradle b/eno-ws/build.gradle index 215866ebe..4b6aceffb 100644 --- a/eno-ws/build.gradle +++ b/eno-ws/build.gradle @@ -4,6 +4,7 @@ plugins { id 'io.spring.dependency-management' id 'java' id 'maven-publish' + id 'jacoco' } ext { diff --git a/sonar.gradle b/sonar.gradle new file mode 100644 index 000000000..521436cdb --- /dev/null +++ b/sonar.gradle @@ -0,0 +1,9 @@ +apply plugin: "org.sonarqube" + +sonar { + properties { + property 'sonar.projectKey', 'InseeFr_Eno' + property 'sonar.host.url', 'https://sonarcloud.io' + property 'sonar.organization', 'inseefr' + } +} \ No newline at end of file