Code Quality (BASIC ALL)

使用 Code Quality 来分析源代码的质量和复杂性,有助于使您的项目代码简单、可读且易于维护。Code Quality 应该补充您的其他评审流程,而不是取代它们。

Code Quality 使用开源 Code Climate 工具,并选择插件来分析您的源代码。 要确认您的代码的语言是否包含在内,请参阅支持的可维护性语言的 Code Climate 列表。 您可以使用 Code Climate 分析插件自定义工具来扩展代码覆盖率。

在 CI/CD 流水线中运行 Code Quality 报告,验证变更不会降低代码质量,然后再将它们提交到默认分支。

产品级别功能摘要

不同的极狐GitLab 产品级别提供不同的功能,如下表所示:

能力 基础版 专业版 旗舰版
配置扫描器
集成自定义扫描器
在合并请求部件中查看结果
生成 JSON 或 HTML 报告产物
查看 CI 流水线中的报告
在合并请求差异视图中查看结果

查看 Code Quality 结果

Code Quality 结果显示在:

  • 合并请求部件
  • 合并请求变更视图
  • 流水线详情视图
  • 项目质量视图

合并请求部件

如果来自目标分支的报告可用于比较,Code Quality 分析结果将显示在合并请求部件区域中。

Code Quality Widget

查看 Code Climate 支持的可维护性语言列表。

合并请求变更视图 (ULTIMATE ALL)

  • 引入于 13.11 版本,在 codequality_mr_diff 功能标志后面默认禁用。
  • 默认启用于 13.12 版本。
  • 默认禁用于 14.0 版本。
  • 于 14.1 版本添加了行内注释,并删除了功能标志。

Code Quality 结果显示在合并请求变更视图中。对于包含 Code Quality 问题的行,会在装订线旁边显示标记。将鼠标悬停在标记上可以了解问题的详细信息。

Code Quality MR diff report

流水线详情视图 (PREMIUM ALL)

流水线生成的 Code Quality 违规的完整列表显示在流水线详细信息页面的代码质量选项卡中。

Code Quality Report

项目质量视图 (ULTIMATE ALL)

项目质量视图显示代码质量调查结果的概览。

Code Quality Summary

启用 Code Quality

先决条件:

  • 极狐GitLab CI/CD 配置(.gitlab-ci.yml)必须包括 test 阶段。
  • 如果您使用的是共享 runner,则必须为 Docker-in-Docker 工作流 配置 Code Quality 作业。
  • 如果您使用私有 runner,您应该使用推荐的替代配置,更有效地运行 Code Quality 分析。
  • Runner 必须有足够的磁盘空间来存储生成的 Code Quality 文件。例如,在极狐GitLab 项目上,文件大约为 7 GB。

要启用代码质量,您可以:

  • 启用 Auto DevOps,其中包括 Auto Code Quality

  • 或在 .gitlab-ci.yml 文件中包含 Code Quality 模板。

    示例:

       include:
       - template: Code-Quality.gitlab-ci.yml
    

    Code Quality 现在在流水线中运行。

caution在私有化部署版实例上,如果恶意行为者破坏 Code Quality 作业定义,他们可以在 runner 主机上执行特权 Docker 命令。拥有适当的访问控制策略,通过只允许受信任的参与者访问来减缓这种攻击向量。

使用私有 runners 提升 Code Quality 性能

如果您有私有 runner,您应该使用以下配置来提高 Code Quality 的性能:

  • 不使用特权模式。
  • 不使用 Docker-in-Docker。
  • Docker 镜像,包括所有 CodeClimate 镜像都被缓存,并且不会为后续作业重新获取。

此替代配置使用套接字绑定与作业环境共享 Runner 的 Docker 守护进程。在实施此配置之前,请考虑其限制

使用私有 runners:

  1. 注册一个新的 runner:

    $ gitlab-runner register --executor "docker" \
      --docker-image="docker:stable" \
      --url "https://jihulab.com/" \
      --description "cq-sans-dind" \
      --tag-list "cq-sans-dind" \
      --locked="false" \
      --access-level="not_protected" \
      --docker-volumes "/cache"\
      --docker-volumes "/builds:/builds"\
      --docker-volumes "/var/run/docker.sock:/var/run/docker.sock" \
      --registration-token="<project_token>" \
      --non-interactive
    
  2. 可选,但推荐:将构建目录设置为 /tmp/builds,以便定期从 runner 主机中清除作业产物。如果跳过这一步,您必须自己清理默认的构建目录(/builds)。您可以通过在上一步中,将以下两个标志添加到 gitlab-runner register 来做到这一点。

    --builds-dir "/tmp/builds"
    --docker-volumes "/tmp/builds:/tmp/builds" # Use this instead of --docker-volumes "/builds:/builds"
    

    生成的配置:

    [[runners]]
      name = "cq-sans-dind"
      url = "https://jihulab.com/"
      token = "<project_token>"
      executor = "docker"
      builds_dir = "/tmp/builds"
      [runners.docker]
        tls_verify = false
        image = "docker:stable"
        privileged = false
        disable_entrypoint_overwrite = false
        oom_kill_disable = false
        disable_cache = false
        volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock", "/tmp/builds:/tmp/builds"]
        shm_size = 0
      [runners.cache]
        [runners.cache.s3]
        [runners.cache.gcs]
    
  3. 对模板创建的 code_quality 作业应用两个覆盖:

    include:
      - template: Code-Quality.gitlab-ci.yml
    
    code_quality:
      services:            # Shut off Docker-in-Docker
      tags:
        - cq-sans-dind     # Set this job to only run on our new specialized runner
    

Code Quality 现在在标准 Docker 模式下运行。

禁用 Code Quality

如果存在 $CODE_QUALITY_DISABLED CI/CD 变量,则 code_quality 作业不会运行。有关如何定义变量的更多信息,请参阅极狐GitLab CI/CD 变量

要禁用 Code Quality,请创建一个名为 CODE_QUALITY_DISABLED 的自定义 CI/CD 变量,用于:

自定义扫描设置

您可以使用 .gitlab-ci.yml 中的 CI/CD 变量,更改 Code Quality 扫描设置。

配置 Code Quality 作业:

  1. 在包含模板后,声明一个与 Code Quality 作业同名的作业。
  2. 在作业中指定附加键。

有关示例,请参阅下载 JSON 格式的输出

可用的 CI/CD 变量

您可以通过定义可用的 CI/CD 变量来自定义 Code Quality:

CI/CD 变量 描述
SOURCE_CODE 要扫描的源代码的路径。
TIMEOUT_SECONDS codeclimate analyze 命令的自定义超时。
CODECLIMATE_DEBUG 设置启用 Code Climate debug 模式
CODECLIMATE_DEV 设置为启用 --dev 模式,该模式允许您运行 CLI 未知的引擎。
REPORT_STDOUT 设置将报告打印到 STDOUT,而不是生成通常的报告文件。
REPORT_FORMAT 设置控制生成的报告文件的格式。例如:json\|html
ENGINE_MEMORY_LIMIT_BYTES 设置引擎的内存限制,默认为 1,024,000,000 字节。
CODE_QUALITY_DISABLED 阻止 Code Quality 作业运行。
CODECLIMATE_PREFIX 设置前缀以用于 CodeClimate 引擎中的所有 docker pull 命令,适用于离线扫描

输出

Code Quality 会创建一个名为 gl-code-quality-report.json 的文件。此文件的内容在内部处理,结果显示在 UI 中。要查看原始结果,您可以配置 Code Quality 作业允许下载此文件。格式选项是 JSON 格式、HTML 格式或两者都有。使用 HTML 格式以更易于阅读的格式查看报告。例如,您可以在 Pages 上发布 HTML 格式文件,以便更轻松地查看。

下载 JSON 格式的输出

为了能够下载 JSON 格式的代码质量报告,请将 gl-code-quality-report.json 文件声明为 code_quality 作业的产物:

include:
  - template: Code-Quality.gitlab-ci.yml

code_quality:
  artifacts:
    paths: [gl-code-quality-report.json]

完整的 JSON 文件可作为 code_quality 作业的可下载产物使用。

下载 JSON 和 HTML 格式的输出

HTML 报告格式引入于 13.6 版本。

note要创建 HTML 格式文件,Code Quality 作业必须运行两次,每种格式一次。 在此配置中,创建了 JSON 格式文件,但仅在内部处理。

要能够以 JSON 和 HTML 格式下载 Code Quality 报告,请使用 extends: code_quality 向您的模板添加另一个作业:

include:
  - template: Code-Quality.gitlab-ci.yml

code_quality_html:
  extends: code_quality
  variables:
    REPORT_FORMAT: html
  artifacts:
    paths: [gl-code-quality-report.html]

JSON 和 HTML 文件都可以作为 code_quality 作业的可下载产物使用。

仅以 HTML 格式下载输出

要仅下载 HTML 格式文件的 Code Quality 报告,请在现有作业中将 REPORT_FORMAT 设置为 html

note此操作不会创建 JSON 格式文件,因此 Code Quality 结果不会显示在合并请求部件、流水线报告或变更视图中。
include:
  - template: Code-Quality.gitlab-ci.yml

code_quality:
  variables:
    REPORT_FORMAT: html
  artifacts:
    paths: [gl-code-quality-report.html]

HTML 文件可作为 code_quality 作业的可下载产物

将 Code Quality 与合并请求流水线一起使用

默认 Code Quality 配置不允许 code_quality 作业在合并请求流水线上运行。

要使 Code Quality 能够在合并请求流水线上运行,请覆盖代码质量 rulesworkflow: rules,以便它们与您当前的rules 相匹配。

例如:

include:
  - template: Code-Quality.gitlab-ci.yml

code_quality:
  rules:
    - if: $CODE_QUALITY_DISABLED
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" # Run code quality job in merge request pipelines
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH      # Run code quality job in pipelines on the default branch (but not in other branch pipelines)
    - if: $CI_COMMIT_TAG                               # Run code quality job in pipelines for tags

使用私有容器镜像库

引入于 13.7 版本

使用私有容器镜像仓库可以减少下载镜像的时间,也可以减少外部依赖。由于容器执行的嵌套架构,镜像库前缀必须专门配置为向下传递到 CodeClimate 的后续单个 engine 的 docker pull 命令中。

以下变量可以解决所有必需的镜像拉取:

  • CODE_QUALITY_IMAGE:一个完全前缀的镜像名称,可以位于从您的工作环境访问的任何位置。GitLab Container Registry 可用于托管您自己的副本。
  • CODECLIMATE_PREFIX:您预期的容器镜像库的域名,这是 CodeClimate CLI 支持的配置选项。您必须:
    • 包括尾部斜杠 (/)。
    • 不包括协议前缀,例如 https://
  • CODECLIMATE_REGISTRY_USERNAME:一个可选变量,用于指定从 CODECLIMATE_PREFIX 解析的镜像库域名的用户名。
  • CODECLIMATE_REGISTRY_PASSWORD:一个可选变量,用于指定从 CODECLIMATE_PREFIX 解析的镜像库域名的密码。
include:
  - template: Code-Quality.gitlab-ci.yml

code_quality:
  variables:
    CODE_QUALITY_IMAGE: "my-private-registry.local:12345/codequality:0.85.24"
    CODECLIMATE_PREFIX: "my-private-registry.local:12345/"

此示例特定于 Code Quality。有关如何使用镜像库镜像配置 DinD 的更多一般说明,请参阅相关文档

必需的镜像

默认的 .codeclimate.yml 需要以下镜像:

  • codeclimate/codeclimate-structure:latest
  • codeclimate/codeclimate-csslint:latest
  • codeclimate/codeclimate-coffeelint:latest
  • codeclimate/codeclimate-duplication:latest
  • codeclimate/codeclimate-eslint:latest
  • codeclimate/codeclimate-fixme:latest
  • codeclimate/codeclimate-rubocop:rubocop-0-92

如果您使用自定义的 .codeclimate.yml 配置文件,则必须在私有容器镜像库中添加指定的插件。

使用经身份验证的 DockerHub

您可以使用 DockerHub 作为 Code Quality 镜像的替代来源。

先决条件:

要使用 DockerHub,请在 .gitlab-ci.yml 文件中配置以下变量:

  • CODECLIMATE_PREFIX
  • CODECLIMATE_REGISTRY_USERNAME
  • CODECLIMATE_REGISTRY_PASSWORD

示例:

include:
  - template: Jobs/Code-Quality.gitlab-ci.yml

code_quality:
  variables:
    CODECLIMATE_PREFIX: "registry-1.docker.io/"
    CODECLIMATE_REGISTRY_USERNAME: $DOCKERHUB_USERNAME
    CODECLIMATE_REGISTRY_PASSWORD: $DOCKERHUB_PASSWORD

使用 Dependency Proxy

您可以使用 Dependency Proxy 来减少下载依赖项所花费的时间。

先决条件:

要引用 Dependency Proxy,请在 .gitlab-ci.yml 文件中配置以下变量:

  • CODE_QUALITY_IMAGE
  • CODECLIMATE_PREFIX
  • CODECLIMATE_REGISTRY_USERNAME
  • CODECLIMATE_REGISTRY_PASSWORD

例如:

include:
  - template: Code-Quality.gitlab-ci.yml

code_quality:
  variables:
    ## You must add a trailing slash to `$CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX`.
    CODECLIMATE_PREFIX: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/
    CODECLIMATE_REGISTRY_USERNAME: $CI_DEPENDENCY_PROXY_USER
    CODECLIMATE_REGISTRY_PASSWORD: $CI_DEPENDENCY_PROXY_PASSWORD

使用自定义工具

您可以将自定义工具集成到极狐GitLab 中,提供 Code Quality 报告。

Code Quality 报告产物 JSON 文件必须包含具有以下属性的对象数组:

名称 描述
description 代码质量违规的描述。
fingerprint 用于识别代码质量违规的唯一指纹。例如,MD5 哈希。
severity 严重性字符串(可以是 infominormajorcriticalblocker)。
location.path 包含代码质量违规的文件的相对路径。
location.lines.begin or location.positions.begin.line 发生代码质量违规的行。
note尽管 Code Climate 规范支持更多属性,但极狐GitLab 会忽略这些属性。极狐GitLab 解析器不允许在文件开头使用字节顺序标记。

要使用自定义 Code Quality 工具:

  1. 在生成 Code Quality 报告产物.gitlab-ci.yml 文件中定义一个作业。
  2. 配置工具,将 Code Quality 报告产物生成为 JSON 文件,该文件实现了 Code Climate 规范

示例:

[
  {
    "description": "'unused' is assigned a value but never used.",
    "fingerprint": "7815696ecbf1c96e6894b779456d330e",
    "severity": "minor",
    "location": {
      "path": "lib/index.js",
      "lines": {
        "begin": 42
      }
    }
  }
]

使用分析插件

可以使用 Code Climate 分析插件 扩展 Code Quality 功能。

例如,要使用 SonarJava 分析器

  1. 将名为 .codeclimate.yml 的文件添加到仓库的根目录。
  2. 将插件的 enablement code 添加到仓库根目录的 .codeclimate.yml 中:
  version: "2"
  plugins:
    sonar-java:
      enabled: true

这样会将 SonarJava 添加到包含在您的项目中的默认 .codeclimate.ymlplugins: 部分。

plugins: 部分的更改不会影响默认 .codeclimate.ymlexclude_patterns 部分。有关详细信息,请参阅[排除文件和文件夹] (https://docs.codeclimate.com/docs/exclude-files-and-folders)的 Code Climate 文档。

故障排除

更改默认配置无效

一个常见的问题是术语 Code QualityCode Climate(使用的引擎)非常相似。您必须添加 .codeclimate.yml 文件来更改默认配置,不是 .codequality.yml 文件。如果您使用了错误的文件名,仍使用默认的 .codeclimate.yml

合并请求中不显示 Code Quality 报告

这可能是由于多种原因:

  • 您刚刚在 .gitlab-ci.yml 中添加了 Code Quality 作业。该报告还没有任何可比较的内容,因此无法显示任何信息。它仅在将来的合并请求有可比较的内容后显示。
  • 您的流水线未设置为在目标分支上运行代码质量作业。如果目标分支没有生成报告,则您的 MR 分支报告没有可比性。在这种情况下,您将看到一条错误消息,指出 Base pipeline codequality artifact not found
  • artifacts:expire_in CI/CD 设置可能导致 Code Quality 产物比预期的更快过期。
  • 小部件使用最新提交到目标分支的流水线。如果提交到不运行代码质量作业的默认分支,可能会导致合并请求小部件没有用于比较的基本报告。
  • 如果使用 REPORT_STDOUT 环境变量,则不会生成报告文件,合并请求中也不会显示任何内容。

仅显示一个 Code Quality 报告,但定义了更多

从 15.7 版本开始,Code Quality 结合流水线中所有作业的结果。

在以前的版本中,极狐GitLab 仅使用最新创建的作业(具有最大的作业 ID)中的 Code Quality 产物。 如果流水线中的多个作业生成 Code Quality 产物,则忽略较早作业的 Code Quality 产物。

为避免混淆,请仅配置一项作业生成 gl-code-quality-report.json 文件。

RuboCop 错误

在 Ruby 项目上使用 Code Quality 作业时,您可能会遇到运行 RuboCop 的问题。 例如,使用非常新或非常旧版本的 Ruby 时可能会出现以下错误:

/usr/local/bundle/gems/rubocop-0.52.1/lib/rubocop/config.rb:510:in `check_target_ruby':
Unknown Ruby version 2.7 found in `.ruby-version`. (RuboCop::ValidationError)
Supported versions: 2.1, 2.2, 2.3, 2.4, 2.5

这是由于检查引擎使用的默认 RuboCop 版本不包括对正在使用的 Ruby 版本的支持。

要使用支持项目使用的 Ruby 版本的自定义版本的 RuboCop,您可以通过在项目仓库中创建 .codeclimate.yml 文件覆盖配置。

例如,要指定使用 RuboCop 版本 0.67

version: "2"
plugins:
  rubocop:
    enabled: true
    channel: rubocop-0-67

使用自定义工具时,合并请求上不显示 Code Quality

如果您的合并请求在使用自定义工具时未显示任何 Code Quality 更改,请确保 line 属性是 integer

错误:Could not analyze code quality

您可能会遇到以下错误:

error: (CC::CLI::Analyze::EngineFailure) engine pmd ran for 900 seconds and was killed
Could not analyze code quality for the repository at /code

如果您启用了任何 Code Climate 插件,并且 Code Quality CI/CD 作业失败并显示此错误消息,则该作业可能需要比默认超时 900 秒更长的时间。

要解决此问题,请在 .gitlab.-ci.yml 文件中将 TIMEOUT_SECONDS 设置为更高的值。

例如:

variables:
  TIMEOUT_SECONDS: 3600

将 Code Quality 与 Kubernetes CI 执行器一起使用

Code Quality 需要 Docker in Docker 设置才能工作。Kubernetes 执行器已经对此提供支持

为确保 Code Quality 作业可以在 Kubernetes 执行器上运行:

错误:x509: certificate signed by unknown authority

如果将 CODE_QUALITY_IMAGE 设置为托管在 Docker 镜像库中的镜像,该镜像使用不受信任的 TLS 证书(例如自签名证书),您会看到如下所示的错误:

$ docker pull --quiet "$CODE_QUALITY_IMAGE"
Error response from daemon: Get https://gitlab.example.com/v2/: x509: certificate signed by unknown authority

要解决此问题,请将 Docker daemon 配置为信任证书,方法是将证书放入 /etc/docker/certs.d 目录中。

此 Docker daemon 暴露给极狐GitLab Code Quality 模板中的后续 Code Quality Docker 容器,并且应该暴露您希望在其中应用证书配置的任何其他容器。

Docker

如果您有权访问极狐GitLab Runner 配置,请将目录添加为卷挂载

gitlab.example.com 替换为镜像库的实际域名。

示例:

[[runners]]
  ...
  executor = "docker"
  [runners.docker]
    ...
    privileged = true
    volumes = ["/cache", "/etc/gitlab-runner/certs/gitlab.example.com.crt:/etc/docker/certs.d/gitlab.example.com/ca.crt:ro"]

Kubernetes

如果您有权访问极狐GitLab Runner 配置和 Kubernetes 集群,则可以挂载 ConfigMap

gitlab.example.com 替换为镜像库的实际域名。

  1. 使用证书创建 ConfigMap:

    kubectl create configmap registry-crt --namespace gitlab-runner --from-file /etc/gitlab-runner/certs/gitlab.example.com.crt
    
  2. 更新极狐GitLab Runner config.toml 指定 ConfigMap:

    [[runners]]
      ...
      executor = "kubernetes"
      [runners.kubernetes]
        image = "alpine:3.12"
        privileged = true
        [[runners.kubernetes.volumes.config_map]]
          name = "registry-crt"
          mount_path = "/etc/docker/certs.d/gitlab.example.com/ca.crt"
          sub_path = "gitlab.example.com.crt"