- 产品级别功能摘要
- 查看 Code Quality 结果
- 启用 Code Quality
- 禁用 Code Quality
- 自定义扫描设置
- 输出
- 将 Code Quality 与合并请求流水线一起使用
- 使用私有容器镜像库
- 使用经身份验证的 DockerHub
- 使用 Dependency Proxy
- 使用自定义工具
- 使用分析插件
- 故障排除
Code Quality
使用 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 Climate 支持的可维护性语言列表。
合并请求变更视图
- 引入于 13.11 版本,在
codequality_mr_diff
功能标志后面默认禁用。- 默认启用于 13.12 版本。
- 默认禁用于 14.0 版本。
- 于 14.1 版本添加了行内注释,并删除了功能标志。
Code Quality 结果显示在合并请求变更视图中。对于包含 Code Quality 问题的行,会在装订线旁边显示标记。将鼠标悬停在标记上可以了解问题的详细信息。
流水线详情视图
流水线生成的 Code Quality 违规的完整列表显示在流水线详细信息页面的代码质量选项卡中。
项目质量视图
项目质量视图显示代码质量调查结果的概览。
启用 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 现在在流水线中运行。
使用私有 runners 提升 Code Quality 性能
如果您有私有 runner,您应该使用以下配置来提高 Code Quality 的性能:
- 不使用特权模式。
- 不使用 Docker-in-Docker。
- Docker 镜像,包括所有 CodeClimate 镜像都被缓存,并且不会为后续作业重新获取。
此替代配置使用套接字绑定与作业环境共享 Runner 的 Docker 守护进程。在实施此配置之前,请考虑其限制。
使用私有 runners:
-
注册一个新的 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
-
可选,但推荐:将构建目录设置为
/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]
-
对模板创建的
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 作业:
- 在包含模板后,声明一个与 Code Quality 作业同名的作业。
- 在作业中指定附加键。
有关示例,请参阅下载 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 版本。
要能够以 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
。
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 能够在合并请求流水线上运行,请覆盖代码质量 rules
或 workflow: 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 镜像的替代来源。
先决条件:
- 在项目中添加用户名和密码作为受保护的 CI/CD 变量。
要使用 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 已在项目所属的群组中启用。
要引用 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
| 严重性字符串(可以是 info 、minor 、major 、critical 或 blocker )。
|
location.path
| 包含代码质量违规的文件的相对路径。 |
location.lines.begin or location.positions.begin.line
| 发生代码质量违规的行。 |
要使用自定义 Code Quality 工具:
- 在生成 Code Quality 报告产物的
.gitlab-ci.yml
文件中定义一个作业。 - 配置工具,将 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 分析器:
- 将名为
.codeclimate.yml
的文件添加到仓库的根目录。 - 将插件的 enablement code 添加到仓库根目录的
.codeclimate.yml
中:
version: "2"
plugins:
sonar-java:
enabled: true
这样会将 SonarJava 添加到包含在您的项目中的默认 .codeclimate.yml
的 plugins:
部分。
对 plugins:
部分的更改不会影响默认 .codeclimate.yml
的 exclude_patterns
部分。有关详细信息,请参阅[排除文件和文件夹] (https://docs.codeclimate.com/docs/exclude-files-and-folders)的 Code Climate 文档。
故障排除
更改默认配置无效
一个常见的问题是术语 Code Quality
和 Code 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 执行器上运行:
- 如果您使用 TLS 与 Docker daemon 通信,则执行程序必须在特权模式下运行。此外,证书目录必须指定为卷挂载。
- 在 Code Quality作业开始之前,DinD 服务可能没有完全启动。
错误: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
替换为镜像库的实际域名。
-
使用证书创建 ConfigMap:
kubectl create configmap registry-crt --namespace gitlab-runner --from-file /etc/gitlab-runner/certs/gitlab.example.com.crt
-
更新极狐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"