Analysing a Java Gradle project on SonarQube.com with Travis CI - java

I have a Java Gradle projet hosted on GitHub and connected to travis CI.
On the root of this project, I have:
.travis.yml
language: java
addons:
sonarqube: true
env:
global:
- secure: <the token generated on sonarqube.com>
script:
gradle check
.sonarsource.properties
wallboard.teamAtSonarSource=support
sonar.host.url=http://sonarqube.com
build.gradle
// Uses DSL plugins resolution introduced in Gradle 2.1
plugins {
id "java"
id "jacoco"
id "org.sonarqube" version "1.2"
}
sonarqube {
properties {
property "sonar.projectName", "Java :: Simple Project :: SonarQube Scanner for Gradle"
property "sonar.projectKey", "org.sonarqube:java-gradle-simple"
property "sonar.jacoco.reportPath", "${project.buildDir}/jacoco/test.exec"
}
}
allprojects {
ext.baseVersion = "0.1"
ext.snapshotVersion = true
group = "org.sonarqube"
version = "$baseVersion" + (snapshotVersion ? "-SNAPSHOT" : "")
}
test {
ignoreFailures = true
}
dependencies {
testCompile 'junit:junit:4.12'
}
repositories {
repositories {
maven {
url "http://repo1.maven.org/maven2/"
}
maven {
url "https://plugins.gradle.org/m2/"
}
}
}
I found this one on SonarSource example repo
The travis CI pass but the sonarqube.com analysis do not run. I am new to Travis, SonarQube and Gradle, so I don't know where exactly I am wrong.
Edit: Here is the Travis logs.

SonarQube analysis is not executed. You have to call it explicitly. Something like:
gradle sonarqube
Please read the documentation for the SonarQube Scanner for Gradle.

First, you should create a token at sonarqube.com. It is under My Account > security.
Then you need to add the token to your sonar properties as
sonar.login=XXX
You may also need to change the url to https.
One thing to note is the token is unsecure. To secure the token follow this guide. You will have to pass the token as a variable to gradle. I believe you can do this with -Psonar.login=$SONAR_TOKEN.

Related

Fail to download sonar-scanner-engine-shaded when run gradle sonarqube from gitlab ci

When I run gradle sonarqube analysis script from Gitlab ci it give me this exception:
Caused by: java.lang.IllegalStateException: Fail to download sonar-scanner-engine-shaded-9.5.0.56709-all.jar to /builds/sof/sonargitlab/.sonar/cache/_tmp/fileCache2921953783035814983.tmp
Hint:
I am using sonarqube9.5 community edition (running image inside docker)
using also gradle 7.4 and java 11
.gitlab-ci.yml
sonarqube-check:
image: gradle:jre11-slim
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
script: gradle sonarqube --stacktrace
allow_failure: true
only:
- merge_requests
- master # or the name of your main branch
- develop
build.gradle:
plugins {
// Apply the java-library plugin for API and implementation separation.
id 'java-library'
id "org.sonarqube" version "3.4.0.2513"
}
sonarqube {
properties {
property "sonar.projectKey", "sof_sonargitlab_AYIwGR4bXnOfnO3zK2VU"
property "sonar.qualitygate.wait", true
}
}
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}
dependencies {
// Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:30.1.1-jre'
}
tasks.named('test') {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
}

Dependency hosted in GitLab's maven repository is not found during pipelines job

I'm encountering a very weird issue. When I build my plugin on my computer everything works fine. But when the plugin is build in the GitLab's pipeline, the build fails saying there's a dependency not found.
Caused by: org.gradle.internal.resolve.ModuleVersionNotFoundException: Could not find any matches for fr.group:theplugin:5.0.+ as no versions of fr.group:theplugin are available.
Searched in the following locations:
- https://gitlab.com/api/v4/groups/GROUP-ID/-/packages/maven/fr/group/theplugin/maven-metadata.xml
I'm using GitLab's maven repository (Package registry) to host artefacts of my own minecraft plugins. The dependency not found is hosted in the package registry. I've tried to remove all my gradle cache and build again on my computer. The dependency was downloaded as expected. So this makes me say that the artefact is available in the package registry.
My installed gradle version is the same as the wrapper (gradle 6.5.1). I've also tried to run the wrapper on my computer just in case and it works fine too.
Here's my build.gradle:
// Build plugins
plugins {
id 'maven-publish'
id 'java'
}
// Upstream Maven repositories
repositories {
mavenCentral()
maven {//Dependencies on the Gitlab's group
url "https://gitlab.com/api/v4/groups/GROUP-ID/-/packages/maven"
name "GitLab"
credentials(HttpHeaderCredentials) {
name = 'Private-Token'
value = gitLabPrivateToken
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
group = 'fr.mygroup'
version = 1.0.0
dependencies {
compileOnly group: 'fr.group', name:'theplugin', version: '5.0.+', transitive: false
}
compileJava {
sourceCompatibility = '1.8'
options.encoding = 'UTF-8'
}
// Maven publish
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
repositories {
maven {
url "https://gitlab.com/api/v4/projects/PROJECT-ID/packages/maven"
credentials(HttpHeaderCredentials) {
name = "Private-Token"
value = gitLabPrivateToken
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
}
Of course I've replaced GROUP-ID and PROJECT-ID in my real build.gradle.
And here is my .gitlab-ci.yml:
image: java:8
before_script:
- chmod +x gradlew
stages:
- build
- test
- publish
# Build stage
build:
only:
- tags
tags:
- docker
stage: build
script:
- ./gradlew -g /cache/.gradle clean assemble -PgitLabPrivateToken=$CI_CUSTOM_TOKEN
allow_failure: false
# Use the generated build output to run the tests.
test:
only:
- tags
tags:
- docker
stage: test
script:
- ./gradlew -g /cache/.gradle check -PgitLabPrivateToken=$CI_CUSTOM_TOKEN
# Publish the artifact to GitLab
publish:
only:
- tags
tags:
- docker
stage: publish
script:
- ./gradlew -g /cache/.gradle clean publish -PgitLabPrivateToken=$CI_CUSTOM_TOKEN
The CI_CUSTOM_TOKEN environment variable contains a personal access token with the scope api of a GitLab's account that is at least maintainer (maybe owner I don't remember) in the GitLab's group in question.
I've tried to create a new GitLab group in witch I've cloned the plugin I'm trying to build, I've created the same CI_CUSTOM_TOKEN environement variable, then I runned a pipeline and it perfectly worked.
Please let me know if something is not clear or if you need more information.
Thank you for reading and maybe helping (I hope)
Have a nice day !
The problem was that the option Protect variable was checked in the CI_CUSTOM_TOKEN environement variable. In consequencies the variable was not passed to pipelines triggered by not protected tags. What's weird is that I should have had a permissions error or something but it just said the dependency was no found.
Anyway, I unchecked the option and now it's perfectly working.

Why is springBoot {} not found?

I have a build script that looks something like this:
plugins {
id("org.springframework.boot") version "2.2.2.RELEASE" apply false
id("io.spring.dependency-management") version "1.0.9.RELEASE" apply false
id("java")
}
repositories {
mavenCentral()
}
allprojects {
// ...
}
project("core") {
apply(plugin = "org.springframework.boot")
apply(plugin = "io.spring.dependency-management") // plugin to manage spring dependencies
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
springBoot {
mainClassName = "com.example.App"
}
}
However, when building, gradle complains that
springBoot {
^ Unresolved reference: springBoot
If I remove the apply false on the spring plugins in the plugins {} block everything works fine.
What I don't understand is that why springBoot{} can't be resolved even if I have called apply(plugin = ) for spring boot in the "core" subproject?
My understanding is that in plugins {} I imported the plugins into the project but not apply it yet. Later in core subproject I apply the plugins and configure spring boot.
From the grade doc https://docs.gradle.org/current/userguide/kotlin_dsl.html#type-safe-accessors
The build script can not use type-safe accessors in this case because the apply() call happens in the body of the build script. You have to use other techniques instead, as demonstrated here:
Type-safe accessors are unavailable for model elements contributed by the following:
Plugins applied via the apply(plugin = "id") method
The project build script
Script plugins, via apply(from = "script-plugin.gradle.kts")
Plugins applied via cross-project configuration
You have to use configure option like below,
configure<SpringBootExtension> {
mainClassName = “ com.example.App”
}

Unable to run Gradle app engine tasks

I'm really confused about converting an old Google App Engine project to Gradle.
I'm trying to follow the instructions on this page. It advises to start with this build script:
buildscript { // Configuration for building
repositories {
jcenter() // Bintray's repository - a fast Maven Central mirror & more
mavenCentral()
}
dependencies {
classpath 'com.google.cloud.tools:appengine-gradle-plugin:+' // latest App Engine Gradle tasks
}
}
repositories { // repositories for Jar's you access in your code
maven {
url 'https://maven-central.storage.googleapis.com' // Google's mirror of Maven Central
// url 'https://oss.sonatype.org/content/repositories/snapshots' // SNAPSHOT Repository (if needed)
}
jcenter()
mavenCentral()
}
apply plugin: 'java' // standard Java tasks
apply plugin: 'war' // standard Web Archive plugin
apply plugin: 'com.google.cloud.tools.appengine' // App Engine tasks
dependencies {
providedCompile group: 'javax.servlet', name: 'servlet-api', version:'2.5'
compile 'com.google.appengine:appengine:+'
// Add your dependencies here.
}
appengine { // App Engine tasks configuration
run { // local (dev_appserver) configuration (standard environments only)
port = 8080 // default
}
deploy { // deploy configuration
stopPreviousVersion = true // default - stop the current version
promote = true // default - & make this the current version
}
}
group = 'com.example.appengine' // Generated output GroupId
version = '1.0-SNAPSHOT' // Version in generated output
sourceCompatibility = 1.7 // App Engine Standard uses Java 7
targetCompatibility = 1.7 // App Engine Standard uses Java 7
However it doesn't work:
$ gradle appengineRun
FAILURE: Build failed with an exception.
* Where:
Build file '/path/to/myproject/build.gradle' line: 32
* What went wrong:
A problem occurred evaluating root project 'myproject'.
> Could not find method run() for arguments [build_c1i62diotjttavcmtjg1zqlbd$_run_closure3$_closure5#33f17289] on root project 'myproject' of type org.gradle.api.Project.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Shouldn't the dependencies be downloaded to make the custom appengine task configuration work?
Please have a look at the sources of the plugin. When the core plugin is applied it decides whether to apply a flexible or standard appengine plugin. Since there's probably no src/main/webapp/WEB-INF/appengine-web.xml flexible plugin is applied which does not create the extension that fails (FYI, this extension is created here). To fix the problem run:
mkdir -p src/main/webapp/WEB-INF
and then:
touch src/main/webapp/WEB-INF/appengine-web.xml
in console where build.gradle is located. This will solve the problem. Poor documentation :/

Android - Jacoco code coverage ignores Robolectric tests

Trying to get Code coverage on my Robolectric tests in Android utilising Jacoco but it simply refuses to acknowledge my Robolectric tests when creating the reports.
My jacoco.gradle file is as follows:
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.7.6.201602180812"
}
project.afterEvaluate {
android.applicationVariants.all { variant ->
def name = variant.name
def testTaskName = "test${name.capitalize()}UnitTest"
tasks.create(name: "${testTaskName}Coverage", type: JacocoReport, dependsOn: "$testTaskName") {
group = "Reporting"
description = "Generate Jacoco coverage reports for the ${name.capitalize()} build."
classDirectories = fileTree(
dir: "${project.buildDir}/intermediates/classes/${name}",
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
'**/BuildConfig.*',
'**/Manifest*.*']
)
sourceDirectories = files(['src/main/java'].plus(android.sourceSets[name].java.srcDirs))
executionData = files("${project.buildDir}/jacoco/${testTaskName}.exec")
reports {
xml.enabled = true
html.enabled = true
}
}
}
}
With this setup I can get Coverage reports but I get 0% coverage despite having Robolectric tests in "src/test/java".
If I add in the following code to that file:
android {
testOptions {
unitTests.all {
jacoco {
includeNoLocationClasses = true
}
}
}
}
I get the following error when Gradle tries to sync:
Error:No such property: includeNoLocationClasses for class:
org.gradle.testing.jacoco.plugins.JacocoTaskExtension_Decorated
I know that I need to have Gradle 2.13 to use this includeNoLocationClasses value so in graddle-wrapper.properties I have the following:
#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions-snapshots/gradle-2.13-20160228000026+0000-all.zip
I am pretty certain I am running Gradle 2.13 with Android plugin version 1.5
In my apps Gradle file I have the following:
//...
apply from: 'jacoco.gradle'
//..
testOptions {
unitTests.returnDefaultValues = true
}
//...
debug {
testCoverageEnabled true
}
And the command I use to run the coverage is:
./gradlew createDebugCoverageReport
So I am wondering why I get the includeNoLocationClasses error despite using the correct Gradle version? And outside of that maybe I am doing something wrong where Jacoco isn't picking up the Robolectric tests in src/test.java ?
I don't see you build.gradle completely, but to have that flag in you have to:
Use gradle 2.13+
Use jacoco 0.7.6.201602180812
You're sure that you use gradle proper version. So, I think, the issue is only in using wrong jacoco.
Mentioning jacoco {toolVersion = "0.7.6.201602180812"} doesn't influence gradle DSL. You should add newer jacoco plugin:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.jacoco:org.jacoco.core:...'
}
}
And you should apply plugin, which you're already doing:
apply from: 'jacoco'
After such configuraiton you don't need jacoco {toolVersion = "..."} more.
Note: consider to update to newer android gradle plugin, 2.2.x is already stable. jacoco also has newer version already 0.7.7.201606060606
One more note: if you see original issue in Android Studio, check that you use wrapper by default and check that you pointed wrapper to gradle 2.13

Categories

Resources