基于 Gitlab 的 Code Review 最佳实践

4.4 Gitlab 的 Code Quality 功能

我们可以利用开源的 Code Climate Engines 工具,对仓库代码进行质量检查。Code Climate Engines 可以免费使用,但是 report 在 mr 界面的 report 展示需要 企业版 (Starter) 才支持。具体说明可参考官方文档 (https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html),要使用该功能,需要配置好 gitlab-runner 的 Docker-in-Docker 模式,其中 gitlab-runner 的 config.toml 配置可参考如下:

[[runners]]
  name = "gitlab_runner_name"
  url = "https://git-test.xxx.com/"
  token = "your_token"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.docker]
    tls_verify = false
    image = "docker:stable"
    privileged = true  # 必须打开特权模式
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size = 0
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]

对应的 .gitlab-ci.yml 配置可参考如下:

code_quality:
  stage: check
  tags: 
    - codequality
  image: registry.test.com/library/debian_ci
  allow_failure: false
  services:
    - name: docker:stable-dind
      alias: docker-codequality
  variables:
    DOCKER_TLS_CERTDIR: ""
    DOCKER_HOST: "tcp://docker-codequality:2375"
    DOCKERHUB_URL: "registry.test.com"
    GIT_LFS_SKIP_SMUDGE: "1"
    AUTH_TOKEN_TTL: "1800"
  before_script:
    - |
      if ! [ -f .codeclimate.yml -o -f .codeclimate.json ] ; then
        cp .gitlab/ci/codeclimate/.codeclimate.yml ./
      fi
    - |
      if ! [ -f tox.ini ] ; then # pep8
        cp .gitlab/ci/codeclimate/tox.ini ./
      fi
    - |
      if ! [ -f .pylintrc ] ; then
        cp .gitlab/ci/codeclimate/.pylintrc ./
      fi
    - |
      if ! [ -f .cppcheck-suppressions ] ; then
        cp .gitlab/ci/codeclimate/.cppcheck-suppressions ./
      fi
    - |
      AUTH_TOKEN=`python $PWD/.gitlab/ci/dockerhub/get_token.py`
      docker login -u "$AUTH_USER" -p "$AUTH_TOKEN" "$DOCKERHUB_URL"
      docker run --env CFG="$(cat /root/.docker/config.json)" \
        --volume /root/.docker:/root/.docker \
        alpine sh -c 'echo "$CFG" > /root/.docker/config.json'
  script:
    - |
      if ! docker info &>/dev/null; then
        if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
          export DOCKER_HOST='tcp://localhost:2375'
        fi
      fi
    - docker run --env SOURCE_CODE="$PWD" 
        --env ENGINE_MEMORY_LIMIT_BYTES=4000000000
        --volume "$PWD":/code 
        --volume /var/run/docker.sock:/var/run/docker.sock 
        --volume /root/.docker:/root/.docker 
        "$DOCKERHUB_URL/test/codequality:12-3-stable" /code
    - |
      if [ -f gl-code-quality-report.json ] ; then
        REPORT=$(head -n 1 gl-code-quality-report.json)
        if [ "$REPORT" != '[]' ] ; then
          exit 1
        fi
      fi
  after_script:
    - docker logout "$DOCKERHUB_URL"
  artifacts:
    reports:
      codequality: gl-code-quality-report.json
    paths: [gl-code-quality-report.json]
    when: on_failure
    expire_in: 1 week
  only:
    refs:
      - merge_requests
    changes:
      - .gitlab/ci/Code-Quality.gitlab-ci.yml
      - .gitlab/ci/codeclimate/*
      - Client/Content/Scripts/**/*.py
      - Server/Logic/**/*.py
      - Server/GameCpp/GameCore/**/*.{cpp,h}
  except:
    variables:
      - $CODE_QUALITY_DISABLED

empty-report:
  stage: check
  tags:
    - docker-dind
  image: registry.test.com/test/alpine:3.11
  variables:
    GIT_LFS_SKIP_SMUDGE: "1"
    GIT_SUBMODULE_STRATEGY: none
    GIT_STRATEGY: none
  script:
    - echo '[]' > gl-code-quality-report.json
  artifacts:
    reports:
      codequality: gl-code-quality-report.json
    expire_in: 1 week
  only:
    refs:
      - master

这里需要注意的是,当检查的代码文件数较多时,需要根据情况适当提高 ENGINE_MEMORY_LIMIT_BYTES 的值,否则会因为内存不足检查失败。同时 gl-code-quality-report 依赖上次 master 分支是否有 diff 而进行展示,故首次使用时,需触发下面的 empty-report 这个 stage,上传一个空的 gl-code-quality-report.json 文件。

上传以后,在 MR 的界面,可以看到类似如下的界面,代表 Code Quality 功能启用成功。