使用 Reviewdog 与 GitLab Connector

本指南演示如何使用自定义 CLI 工具如 reviewdog 与 GitLab 交互,实现合并请求的自动代码审查。

Overview

Reviewdog 是一款自动化代码审查工具,可以向包括 GitLab 在内的多个平台发布审查评论。结合 GitLab Connector,您可以在 CI/CD 流水线中运行自动代码审查,而无需手动管理 GitLab 凭据。

Prerequisites

  • 配置了带有 api 权限范围的 Private Access Token 的 GitLab Connector
  • 具有现有合并请求的 GitLab 仓库
  • 对 Kubernetes 集群具有 kubectl 访问权限
  • 对 reviewdog 和 lint 工具有基本了解

What You'll Learn

  • 如何使用 GitLab Connector 的内置配置访问 GitLab API
  • 如何配置 reviewdog 在合并请求上发布自动代码审查评论

Workflow Overview

使用 reviewdog 和 GitLab Connector 的典型工作流程:

  1. 使用 GitLab CLI (glab) 克隆仓库并检出合并请求分支
  2. 对代码运行 lint/分析工具
  3. 使用 reviewdog 通过 GitLab API 将发现的问题作为评论发布到合并请求

Step 1: Create a GitLab Connector

确保您拥有具有适当权限的 GitLab Connector:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: gitlab-secret
  namespace: gitlab-connector-demo
type: connectors.cpaas.io/gitlab-pat-auth
stringData:
  token: glpat-xxxxxxxxxxxxxxxxxxxx  # 令牌必须具有 'api' 权限范围
---
apiVersion: connectors.alauda.io/v1alpha1
kind: Connector
metadata:
  name: gitlab-connector
  namespace: gitlab-connector-demo
spec:
  connectorClassName: gitlab
  address: https://gitlab.com
  auth:
    name: patAuth
    secretRef:
      name: gitlab-secret
EOF

替换说明:

  • glpat-xxxxxxxxxxxxxxxxxxxx:替换为您的实际 GitLab Private Access Token(必须具有 api 权限范围)
  • https://gitlab.com:替换为您的 GitLab 服务器地址(GitLab.com 使用 https://gitlab.com,自托管 GitLab 使用相应 URL)

Step 2: Use Reviewdog to Post Review Comments

以下是一个完整示例,演示如何克隆仓库、检出合并请求分支并运行 reviewdog:

cat << 'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: reviewdog-demo
  namespace: gitlab-connector-demo
spec:
  restartPolicy: Never
  initContainers:
  # 克隆仓库并检出合并请求分支
  - name: checkout-mr
    image: gitlab/glab:v1.74.0
    command: ["sh"]
    args:
    - "-c"
    - |
      set -ex
      
      # 设置 glab 配置
      mkdir -p ~/.config/glab-cli
      cp /opt/gitlab/config/config.yml ~/.config/glab-cli/
      chmod 600 ~/.config/glab-cli/config.yml
      
      cp /opt/gitlab/config/.gitconfig ~/
      chmod 644 ~/.gitconfig
      
      # 克隆仓库并检出合并请求分支
      cd /data
      glab repo clone <your-group>/<your-repo> ./repo
      cd /data/repo
      git checkout <mr-source-branch-name>
    volumeMounts:
    - name: gitlab-config
      mountPath: /opt/gitlab/config
    - name: data
      mountPath: /data
  containers:
  # 运行 reviewdog 发布审查评论
  - name: reviewdog
    image: reviewdog/action-golangci-lint:v1
    command: ["sh"]
    args:
    - "-c"
    - |
      set -ex
      cd /data/repo
      
      # 从 connector 内置配置读取 GitLab 凭据
      GITLAB_TOKEN=$(cat /opt/gitlab/config/context.token)
      GITLAB_SERVER=$(cat /opt/gitlab/config/connector.status.proxyAddress)
      
      # 配置 reviewdog 环境变量
      export REVIEWDOG_GITLAB_API_TOKEN=${GITLAB_TOKEN}
      export GITLAB_API=${GITLAB_SERVER}/api/v4
      export CI_PULL_REQUEST=<merge-request-id>
      export CI_REPO_OWNER=<your-group>
      export CI_REPO_NAME=<your-repo>
      export CI_COMMIT=$(git rev-parse HEAD)
      
      # 运行 reviewdog(示例使用假评论)
      echo "example.go:1:1: This is a review comment from reviewdog" | \
        reviewdog -f=golint -reporter=gitlab-mr-commit -fail-on-error=false
      
      echo "Reviewdog completed"
    volumeMounts:
    - name: gitlab-config
      mountPath: /opt/gitlab/config
    - name: data
      mountPath: /data
  volumes:
  - name: data
    emptyDir: {}
  - name: gitlab-config
    csi:
      driver: connectors-csi
      readOnly: true
      volumeAttributes:
        connector.name: "gitlab-connector"
        configuration.names: "gitlabconfig,gitconfig"
EOF

替换说明:

  • <your-group>/<your-repo>:替换为您的 GitLab 仓库路径(例如 gitlab-org/gitlab
  • <merge-request-id>:替换为合并请求 ID(例如 123
  • <mr-source-branch-name>:替换为合并请求源分支名称(例如 feature-branch
  • <your-group>:替换为您的 GitLab 组/用户名
  • <your-repo>:替换为您的仓库名称
  • echo "example.go:1:1: This is a review comment from reviewdog":替换为实际 lint 工具输出(确保文件存在于合并请求中且行号有效)

Step 3: Verify the Results

应用 Pod 后,验证 reviewdog 是否成功发布了合并请求评论。

查看 Pod 日志:

# 查看 checkout-mr 容器日志
kubectl logs reviewdog-demo -n gitlab-connector-demo -c checkout-mr

您可以看到仓库克隆成功并检出合并请求分支的输出:

Cloning into './repo'...
remote: Enumerating objects: 123, done.
remote: Counting objects: 100% (123/123), done.
remote: Compressing objects: 100% (89/89), done.
remote: Total 123 (delta 34), reused 123 (delta 34), pack-reused 0
Receiving objects: 100% (123/123), 45.67 KiB | 1.23 MiB/s, done.
Resolving deltas: 100% (34/34), done.
+ echo 'Repository cloned successfully'
Repository cloned successfully
+ cd /data/repo
+ git checkout dev-1764221453
branch 'dev-1764221453' set up to track 'origin/dev-1764221453'.
Switched to a new branch 'dev-1764221453'
# 查看 reviewdog 容器日志
kubectl logs reviewdog-demo -n gitlab-connector-demo -c reviewdog

您可以看到 reviewdog 成功完成的输出:

+ git rev-parse HEAD
+ export 'CI_COMMIT=7681622c06bb5e298ee5da6a710a177f7d4f2af6'
+ echo 'README.md:3:1: This is a review comment from reviewdog'
+ reviewdog '-f=golint' '-reporter=gitlab-mr-commit' '-fail-on-error=false'
Reviewdog completed
+ echo 'Reviewdog completed'

在 GitLab UI 中验证:

打开 GitLab 中的合并请求,查看 Changes 标签页。审查评论应显示在指定的文件和行号上。

如果评论未出现,请检查:

  • Pod 日志是否有错误:kubectl logs reviewdog-demo -c reviewdog -n gitlab-demo
  • 评论中的文件名和行号是否存在于合并请求中
  • 合并请求 ID 是否正确
  • Private Access Token 是否具有 api 权限范围
  • Connector 状态是否为“Ready”:kubectl get connector gitlab-connector -n gitlab-connector-demo

Understanding the Configuration

Reviewdog Environment Variables

以下环境变量是 reviewdog 与 GitLab 交互所必需的:

变量描述来源
REVIEWDOG_GITLAB_API_TOKENGitLab API 认证令牌来自 context.token 文件
GITLAB_APIGitLab API 端点来自 connector.status.proxyAddress + /api/v4
CI_PULL_REQUEST合并请求 ID用户提供
CI_REPO_OWNER仓库所有者/组用户提供
CI_REPO_NAME仓库名称用户提供
CI_COMMIT需审查的提交 SHA来自 git rev-parse HEAD

更多信息请参考 Reviewdog Documentation

Connector Built-in Configurations

GitLab Connector 提供以下内置配置文件:

  • context.token:用于访问 connector 代理服务的 Kubernetes API 令牌
  • connector.status.proxyAddress:connector 代理服务地址

详情请参见:Connectors-CSI Built-in Configurations

Using with Real Linting Tools

上述示例使用了假评论进行演示。生产环境中请使用实际的 lint 工具:

使用 golangci-lint 的示例:

golangci-lint run --out-format=line-number ./... | \
  reviewdog -f=golangci-lint -reporter=gitlab-mr-commit -fail-on-error=false

使用 eslint 的示例:

eslint . --format=stylish | \
  reviewdog -f=eslint -reporter=gitlab-mr-commit -fail-on-error=false

更多 reviewdog 集成请参见:Reviewdog Documentation

Next Steps