跳至主要内容

SonarQube Gitlab Integration

SonarQube Gitlab Integration

In order to improve the code quality, our team decided to install the SonarQube to do the static code analysis.

Easy Install

The installation can be done very easily using docker compose:

version: "2"

services:
  sonarqube:
    image: sonarqube
    ports:
      - "9002:9000"
    environment:
      - SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar
    volumes:
      - ./sonarqube_conf:/opt/sonarqube/conf
      - ./sonarqube_data:/opt/sonarqube/data
      - ./sonarqube_extensions:/opt/sonarqube/extensions
      - ./sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins

  db:
    image: postgres
    environment:
      - POSTGRES_USER=sonar
      - POSTGRES_PASSWORD=sonar
    volumes:
      - ./postgresql:/var/lib/postgresql
      # This needs explicit mapping due to https://github.com/docker-library/postgres/blob/4e48e3228a30763913ece952c611e5e9b95c8759/Dockerfile.template#L52
      - ./postgresql_data:/var/lib/postgresql/data

There exists two things to be noticed:

  • We didn’t specify networks because docker compose will create a default bridge network for all services to communicate;
  • We use relative path like ./sonarqube_conf to mount those data & config volume out;

Simple Run

After the installation, we can run mvn/gradle command to analyze code and submit report:

mvn sonar:sonar \
  -Dsonar.host.url=$SONAR_URL \
  -Dsonar.login=$SONAR_LOGIN
# $SONAR_LOGIN is the token generated in sonar `accoun-security` config 

With Gitlab

Config Sonar

If we want to control the quality of new code, we need to control the merge request and this is where integrate Sonar. In order to integrate Sonar with Gitlab, we need to install Gitlab plugin in Sonar rather than install Sonar plugin in Gitlab.

The control flow is like following:

  • User submit merge request;
  • Gitlab run the Gitlab runner to do the CI of related repo;
  • The CI run analyze command and submit report;
  • The Sonar add comment about problems in new code under the merge request;
  • Other colleague review the code and decide whether to accept the merge request;

In order to do it, we need to do the following configs in SonarQube:

  • Sonar Gitlab plugin;
  • Update settings:
    • Add Gitlab user token;
    • Add Gitlab URL;
    • Add Gitlab api version: Notice – Gitlab 8.x need to use v3;
  • Sonar Java plugin;

Config Gitlab

sonarqube_master_job:  
	stage: test  
	only:  
	    - master  
	script:  
	    - mvn --batch-mode verify sonar:sonar -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN
sonarqube_preview_feature_job:  
	stage: test  
	only:  
	    - /^feature\/*/  
	script:  
	 - git checkout origin/master - git merge $CI_COMMIT_SHA --no-commit --no-ff - mvn --batch-mode verify sonar:sonar -Dsonar.host.url=http://192.168.1.204:9002 -Dsonar.login=07d1235f70b084c6d08c4f3e3ff86fe84c3ee52e -Dsonar.analysis.mode=preview -Dsonar.gitlab.project_id=$CI_PROJECT_PATH -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME

Problem List

Wrong Variable
GitLab 8.x name GitLab 9.x name
CI_BUILD_REF CI_COMMIT_SHA
CI_BUILD_REF_NAME CI_COMMIT_REF_NAME
No quality profiles have been found, you probably don’t have any language plugin installed

Lacking plugin will result in this error when run mvn command.

Gitlab runner fail to register

If met this error, check the detailed error in /var/log/gitlab/production.log to find real reason. In our case, it is version mismatch.

Ref

Written with StackEdit.

评论

此博客中的热门博文

Spring Boot: Customize Environment

Spring Boot: Customize Environment Environment variable is a very commonly used feature in daily programming: used in init script used in startup configuration used by logging etc In Spring Boot, all environment variables are a part of properties in Spring context and managed by Environment abstraction. Because Spring Boot can handle the parse of configuration files, when we want to implement a project which uses yml file as a separate config file, we choose the Spring Boot. The following is the problems we met when we implementing the parse of yml file and it is recorded for future reader. Bind to Class Property values can be injected directly into your beans using the @Value annotation, accessed via Spring’s Environment abstraction or bound to structured objects via @ConfigurationProperties. As the document says, there exists three ways to access properties in *.properties or *.yml : @Value : access single value Environment : can access multi

Elasticsearch: Join and SubQuery

Elasticsearch: Join and SubQuery Tony was bothered by the recent change of search engine requirement: they want the functionality of SQL-like join in Elasticsearch! “They are crazy! How can they think like that. Didn’t they understand that Elasticsearch is kind-of NoSQL 1 in which every index should be independent and self-contained? In this way, every index can work independently and scale as they like without considering other indexes, so the performance can boost. Following this design principle, Elasticsearch has little related supports.” Tony thought, after listening their requirements. Leader notice tony’s unwillingness and said, “Maybe it is hard to do, but the requirement is reasonable. We need to search person by his friends, didn’t we? What’s more, the harder to implement, the more you can learn from it, right?” Tony thought leader’s word does make sense so he set out to do the related implementations Application-Side Join “The first implementation

Implement isdigit

It is seems very easy to implement c library function isdigit , but for a library code, performance is very important. So we will try to implement it and make it faster. Function So, first we make it right. int isdigit ( char c) { return c >= '0' && c <= '9' ; } Improvements One – Macro When it comes to performance for c code, macro can always be tried. #define isdigit (c) c >= '0' && c <= '9' Two – Table Upper version use two comparison and one logical operation, but we can do better with more space: # define isdigit(c) table[c] This works and faster, but somewhat wasteful. We need only one bit to represent true or false, but we use a int. So what to do? There are many similar functions like isalpha(), isupper ... in c header file, so we can combine them into one int and get result by table[c]&SOME_BIT , which is what source do. Source code of ctype.h : # define _ISbit(bit) (1 << (