Gitlab CICD: Tests are not being run as part of the build process, during build stage for Gradle Project resulting in 0% coverage in SonarQube - gradle

I have created a simple project to run a gitlab pipeline, including build, test, coverage, and exporting results in SonarQube. It fails to run the test tasks and therefore no coverage reports are generated.
I have included a build.gradle and a sonar-project.properties file in my gitlab repository as well as the src/main/HelloWorld.java and src/test/HelloWorldTest.java folder. No test-results folder is being generated when running gradle build or gradle test command.
The gitlab-ci.yml file used is the following:
image gradle:latest
stages:
- build
- test
- coverage
- scan
before_script:
- echo $CI_PROJECT_DIR
- echo $CI_BUILDS_DIR
- echo $CI_COMMIT_REF_NAME
build:
stage: build
script:
- gradle clean build
after_script:
- ls
- cd build
artifacts:
paths:
- build/libs
test:
stage: test
before_script:
- echo $CI_PROJECT_DIR
- echo $CI_BUILDS_DIR
- echo $CI_COMMIT_REF_NAME
script:
- gradle test --debug
after_script:
- ls
artifacts:
paths:
- build/test-results
report:
stage: coverage
before_script:
- echo $CI_PROJECT_DIR
- echo $CI_BUILDS_DIR
- echo $CI_COMMIT_REF_NAME
script:
- gradle jacocoTestReport
after_script:
- ls
artifacts:
paths:
- build/reports/jacoco/test/html
- build/reports/jacoco/test/xml
sonarqube-check:
image:
name: sonarsource/sonar-scanner-cli:latest
entrypoint: [""]
stage: scan
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
GIT_DEPTH: "0"
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
before_script:
- echo $CI_PROJECT_DIR
- echo $CI_BUILDS_DIR
- echo $CI_COMMIT_REF_NAME
- echo $CI_JOB_NAME
script:
- sonar-scanner
allow_failure: true
only:
- main
The result following gradle build is:
$ ls
build
build.gradle
README.md
sonar-project.properties
src
No test results folder is created.
The associated build.gradle file is:
plugins {
id 'java'
id 'org.sonarqube' version '2.7'
id 'jacoco'
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.1'
testImplementation 'org.jacoco:org.jacoco.core:0.8.6'
}
test {
useJUnitPlatform()
reports {
junitXml.outputLocation.set(layout.buildDirectory.dir("$buildDir/test-
results/test-junit-xml"))
}
jacoco {
destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
}
}
sonarqube {
properties {
property "sonar.projectName", "imagehelloworld"
property "sonar.projectKey", "imagehelloworld"
property "sonar.sources", "src/main"
property "sonar.tests", "src/test"
property "sonar.junit.reportsPath", "$buildDir/test-results/test"
property "sonar.jacoco.reportPaths",
"$buildDir/jacoco/jacocoTest.exec"
}
}
The output of the build job is as follows:
gradle clean build
Welcome to Gradle 7.6!
Here are the highlights of this release:
- Added support for Java 19.
- Introduced `--rerun` flag for individual task rerun.
- Improved dependency block for test suites to be strongly typed.
- Added a pluggable system for Java toolchains provisioning.
For more details see https://docs.gradle.org/7.6/release-notes.html
Starting a Gradle Daemon (subsequent builds will be faster)
> Task :clean UP-TO-DATE
> Task :compileJava NO-SOURCE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :jar
> Task :assemble
> Task :compileTestJava NO-SOURCE
> Task :processTestResources NO-SOURCE
> Task :testClasses UP-TO-DATE
> Task :test NO-SOURCE
> Task :check UP-TO-DATE
> Task :build
BUILD SUCCESSFUL in 17s

Related

Gradle task output not reused in gitlab for kotlin build

I have created simple kotlin project with gradle build tool and pushed it to gitlab. To speed up pipeline I want to reuse tasks output. So I configured gitlab to cache build folder. Here is gitlab-ci.yml:
stages:
- build
build:
stage: build
image: gradle:7.5.1-jdk17
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
cache:
- key: global-cache # gradle thirdparty artifacts cache
paths:
- /home/gradle/.gradle
- key: $CI_COMMIT_REF_NAME # gradle previous build task output cache
paths:
- build
script:
- ls build/libs
- gradle -version
- gradle build --console=plain
artifacts:
paths:
- build/libs/*.jar
reports:
junit:
- build/test-results/test/TEST-*.xml
expire_in: 1 week
when: always
In pipeline I have executed build job twice(second job run). Since build folder cached my expectation was all tasks will be UP-TO-DATE for second job. Unfortunately, both jobs have same task state:
> Task :compileKotlin
> Task :compileJava NO-SOURCE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :jar
> Task :inspectClassesForKotlinIC
> Task :assemble
> Task :compileTestKotlin
> Task :compileTestJava NO-SOURCE
> Task :processTestResources NO-SOURCE
> Task :testClasses UP-TO-DATE
> Task :test
> Task :check
> Task :build
To debug "jar" task I printed build/lib/ files to console:
$ ls build/libs
gradle-reuse-build-example.jar
You can notice build/libs have cached file inside. Do you have any ideas why jar task isn't UP-TO-DATE? How should I configurate gitlab/gradle to reuse previous job run task output?
Your build fetches the git repo again when running each time(because gitlab uses different shared runner for job execution). That means that the timestamps of the kotlin source files are later than the classes compiled in earlier builds. As a result, the compileKotlin task is not UP-TO-DATE, causing the jar task to also be out of date.
Documentation here: https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:how_does_it_work
As to how to configure the build to do what you want, you may need to look into how to reuse an existing git clone instead of cloning fresh each time. I don't even know if that's possible.

Dev Azure: No code coverage results were found to publish

I'm trying to see my code coverage in my pipeline summary
project details: Java spring
Error: ##[warning]No code coverage results were found to publish.
Pipeline:
- task: Maven#3
displayName: Maven SoftwareEngineeringBackend/pom.xml
inputs:
mavenPOMFile: $(BuildParameters.mavenPOMFile)
goals: "test"
- task: PublishTestResults#2
displayName: "Publish test results"
inputs:
testResultsFormat: "JUnit"
mergeTestResults: true
- task: PublishCodeCoverageResults#1
inputs:
summaryFileLocation: '$(System.DefaultWorkingDirectory)/target/site/jacoco/jacoco.xml'
pathToSources: '$(System.DefaultWorkingDirectory)/src/main/java/'
Firstly check if you have added the Jacoco plugin in your Pom.xml or not. If added then add configuration for it to enable XML report i.e xml.enabled true.
After mvn build process is finished go to the build or target directory and find the path of XML report most probably it will be $(System.DefaultWorkingDirectory)/build/reports/jacoco/test/jacocoTestReport.xml for Gradle and {System.DefaultWorkingDirectory}/**/reports/jacoco/test/jacocoTestReport.xml for Maven
Reference -
https://iamvickyav.medium.com/code-coverage-report-with-jacoco-in-azure-devops-pipeline-395558712977
https://www.lambdatest.com/blog/reporting-code-coverage-using-maven-and-jacoco-plugin/

Cobertura not generating coverage report

I am trying to use cobertura to generate coverage report for my groovy project. I am using gradle to install cobertura ang junit 5
plugins {
id 'java'
id 'groovy'
id 'net.saliman.cobertura' version '2.5.4'
}
dependencies {
implementation 'org.codehaus.groovy:groovy-all:2.4.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
}
test {
useJUnitPlatform()
}
Running the cobertura task generates an empty coverage report (0 classes and no coverage). The jUnit report shows the correct unit test which have been run.
Gralde output
> Task :coberturaReport UP-TO-DATE
> Task :compileJava NO-SOURCE
> Task :compileGroovy
> Task :processResources NO-SOURCE
> Task :classes
> Task :instrument
Cobertura 2.1.1 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
> Task :copyCoberturaDatafile
> Task :compileTestJava NO-SOURCE
> Task :compileTestGroovy
> Task :processTestResources NO-SOURCE
> Task :testClasses
> Task :test
> Task :generateCoberturaReport
Cobertura 2.1.1 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
Report time: 150ms
> Task :performCoverageCheck SKIPPED
> Task :cobertura
BUILD SUCCESSFUL in 11s
6 actionable tasks: 6 executed
07:53:16: Task execution finished 'cobertura'.
What confuses me is the line > Task :performCoverageCheck SKIPPED Is this the problem? How do I enable the coverage check?
After enabling --debug, I found that it is not instrumenting any classes. Adding coverageDirs = ["${buildDir}/classes/groovy/main"] in cobertura as below solved the issues for me.
cobertura {
coverageFormats = ["html", "xml"]
coverageIgnoreTrivial true
coverageCheckHaltOnFailure false
coverageDirs = ["${buildDir}/classes/groovy/main"]
}

Gradle uploadArchives task invoked for module even though explicitly not configured

I have a Java Gradle 2.14.1 project with a few subprojects: a, b, c and no. no is 'special' as it doesn't contain anything in src/main/java, it just has some e2e tests using all the modules. I want to apply the maven plugin to a, b and c, but not to no. Here is my code (in the form of a Bash session; please ignore the fact there is no code - it is the simplest thing which reproduces my issue):
maven-test $ find .
.
./a
./b
./build.gradle
./c
./gradle
./gradle/wrapper
./gradle/wrapper/gradle-wrapper.jar
./gradle/wrapper/gradle-wrapper.properties
./gradle.properties
./gradlew
./gradlew.bat
./no
./no/build.gradle
./settings.gradle
maven-test $ cat settings.gradle
rootProject.name = 'maven-test'
include ':a'
include ':b'
include ':c'
include ':no'
maven-test $ cat build.gradle
subprojects {
apply plugin: 'java'
if (it != project(':no')) {
println 'applying maven for ' + it
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: "file://build")
}
}
}
} else {
println 'not applying maven for ' + it
}
defaultTasks = ['clean', 'build']
afterEvaluate { project ->
println("================ $project.path tasks:")
project.tasks.each { task ->
println(" $task.name")
}
}
}
task wrapper(type: Wrapper) {
gradleVersion = '2.14.1'
}
maven-test $ cat no/build.gradle
jar.enabled = false
I.e. the no/build.gradle file disables the jar task (as there is nothing to jar). The main build.gradle file configures the java and maven plugins, but the maven plugin is explicitly omitted from the no module. Also, there is some debugging output added to see what is going on.
Here is the output (a bit chatty, I hope it is Ok):
maven-test $ ./gradlew clean uploadArchives
applying maven for project ':a'
applying maven for project ':b'
applying maven for project ':c'
not applying maven for project ':no'
================ :a tasks:
assemble
build
buildDependents
buildNeeded
check
classes
clean
compileJava
compileTestJava
install
jar
javadoc
processResources
processTestResources
test
testClasses
uploadArchives
================ :b tasks:
assemble
build
buildDependents
buildNeeded
check
classes
clean
compileJava
compileTestJava
install
jar
javadoc
processResources
processTestResources
test
testClasses
uploadArchives
================ :c tasks:
assemble
build
buildDependents
buildNeeded
check
classes
clean
compileJava
compileTestJava
install
jar
javadoc
processResources
processTestResources
test
testClasses
uploadArchives
================ :no tasks:
assemble
build
buildDependents
buildNeeded
check
classes
clean
compileJava
compileTestJava
jar
javadoc
processResources
processTestResources
test
testClasses
:a:clean
:b:clean
:c:clean
:no:clean
:a:compileJava UP-TO-DATE
:a:processResources UP-TO-DATE
:a:classes UP-TO-DATE
:a:jar
:a:uploadArchives
:b:compileJava UP-TO-DATE
:b:processResources UP-TO-DATE
:b:classes UP-TO-DATE
:b:jar
:b:uploadArchives
:c:compileJava UP-TO-DATE
:c:processResources UP-TO-DATE
:c:classes UP-TO-DATE
:c:jar
:c:uploadArchives
:no:compileJava UP-TO-DATE
:no:processResources UP-TO-DATE
:no:classes UP-TO-DATE
:no:jar SKIPPED
:no:uploadArchives FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':no:uploadArchives'.
> Could not publish configuration 'archives'
> Cannot publish artifact 'no.jar (com.test:no:0.1.0-SNAPSHOT)' (/Users/wujek/Development/IdeaProjects/maven-test/no/build/libs/no-0.1.0-SNAPSHOT.jar) as it does not exist.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 1.145 secs
What is interesting is: the output says the maven plugin is not configured for the no module (not applying maven for project :no), the uploadArchives task is not listed for the :no module, but in the Gradle output is still says this task is invoked and it fails. I can also invoke this 'phantom' task directly using ./gradlew :no:uploadArchives and it fails the same way instead of telling me the task is missing.
What is wrong with my configuration?

Gradle : Copy different properties file depending on the environment and create jar

I am evaluating gradle for my spring boot project. Everything seems to work but here is where I am stuck. I have 2 properties file. One for prod i.e.:
application_prod.properties
and another for qa i.e.:
application_qa.properties
My requirement is such that while I build (create jar file) the project from gradle, I've to rename the properties file to
application.properties
and then build the jar file. As far as I know, gradle has a default build task. So here I've to override it such that it considers only the required properties file and rename it and then build depending on the environment.
How can I achieve this?
What you need to do is to override processResources configuration:
processResources {
def profile = (project.hasProperty('profile') ? project.profile : 'qa').toLowerCase()
include "**/application_${profile}.properties"
rename {
'application.properties'
}
}
With the following piece of code changed you will get the output below:
$ ./gradlew run -Pprofile=PROD
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
LOL
Profile: PROD
BUILD SUCCESSFUL
Total time: 3.63 secs
$ ./gradlew run -Pprofile=QA
:compileJava UP-TO-DATE
:processResources
:classes
:run
LOL
Profile: QA
BUILD SUCCESSFUL
Total time: 3.686 secs
$ ./gradlew run
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
LOL
Profile: QA
BUILD SUCCESSFUL
Total time: 3.701 secs
Demo is here.

Resources