Installation and Configuration
Installation
- Binary installation: https://www.sonarsource.com/products/sonarqube/downloads/
 - Recommended Docker deployment (note volume mounting): https://docs.sonarsource.com/sonarqube/latest/setup-and-upgrade/install-the-server/installing-sonarqube-from-docker/
 - Install Chinese Pack plugin (optional)
 
Configure Gitlab Login
- 
Documentation: https://docs.sonarsource.com/sonarqube/10.1/instance-administration/authentication/gitlab/
- Create application at 
https://<Your Gitlab URL>/-/profile/applications(read_user permission) - Callback URL must be 
<Your SonarQube URL>/oauth2/callback/gitlab 
 - Create application at 
 - 
Gitlab login button should appear after configuration
- Server base URL must be configured for successful redirection
	
	
	2.png 
	
	
	3.png 
	
	
	4.png  - Configure Gitlab project import
 - Create Token at 
https://<Your Gitlab URL>/-/profile/personal_access_tokens - Gitlab API endpoint: 
https://<Your Gitlab URL>/api/v4 - Gitlab option will appear in project creation after successful configuration
	
	
	5.png 
	
	
	6.png 
	
	
	7.png  
 - Server base URL must be configured for successful redirection
 - 
Multi-branch configuration (default single branch only)
- Use plugin: https://github.com/mc1arke/sonarqube-community-branch-plugin
 - Note plugin version compatibility with SonarQube
 - Modify configuration file accordingly
 
 
Project Configuration
- Prepare three configurations in SonarQube (custom variable names allowed):
- SONAR_HOST_URL= (SonarQube URL)
 - SONAR_PROJECT_KEY= (Project identifier)
 - SONAR_TOKEN= (Project token created in final setup step)
 - Add these variables to Gitlab CI/CD
 
 
.gitlab-ci.yml
sonarqube-check:
  stage: check
  image:
    name: sonarsource/sonar-scanner-cli:latest
    entrypoint: [""]
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
    GIT_DEPTH: "0"
    SONAR_HOST_URL: "${SONAR_HOST_URL}"
    SONAR_TOKEN: "${SONAR_TOKEN}"
    SONAR_PROJECT_KEY: "${SONAR_PROJECT_KEY}"
  allow_failure: false
  only:
    - main
    - dev
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  coverage: '/total:\s+\(statements\)\s+\d+.\d+%/'
  script:
    - bash ./deployment/sonarqube-check.sh
    - sonar-scanner -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.token=$SONAR_TOKEN -Dsonar.projectKey=$SONAR_PROJECT_KEY -Dsonar.branch.name=$CI_COMMIT_REF_NAME
.golangci.yml
run:
  concurrency: 4
  timeout: 5m
  issues-exit-code: 1
  tests: true
output:
  print-issued-lines: true
  print-linter-name: true
  uniq-by-line: true
  sort-results: false
linters:
  disable-all: true
  enable:
    - cyclop
    - gocognit
    - gocyclo
    - maintidx
    - gocritic
    - ineffassign
    - durationcheck
    - errcheck
    - errorlint
    - exhaustive
    - exportloopref
    - funlen
    - goconst
    - lll
    - nilnil
    - prealloc
    - promlinter
    - grouper
    - varnamelen
    - importas
    - forcetypeassert
    - decorder
    - errname
    - err113
    - gofmt
    - goimports
    - gomodguard
    - goprintffuncname
    - govet
    - misspell
    - nakedret
    - nestif
    - predeclared
    - unconvert
    - thelper
linters-settings:
  cyclop:
    max-complexity: 30
    skip-tests: false
  gocognit:
    min-complexity: 30
  gocyclo:
    min-complexity: 30
  dogsled:
    max-blank-identifiers: 2
  errcheck:
    check-type-assertions: true
    check-blank: true
    exclude-functions:
      - io.Copy(*bytes.Buffer)
      - io.Copy(os.Stdout)
  errorlint:
    errorf: true
    asserts: true
    comparison: true
  exhaustive:
    default-signifies-exhaustive: false
  funlen:
    lines: 100
    statements: 40
  goconst:
    min-len: 3
    min-occurrences: 3
    ignore-tests: false
    match-constant: true
    numbers: true
    min: 3
    max: 99999
    ignore-calls: false
  gofmt:
    simplify: true
  lll:
    line-length: 120
    tab-width: 1
  makezero:
    always: false
  nestif:
    min-complexity: 4
  nilnil:
    checked-types:
      - ptr
      - func
      - iface
      - map
      - chan
  nlreturn:
    block-size: 1
  varnamelen:
    max-distance: 9
    min-name-length: 1
  predeclared:
    ignore: ""
    q: false
  staticcheck:
    checks: [ "all" ]
  stylecheck:
    checks: [ "all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022" ]
    dot-import-whitelist:
      - fmt
    initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS" ]
    http-status-code-whitelist: [ "200", "400", "404", "500" ]
  unparam:
    check-exported: false
  unused:
    exported-is-used: false
    exported-fields-are-used: false
./deployment/sonarqube-check.sh
#!/bin/bash
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct
go mod tidy
## Code quality check
golangci-lint run ./... --out-format checkstyle > report.xml
ret01=$?
if [ $ret01 -ne 0 ]; then
    echo -e "\033[31m  >>>> Code quality check failed, exiting <<<<  \033[0m"
    exit 1
fi
## Test coverage
go test ./... -coverprofile="coverage.cov" -covermode count
ret02=$?
if [ $ret02 -ne 0 ]; then
    echo -e "\033[31m  >>>> Test coverage check failed, exiting <<<<  \033[0m"
    exit 2
fi
## Output coverage for Gitlab parsing
go tool cover -func="coverage.cov"
## Unit tests
go test -json ./... > report.json
ret03=$?
if [ $ret03 -ne 0 ]; then
    echo -e "\033[31m  >>>> Unit tests failed, exiting <<<<  \033[0m"
    exit 3
fi
exit 0
Final Results
- After configuration, code quality metrics will be visible in Gitlab