还在犯低级错误?用 golangci-lint 配合 GitLab 进行代码静态检查!

背景

代码静态检查能检查出很多问题,这些问题可能在测试中也无法发现,只有某些极端条件下会触发,例如死锁、竞争条件,没有处理的 err 等;同时也能检查出代码中的 bad smell,能够优化代码质量,尽量减少技术债务。

思路

对于 Go,有比较现成的工具 golangci-lint。这是一个静态代码检查工具,能够配置多种 lint 规则,执行速度较快,适合在 ci 流程中运行。

接入的过程比较简单,通过 push 或者 merge request 触发 pipeline,然后运行静态代码检查,输出结果。

实操

GitLab CI

要实现在 push 或者 merge request 的时候触发 pipeline,首先需要定义一个 GitLab CI 流程。在项目里新建一个 .gitlab-ci.yml 文件,内容如下:

yaml 复制代码
default:
  image: leslieleung/gitlab-golangci-lint:v0.0.3

stages:
  - lint

workflow:
  rules:
    - if: "$CI_PIPELINE_SOURCE == 'push'

lint:
  stage: lint
  tags:
    - myrunner
  script:
    - export GOPROXY=https://goproxy.cn
    - golangci-lint run > report.xml
  artifacts:
    when: always
    reports:
      junit: report.xml
  allow_failure: true

首先,要求 runner 使用一个 docker 镜像来运行。在 CI 任务中,给 runner 配置环境可能比较麻烦,使用配好需要的软件的 docker 镜像是更好的选择。在这个 docker 镜像中,包含了 go 的运行环境和一个 golangci-lint 二进制文件。

然后定义一个 pipeline 需要运行的 stage(步骤),目前只需要进行一个 lint。接下来定义需要执行 workflow 的场景,使用rules.if,这里我设置了当发生 push 事件,且提交的分支不是 k8s 的自动构建分支时,运行这个 pipeline。

最后是定义每一个 job(步骤)。stage 和上面的 stages 对应,tags 用来标识要用来运行的 runner。重点介绍 script 和 artifacts 两部分。script 是在这个 job 中要运行的命令,因为只是执行代码检查,要运行的命令就比较简单。如果要进行构建等等,也可以在这里执行。artifacts 是一个用来上传上一步 script 产生的构建产物的空间,如果你在上一步构建了二进制之类的文件,可以使用 artifacts 发布产物,会在 pipeline 中产生一个下载页面。这里我们需要的是上一步 lint 出来的结果,因此我们选择artifacts.reports.junit,GitLab 自带了一个可视化 junit 单测结果的界面。

golangci-lint 配置

golangci-lint 自带了非常多的规则,可以根据项目的需要来启用。示例如下:

yaml 复制代码
run:
# 要跳过的目录,根据需要调整
  skip-dirs:
    - tests
    - docs
    - gen
# 当前项目的Go版本
  go: '1.19'
  timeout: 5m
  tests: false
  allow-parallel-runners: true
  modules-download-mode: readonly
  issues-exit-code: 0
output:
  format: junit-xml
linters:
  disable-all: true
  enable:
    - errcheck
    - govet
    - ineffassign
    - unused
    - gosimple
    - staticcheck
    - gocognit
    - nilerr
    - goconst
    - revive

这套配置比较简单,只包含了一些诸如未处理的 err、无效赋值、未使用的变量、过高复杂度等的静态检查,可以根据项目需要进行调整。

最终效果

在左侧 CI/CD -> Pipelines -> Tests 可以看到 lint 的结果,failures 数即为 linter 检测出的问题数。

相关推荐
摇滚侠3 小时前
Spring Boot 3零基础教程,IOC容器中组件的注册,笔记08
spring boot·笔记·后端
程序员小凯5 小时前
Spring Boot测试框架详解
java·spring boot·后端
你的人类朋友6 小时前
什么是断言?
前端·后端·安全
程序员小凯7 小时前
Spring Boot缓存机制详解
spring boot·后端·缓存
i学长的猫7 小时前
Ruby on Rails 从0 开始入门到进阶到高级 - 10分钟速通版
后端·ruby on rails·ruby
用户21411832636028 小时前
别再为 Claude 付费!Codex + 免费模型 + cc-switch,多场景 AI 编程全搞定
后端
茯苓gao8 小时前
Django网站开发记录(一)配置Mniconda,Python虚拟环境,配置Django
后端·python·django
Cherry Zack8 小时前
Django视图进阶:快捷函数、装饰器与请求响应
后端·python·django
爱读源码的大都督9 小时前
为什么有了HTTP,还需要gPRC?
java·后端·架构
码事漫谈9 小时前
致软件新手的第一个项目指南:阶段、文档与破局之道
后端