gitlab+reviewdog+golangci-lint实现提交MR时进行代码检测

本文使用 shell 作为 gitlab-runner 执行器 (executor) 演示提交 MR 时执行代码检查。

gitlab搭建参考文章:<基于docker搭建的gitlab实现CI/CD>,本文只是把文章中 runner 执行器由 docker 变成了 shell。

1.准备工作

  1. 安装gitlab-runner、reviewdog、golangci-lint

    1
    2
    3
    4
    5
    6
    #安装 gitlab-runner
    curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
    #安装 reviewdog
    curl -sfL https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh | sh -s
    #安装 golangci-lint
    curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.46.2
  2. gitlab-runner 注册到 gitlab

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    sudo gitlab-runner register \
    --non-interactive \
    --executor "shell" \
    --docker-image alpine:latest \
    --url "http://101.132.194.252/" \
    --registration-token "GR1348941ZCPzw2JGx4ubLcwn25dy" \
    --description "register-runner" \
    --tag-list "shell-runner" \
    --run-untagged="true" \
    --locked="false" \
    --access-level="not_protected"

    参数说明:

  • –executor runner执行器类型为shell
  • –url gitlab地址
  • –registration-token register需要的token(由gitlab提供)
  • –tag-list 当前 runner 的tag列表,job 通过 tags 来指定执行的runner

2.gitlab 代码仓库

1
2
3
4
5
.
├── .gitlab-ci.yml
├── .reviewdog.yml
├── go.mod
└── main.go

文件说明:

  • .gitlab-ci.yml gitlab执行CI/CD时需要的配置文件
  • .reviewdog.yml reviewdog需要的配置文件

.gitlab-ci.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
stages:
- test
- golint
- deploy

# job
build:
# 执行阶段
stage: golint
tags:
# 使用执行器的tag
- shell-runner
script:
# 执行脚本
# reviewdog 实现自动 comment 所需要的 token
# 在 gitlab( Setting -> Access Tokens )中创建
- export REVIEWDOG_GITLAB_API_TOKEN=bs8Wu4_FRWm4QZi4G5h2
# 仓库所有者
- export CI_REPO_OWNER=gitlab-instance-48689f56
# 仓库名称
- export CI_REPO_NAME=cicd-test
# gitlab仓库 API 接口名
- export GITLAB_API="http://101.132.194.252/api/v4"
- export REVIEWDOG_INSECURE_SKIP_VERIFY=true
- export CI_COMMIT=$(git rev-parse HEAD)
- reviewdog -reporter=gitlab-mr-discussion
only:
# 当前 job 只在执行 MR 时才执行
- merge_requests

.reviewdog.yml

1
2
3
4
5
6
7
runner:
golint:
# 执行 go lint
cmd: golangci-lint run
errorformat:
- "%f:%l:%c: %m"
level: warning

main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import (
"log"
"net/http"

// fmt 包未使用
"fmt"
)

func main() {
// num 变量未使用
var num int

s := http.NewServeMux()
s.HandleFunc("/hello", func(writer http.ResponseWriter, request *http.Request) {
writer.Write([]byte("hello world 7"))
})

if err := http.ListenAndServe(":8080", s); err != nil {
log.Fatalln(err)
}
}

3.提交MR,执行 go lint

提交MR时,gitlab执行对应job,在runner中使用golangci-lint做代码检查。

可以看出,代码检查的结果显示有两处错误。

1
2
main.go:10:6: [golint] num declared but not used (typecheck)
main.go:6:2: [golint] "fmt" imported but not used (typecheck)

同时会把这些问题作为 comment 提交到 MR 中。

4.一些问题及解决方法

问题1. reviewdog: golint failed with zero findings

1
reviewdog: golint failed with zero findings: The command itself failed (exit status 127) or reviewdog cannot parse the results

此问题,需要检查 golangci-lint 是否正确安装,并且该命令是否存在于 PATH 路径。

问题2. reviewdog: GET 404

1
reviewdog: GET http://101.132.194.252/api/v4/projects/root/cicd-test/merge_requests/13: 404 {message: 404 Project Not Found}

此问题,需要检查 root/cicd-test 是否正确,即:是否是存在的仓库路径。

问题3. reviewdog: command not found

1
bash: line 128: reviewdog: command not found

此问题,需要检查 reviewdog 是否正确安装,并且该命令是否存在于 PATH 路径。

扩展阅读