Sonarqube 8.4.1 branch analysis, definition of new ?!

Hi,

this is related to

and

Happy to see Sonarqube 8.4.1 with the changes of https://jira.sonarsource.com/browse/MMF-1994

Unfortunately after the first tests, i have to say it’s only half the job done and still not really usable for legacy projects without PR workflows.
Our generic Jenkins pipelines currently running with Sonarqube 7.9.1 simply use the
Jenkins $BRANCH_NAME as sonar.branch.name with the default sonar.branch.target = master
and only new conditions in quality gate for legacy projects.
If there is only one new issue on the branch the build fails with quality gate status red.

To achieve the same behaviour with Sonarqube 8.4.1 i need to have a project setting that sets
the main branch as reference for ALL branches.

If using

sq841_referencebranch

it works great for all branches, but

this means no more issues on main branch because

As the web api api/new_code_periods/set can only be used after the branch exists, i see no solution.
In fact you need an useless initial analysis creating the branch to be able to set the main
branch as reference. After that a second analysis of the branch shows the issues as expected.

Suggestion => if the project setting would work without affecting the main branch also it would be OK to go with the project setting.
Did i miss anything, is there a solution | workaround ?

If there would only be one analysis at a time, i could change the new code project setting via web api,
$BRANCH_NAME == ‘master’ ? set previous_version : set reference branch master
But there are parallel builds and analysis of different branches of the same project.

Gilbert

Think i’ve found a working hack.

  1. api/projects/search?projects to check if project already exists

  2. api/projects/create if it doesn’t exist

  3. api/new_code_periods/set?project=$projectkey&type=REFERENCE_BRANCH&value=master

  4. api/new_code_periods/set?project=$projectkey&branch=master&type=PREVIOUS_VERSION

  5. run Sonarqube analysis

Thought 3. would not be possible if project is newly created in 2. ,but it is.
Should also be almost safe for parallel builds and scans of the same project !?

After all this is no clean solution, hope it gets polished with the next versions !!

Out of curiousity
What were the reasons to break with the use of the sonar.branch.target property ??

May I ask above mentioned api shall be put at where?

Welcome :slight_smile:

you may use the rest api calls with i.e. cURL, postman … or any language as Groovy, Python …
or if only GET is involved also from the browser.
I use it as Jenkins shared library for our pipelines like that =

// vars/sqRest.groovy

import groovy.json.*
@NonCPS
def call(url, method, apitoken) {
  println "sqRest => " + url
  def jsonSlurper = new JsonSlurperClassic()
  raw = apitoken + ':'
  bauth = 'Basic ' + javax.xml.bind.DatatypeConverter.printBase64Binary(raw.getBytes())
  def conn = new URL(url).openConnection() as HttpURLConnection
  conn.setRequestMethod(method)
  conn.setRequestProperty("Authorization", bauth)
  conn.connect()
  httpstatus = conn.responseCode
  println "sqRest ResponseCode = $httpstatus \nContent length = " + conn.getContentLength()
  if(0 < conn.getContentLength()) {
   def object = jsonSlurper.parseText(conn.content.text)
  }
}

in the pipeline it looks like that i.e.

sqRest("https://${sonarhost}/api/projects/search?projects=${groupId + ':' + it}", 'GET', sonarapitoken)
[...]
println("Set $p.sonarReferenceBranch as reference for branch $BRANCH_NAME")
sqRest("https://${sonarhost}/api/new_code_periods/set?project=${groupId + ':' + it}&branch=$BRANCH_NAME&type=REFERENCE_BRANCH&value=$p.sonarReferenceBranch", 'POST', sonarapitoken)
[...]

or using this shared lib in another shared lib

// vars/sqGetBranches.groovy

def call(sonarhost, sqprojectkey, method, apitoken) {
  list=[]
  sqRest("https://${sonarhost}/api/project_branches/list?project=$sqprojectkey", 'GET', apitoken).branches.each { 
    list.add(it.name)
  }
  return list
}

or

// vars/sqGetMainBranch.groovy

def call(sonarhost, sqprojectkey, method, apitoken) {
  for (branch in sqRest("https://${sonarhost}/api/project_branches/list?project=$sqprojectkey", 'GET', apitoken).branches) {
    if (branch.isMain) return branch.name
  }
}

see https://yoursonarhost/web_api for the web api documentation.
You should update to Sonarqube 8.9.1 LTS or the latest 9.0.

Gilbert

Thanks a lot! @Rebse
For my case, we are not rely on Jenkins.

Would it be possible if you can help to take a look on my concerns over there?Automate Branch level New Code definition