Configure gitlab CI for SonarQube with python projects

Hugo
3 min readOct 8, 2019

--

This blogpost is inspired by https://dev.to/mmphego/how-i-configured-sonarqube-for-python-code-analysis-with-jenkins-and-docker-28fm, and while working on it, I found the information is very trivial for gitlab CI.

Step 1: Activate pylint rules in Quality Profile

In my situation, sonarqube server is ready. We use it for java projects already, and the first thing is to activate pylint rules. Go to Quality Profiles tab, at the python panel, you have to create a new Quality Profile and activate pylint rules manually. Otherwise sonarqube server will not analyze the pylint report you upload later.

Inherit it from “Sonar Way”. Then activate in rules from Pylint rules repository.

You should see as the following picture after creating Quality Profile

ref:

Step 2: test locally

You can test first locally and it’s more convenient. So let’s start uploading the report from local.

Get coverage report by

(venv) my-terminal: pytest --cov-branch --cov=app tests/ --cov-report xml:coverage.xml

Get pylint report by

(venv) my-terminal: pylint app/ tests/ -r n — msg-template=”{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}” | tee pylint.txt

Note there is a space after the second colon(:)

Uploading report to sonar requires using sonar-scanner. You have to install it and then set the path. In my ubuntu, sonar-scanner is set in the file .bash_aliases

alias sonar-scanner=”~/Documents/sonar-scanner-4.0.0.1744-linux/bin/sonar-scanner”

and then you can run

sonar-scanner -Dsonar.projectKey=YOURPROJECT -Dsonar.python.pylint.reportPath=pylint.txt -Dsonar.host.url=YOUR_SONARQUBE_URL. -Dsonar.login=YOUR_LOGIN -Dsonar.language=py -Dsonar.python.xunit.reportPath=nosetests.xml -Dsonar.python.coverage.reportPaths=coverage.xml -Dsonar.sources=. -Dsonar.coverage.exclusions=**__init__**,tests/**,*.py -Dsonar.exclusions=*.xml

If you see the report, congrats! If not, check the Quality Profiles in the project page you just created, and it perhaps does not use pylint, but uses the default soanr-python. The Quality File must use the new one that you created before and pylint rules are activated.

Step 3: gitlab CI

OK! now locally works. The CI pipeline looks like below. Note that the image you use must have sonar-scanner installed

sonar-develop:
image: PYTHON_IMG_WITH_SONAR_SCANNER
stage: sonar
script:
- pip3 install -r requirements.txt
- pip3 install pytest pylint
- pytest --cov-branch --cov=app tests/ --cov-report xml:coverage.xml
- 'pylint --exit-zero app/ tests/ -r n --msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" | tee pylint.txt' - pylint app/ tests/ -r n --msg-template="{path}':'{line}':' [{msg_id}({symbol}), {obj}] {msg}" | tee pylint.txt'
- sonar-scanner -Dsonar.python.xunit.reportPath=nosetests.xml -Dsonar.python.coverage.reportPaths=coverage.xml
-- -Dsonar.sources=. -Dsonar.coverage.exclusions=**__init__**,tests/**,config.py,manage.py -Dsonar.exclusions=*.xml
-- -Dsonar.python.pylint.reportPath=pylint.txt -Dsonar.language=py
-- -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN
-- -Dsonar.gitlab.project_id=${CI_PROJECT_NAMESPACE}/$CI_PROJECT_ID
-- -Dsonar.projectName=${CI_PROJECT_NAMESPACE}-${CI_PROJECT_NAME}
-- -Dsonar.projectKey=${CI_PROJECT_NAMESPACE}-${CI_PROJECT_NAME}
-- -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
-- -Dsonar.gitlab.url=$CI_PROJECT_URL -Dsonar.gitlab.project_id=$CI_PROJECT_ID

only:
refs:
- develop
- merge_requests
except:
refs:
- tags
when: manual

The critical part here is colon after a space (: ) in pylint command, so this command needs to be wrapped with quotes. Also note that

pylint --exit-zero

So it properly exits and pipeline can then success.

If you are confused about what to include and what to exclude, please refer to the following document from SonarQube.

For example, my application is flask, so coverage should exclude anything like

Dsonar.coverage.exclusions=**__init__**,tests/**,config.py,manage.py

and pylint should include

pylint app/ tests/

Sign up to discover human stories that deepen your understanding of the world.

--

--

No responses yet

Write a response