Once with running docker images inside a continuation integration pipeline, things got to a new level.
One improvement, we can see it for static code analysis, where there is no need of having a separate instance of sonar, we can have it on the fly.
So, to have a step for this scenario, the CI pipeline, will need to:
- lunch a Sonar instance
- maybe add some configurations/plugins
- run static analysis with the sonar instance
- using Sonar API to retrieve the entire coverage
- docker run -d --name sonarqube-$CI_BUILD_ID sonarqube
# if we want to add a plugin just copy it to the running image / eg. sonar
- wget https://github.com/gabrie-allaigre/sonar-gitlab-plugin/releases/download/3.0.2/sonar-gitlab-plugin-3.0.2.jar
- docker cp sonar-gitlab-plugin-3.0.2.jar sonarqube-$CI_BUILD_ID:/opt/sonarqube/extensions/plugins/sonar-gitlab-plugin-3.0.2.jar
- docker restart sonarqube-$CI_BUILD_ID
# normal step run test & sonar analysis, giving the path to the sonar instance
- export SONAR_IP=`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' sonarqube-$CI_BUILD_ID`
- ./gradlew test sonarqube -Dsonar.host.url=http://$SONAR_IP:9000
The additional scripts used by this step are the following:
generate-sonar-token.sh
#!/bin/bash
# Inspired from https://gist.github.com/cjus/1047794
SONAR_IP=$1
PROP=$2
NAME=$3
function jsonval {
temp=`echo $json | sed 's/\\\\\//\//g' | sed 's/[{}]//g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | sed 's/\"\:\"/\|/g' | sed 's/[\,]/ /g' | sed 's/\"//g' | grep -w $PROP`
echo ${temp##*|}
}
json=`curl -u admin:admin -d "name=$NAME" -H "Content-Type: application/x-www-form-urlencoded" -X POST http://$SONAR_IP:9000/api/user_tokens/generate`
data=`jsonval`
echo $data
And `validate-sonar.sh` uses two scripts (maybe with time I will update them)
- The bash scripts calls a specific python script with the coverage details retrieved from SONAR
#!/bin/bash
SONAR_TOKEN=$1
SONAR_URL=$2
sonar=$(curl -u $SONAR_TOKEN: "$2/api/measures/component?component=d2&metricKeys=coverage")
echo $sonar
exitValue=$(python ci/sonar-coverage.py $sonar 2>&1)
echo $exitValue
exit $exitValue
The python script `sonar-coverage.py` will validate if the coverage retrieved from sonar fulfills or not, the expected value of the project
import json
import sys
from decimal import Decimal
resp = json.loads(sys.argv[1])
# extract the coverage value
val = Decimal(resp['component']['measures'][0]['value'])
if val >= 80:
print 0
else:
print 1
When the entire step is finished, it will be nice to do some cleanup.
after_script:
- docker stop sonarqube-$CI_BUILD_ID
- docker rm sonarqube-$CI_BUILD_ID