Help us learn about your current experience with the documentation. Take the survey.

配置基于 CodeClimate 的代码质量扫描(已弃用)

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

此功能在 GitLab 17.3 中已被弃用,并计划在 19.0 版本中移除。 请改为直接从受支持的工具集成结果。此更改是一个破坏性更改。

代码质量包含一个内置的 CI/CD 模板 Code-Quality.gitlab-ci.yaml。 此模板运行基于开源 CodeClimate 扫描引擎的扫描。

CodeClimate 引擎运行:

  • 一组支持的语言进行基本的可维护性检查。
  • 一组可配置的插件,这些插件包装了开源扫描器,用于分析您的源代码。

启用基于 CodeClimate 的扫描

先决条件:

  • GitLab CI/CD 配置(.gitlab-ci.yml)必须包含 test 阶段。
  • 如果您使用实例级 Runner,则必须为代码质量作业配置 Docker-in-Docker 工作流。 使用此工作流时,必须映射 /builds 卷以允许保存报告。
  • 如果您使用私有 Runner,则应使用 替代配置 以更高效地运行代码质量分析。
  • Runner 必须有足够的磁盘空间来存储生成的代码质量文件。例如,在 GitLab 项目中,这些文件大约为 7 GB。

要启用代码质量,请执行以下任一操作:

在 GitLab Self-Managed 上,如果恶意行为者破坏了代码质量作业定义,他们 可以在 Runner 主机上执行特权 Docker 命令。拥有适当的访问控制策略 通过仅允许受信任的行为者访问来缓解此攻击向量。

禁用基于 CodeClimate 的扫描

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

要禁用代码质量,请创建一个名为 CODE_QUALITY_DISABLED 的自定义 CI/CD 变量,适用于以下任一情况:

配置 CodeClimate 分析插件

默认情况下,code_quality 作业将 CodeClimate 配置为:

要扫描更多语言,您可以启用更多插件。 您还可以禁用 code_quality 作业默认启用的插件。

例如,要使用 SonarJava 分析器

  1. 在您的仓库根目录添加一个名为 .codeclimate.yml 的文件

  2. 将插件的启用代码 添加到仓库根目录的 .codeclimate.yml 文件中:

    version: "2"
    plugins:
      sonar-java:
        enabled: true

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

plugins: 部分的更改不会影响默认 .codeclimate.ymlexclude_patterns 部分。 有关更多详细信息,请参阅 Code Climate 文档中关于 排除文件和文件夹 的内容。

自定义扫描作业设置

您可以通过在 GitLab CI/CD YAML 中设置 CI/CD 变量 来更改 code_quality 扫描作业的行为。

要配置代码质量作业:

  1. 在模板包含后,声明一个与代码质量作业同名的作业。
  2. 在作业的节中指定其他键。

有关示例,请参阅以 HTML 格式下载输出

可用的 CI/CD 变量

可以通过定义可用的 CI/CD 变量来自定义代码质量:

CI/CD 变量 描述
CODECLIMATE_DEBUG 设置以启用 Code Climate 调试模式
CODECLIMATE_DEV 设置以启用 --dev 模式,该模式允许您运行 CLI 不知道的引擎。
CODECLIMATE_PREFIX 设置一个前缀,用于 CodeClimate 引擎中的所有 docker pull 命令。对于离线扫描很有用。有关更多信息,请参阅使用私有容器注册表
CODECLIMATE_REGISTRY_USERNAME 设置以指定从 CODECLIMATE_PREFIX 解析的注册表域的用户名。
CODECLIMATE_REGISTRY_PASSWORD 设置以指定从 CODECLIMATE_PREFIX 解析的注册表域的密码。
CODE_QUALITY_DISABLED 阻止代码质量作业运行。
CODE_QUALITY_IMAGE 设置为完全前缀的镜像名称。镜像必须可以从您的作业环境中访问。
ENGINE_MEMORY_LIMIT_BYTES 设置引擎的内存限制。默认值:1,024,000,000 字节。
REPORT_STDOUT 设置以将报告打印到 STDOUT,而不是生成常规报告文件。
REPORT_FORMAT 设置以控制生成的报告文件的格式。可以是 jsonhtml
SOURCE_CODE 要扫描的源代码路径。必须是存储克隆源代码的目录的绝对路径。
TIMEOUT_SECONDS codeclimate analyze 命令的每个引擎容器设置自定义超时。默认值:900 秒(15 分钟)

输出

代码质量输出一个包含发现问题详细信息的报告。此报告的内容 在内部处理,结果显示在 UI 中。该报告还作为 code_quality 作业的 作业工件输出,名为 gl-code-quality-report.json。您可以选择以 HTML 格式输出报告。 例如,您可以在 GitLab Pages 上发布 HTML 格式文件以便更轻松地审查。

以 JSON 和 HTML 格式输出

要以 JSON 和 HTML 格式输出代码质量报告,您需要创建一个额外的作业。这需要 运行两次代码质量,每种文件格式各一次。

要以 HTML 格式输出代码质量报告,请使用 extends: code_quality 在模板中添加另一个作业:

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

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

JSON 和 HTML 文件都作为作业工件输出。HTML 文件包含在 artifacts.zip 作业工件中。

仅以 HTML 格式输出

要仅以 HTML 格式下载代码质量报告,请将 REPORT_FORMAT 设置为 html,覆盖 code_quality 作业的默认定义。

这不会创建 JSON 格式文件,因此代码质量结果不会显示在合并请求 小部件、管道报告或更改视图中。

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

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

HTML 文件作为作业工件输出。

在合并请求管道中使用代码质量

默认的代码质量配置不允许 code_quality 作业在 合并请求管道上运行。

要使代码质量能够在合并请求管道上运行,请覆盖代码质量 rules, 或 workflow: rules,使它们与您当前的 rules 匹配。

例如:

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

code_quality:
  rules:
    - if: $CODE_QUALITY_DISABLED
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" # 在合并请求管道中运行代码质量作业
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH      # 在默认分支的管道中运行代码质量作业(但不在其他分支管道中)
    - if: $CI_COMMIT_TAG                               # 在标签的管道中运行代码质量作业

更改 CodeClimate 镜像的下载方式

CodeClimate 引擎下载容器镜像来运行其每个插件。 默认情况下,镜像从 Docker Hub 下载。 您可以更改镜像源以提高性能、解决 Docker Hub 速率限制或使用私有注册表。

使用依赖代理下载镜像

您可以使用依赖代理来减少下载依赖项所需的时间。

先决条件:

要引用依赖代理,请在 .gitlab-ci.yml 文件中配置以下变量:

  • CODE_QUALITY_IMAGE
  • CODECLIMATE_PREFIX
  • CODECLIMATE_REGISTRY_USERNAME
  • CODECLIMATE_REGISTRY_PASSWORD

例如:

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

code_quality:
  variables:
    ## 您必须在 `$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

使用带身份验证的 Docker Hub

您可以使用 Docker Hub 作为代码质量镜像的替代源。

先决条件:

要使用 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

使用私有容器镜像注册表

使用私有容器镜像注册表可以减少下载镜像所需的时间,并 减少外部依赖。您必须配置注册表前缀以传递给 CodeClimate 后续的各个引擎的 docker pull 命令,因为 容器执行是嵌套的。

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

  • CODE_QUALITY_IMAGE:一个完全前缀的镜像名称,可以位于 从您的作业环境可访问的任何位置。GitLab 容器注册表可以在此处 用于托管您自己的副本。
  • CODECLIMATE_PREFIX:您预期的容器镜像注册表的域。这是 CodeClimate CLI 支持的配置选项。 您必须:
    • 包含尾部斜杠(/)。
    • 不包含协议前缀,如 https://
  • CODECLIMATE_REGISTRY_USERNAME:一个可选变量,用于指定从 CODECLIMATE_PREFIX 解析的注册表域的用户名。
  • CODECLIMATE_REGISTRY_PASSWORD:一个可选变量,用于指定从 CODECLIMATE_PREFIX 解析的注册表域的密码。
include:
  - template: Jobs/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/"

此示例特定于 GitLab 代码质量。有关如何配置 带有注册表镜像的 DinD 的更一般说明,请参阅 为 Docker-in-Docker 服务启用注册表镜像

所需镜像

默认 .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 配置文件,则必须在您的私有容器注册表中添加指定的插件。

更改 Runner 配置

CodeClimate 为其每个分析步骤运行单独的容器。 您可能需要调整您的 Runner 配置,以便基于 CodeClimate 的扫描能够运行,或者运行得更快。

使用私有 Runner

如果您有私有 Runner,则应使用此配置以提高代码 质量的性能,因为:

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

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

要使用私有 Runner:

  1. 注册一个新的 Runner:

    $ gitlab-runner register --executor "docker" \
      --docker-image="docker:latest" \
      --url "https://gitlab.com/" \
      --description "cq-sans-dind" \
      --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" # 使用此选项代替 --docker-volumes "/builds:/builds"

    生成的配置:

    [[runners]]
      name = "cq-sans-dind"
      url = "https://gitlab.com/"
      token = "<project_token>"
      executor = "docker"
      builds_dir = "/tmp/builds"
      [runners.docker]
        tls_verify = false
        image = "docker:latest"
        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: Jobs/Code-Quality.gitlab-ci.yml
    
    code_quality:
      services:            # 关闭 Docker-in-Docker
      tags:
        - cq-sans-dind     # 将此作业设置为仅在我们新的专用 Runner 上运行

代码质量现在以标准 Docker 模式运行。

使用私有 Runner 以无根模式运行 CodeClimate

如果您使用私有 Runner 并希望以无根 Docker 模式运行代码质量扫描,则代码质量需要进行一些特殊更改才能正常运行。这可能需要有一个专门用于仅运行代码质量作业的 Runner,因为套接字绑定的更改可能会在其他作业中引起问题。

要使用无根私有 Runner:

  1. 注册一个新的 Runner:

    /run/user/<gitlab-runner-user>/docker.sock 替换为 gitlab-runner 用户的本地 docker.sock 路径。

    $ gitlab-runner register --executor "docker" \
      --docker-image="docker:latest" \
      --url "https://gitlab.com/" \
      --description "cq-rootless" \
      --tag-list "cq-rootless" \
      --locked="false" \
      --access-level="not_protected" \
      --docker-volumes "/cache" \
      --docker-volumes "/tmp/builds:/tmp/builds" \
      --docker-volumes "/run/user/<gitlab-runner-user>/docker.sock:/run/user/<gitlab-runner-user>/docker.sock" \
      --token "<project_token>" \
      --non-interactive \
      --builds-dir "/tmp/builds" \
      --env "DOCKER_HOST=unix:///run/user/<gitlab-runner-user>/docker.sock" \
      --docker-host "unix:///run/user/<gitlab-runner-user>/docker.sock"

    生成的配置:

    [[runners]]
      name = "cq-rootless"
      url = "https://gitlab.com/"
      token = "<project_token>"
      executor = "docker"
      builds_dir = "/tmp/builds"
      environment = ["DOCKER_HOST=unix:///run/user/<gitlab-runner-user>/docker.sock"]
      [runners.docker]
        tls_verify = false
        image = "docker:latest"
        privileged = false
        disable_entrypoint_overwrite = false
        oom_kill_disable = false
        disable_cache = false
        volumes = ["/cache", "/run/user/<gitlab-runner-user>/docker.sock:/run/user/<gitlab-runner-user>/docker.sock", "/tmp/builds:/tmp/builds"]
        shm_size = 0
        host = "unix:///run/user/<gitlab-runner-user>/docker.sock"
      [runners.cache]
        [runners.cache.s3]
        [runners.cache.gcs]
  2. 对模板创建的 code_quality 作业应用以下覆盖:

    code_quality:
      services:
      variables:
        DOCKER_SOCKET_PATH: /run/user/997/docker.sock
      tags:
        - cq-rootless

代码质量现在以标准 Docker 模式和无根模式运行。

如果您的目标是使用无根 Podman 运行 Docker 进行代码质量,则需要相同的配置。确保将 /run/user/<gitlab-runner-user>/docker.sock 替换为您系统中正确的 podman.sock 路径,例如:/run/user/<gitlab-runner-user>/podman/podman.sock

配置 Kubernetes 或 OpenShift Runner

您必须设置 Docker in Docker 容器(Docker-in-Docker)才能使用代码质量。Kubernetes 执行器支持 Docker-in-Docker

要确保代码质量作业可以在 Kubernetes 执行器上运行:

  • 如果您使用 TLS 与 Docker 守护进程通信,则执行器必须在特权模式下运行。此外,证书目录必须指定为卷挂载
  • DinD 服务可能在代码质量作业开始之前没有完全启动。这是在 Kubernetes 执行器故障排除中记录的限制。要解决此问题,请使用 before_script 等待 Docker 守护进程完全启动。有关示例,请参阅下一节中描述的 .gitlab-ci.yml 文件中的配置。

Kubernetes

要在 Kubernetes 中运行代码质量:

  • Docker in Docker 服务必须作为服务容器添加到 config.toml 文件中。
  • 服务容器中的 Docker 守护进程必须监听 TCP 和 UNIX 套接字,因为 CodeClimate 需要这两个套接字。
  • Docker 套接字必须与卷共享。

由于 Docker 要求,必须为服务容器启用特权标志。

[runners.kubernetes]

[runners.kubernetes.service_container_security_context]
privileged = true
allow_privilege_escalation = true

[runners.kubernetes.volumes]

[[runners.kubernetes.volumes.empty_dir]]
mount_path = "/var/run/"
name = "docker-sock"

[[runners.kubernetes.services]]
alias = "dind"
command = [
    "--host=tcp://0.0.0.0:2375",
    "--host=unix://var/run/docker.sock",
    "--storage-driver=overlay2"
]
entrypoint = ["dockerd"]
name = "docker:20.10.12-dind"

如果您使用 GitLab Runner Helm Chart,您可以在 values.yaml 文件的config 字段 中使用之前的 Kubernetes 配置。

为确保使用 overlay2 存储驱动程序(提供最佳整体性能):

  • 指定 Docker CLI 通信的 DOCKER_HOST
  • DOCKER_DRIVER 变量设置为空。

使用 before_script 部分等待 Docker 守护进程完全启动。从 GitLab Runner v16.9 开始,这也可以通过仅设置 HEALTHCHECK_TCP_PORT 变量来完成。

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

code_quality:
  services: []
  variables:
    DOCKER_HOST: tcp://dind:2375
    DOCKER_DRIVER: ""
  before_script:
    - while ! docker info > /dev/null 2>&1; do sleep 1; done

OpenShift

对于 OpenShift,您应该使用 GitLab Runner Operator。 要为服务容器中的 Docker 守护进程提供初始化其存储的权限, 您必须将 /var/lib 目录挂载为卷挂载。

如果您无法将 /var/lib 目录挂载为卷挂载,则可以将 --storage-driver 设置为 vfs。 如果您选择 vfs 值,可能会对性能产生负面影响。

要为 Docker 守护进程配置权限:

  1. 使用此配置模板创建一个 config.toml 文件以自定义 Runner 的配置:
[[runners]]

[runners.kubernetes]

[runners.kubernetes.service_container_security_context]
privileged = true
allow_privilege_escalation = true

[runners.kubernetes.volumes]

[[runners.kubernetes.volumes.empty_dir]]
mount_path = "/var/run/"
name = "docker-sock"

[[runners.kubernetes.volumes.empty_dir]]
mount_path = "/var/lib/"
name = "docker-data"

[[runners.kubernetes.services]]
alias = "dind"
command = [
    "--host=tcp://0.0.0.0:2375",
    "--host=unix://var/run/docker.sock",
    "--storage-driver=overlay2"
]
entrypoint = ["dockerd"]
name = "docker:20.10.12-dind"
  1. 将自定义配置设置到您的 Runner

  2. 可选。将privileged 服务账户 附加到构建 Pod。这取决于您的 OpenShift 集群设置:

    oc create sa dind-sa
    oc adm policy add-scc-to-user anyuid -z dind-sa
    oc adm policy add-scc-to-user -z dind-sa privileged
  3. [runners.kubernetes] 部分中设置权限。

  4. 作业定义保持与 Kubernetes 情况相同:

    include:
    - template: Code-Quality.gitlab-ci.yml
    
    code_quality:
    services: []
    variables:
      DOCKER_HOST: tcp://dind:2375
      DOCKER_DRIVER: ""
    before_script:
      - while ! docker info > /dev/null 2>&1; do sleep 1; done

卷和 Docker 存储

Docker 将其所有数据存储在 /var/lib 卷中,这可能导致一个很大的卷。要在集群中重用 Docker-in-Docker 存储, 您可以使用持久卷作为替代。