Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Golang 代码质量持续检测 #30

Closed
yangwenmai opened this issue Jul 29, 2018 · 2 comments
Closed

Golang 代码质量持续检测 #30

yangwenmai opened this issue Jul 29, 2018 · 2 comments

Comments

@yangwenmai
Copy link
Member

yangwenmai commented Jul 29, 2018

Golang 代码质量持续检测

Author: Kenny Allen

Email: kennyallen0520@gmail.com

前言

在软件开发过程中,人工检查项目代码中的漏洞和潜在的 BUG 是一件让人十分费神费力的事情,为了解决这一痛点,SonarQube诞生了,它实现了一系列代码自动检测过程,包括命名规范,代码漏洞,代码重复量等。

但是光有 SonarQube 还不能发挥出应有的高效率,一个完整的代码质量持续检测应配合代码仓库(如 gitlab) 和 Jenkins 来共同构建一个自动化过程。

环境

  • Gitlab、Jenkins、SonarQube 服务都在一台物理机上的Docker中运行

  • 网络 (局域网IP:192.168.1.100)

image

  • 主机科学上网代理

    192.168.1.100:1087

    10.03.05

  • 模拟外网访问

    # 修改 hosts 文件,模拟外网访问
    sudo sh -c "echo '192.168.1.100 jenkins.kenny.com\n192.168.1.100 gitlab.kenny.com\n192.168.1.100 sonarqube.kenny.com' >> /etc/hosts"

    10.04.09

  • 工具集

名称 版本
golang go1.10.3
docker 18.03.1-ce

搭建

接下来,我以一个完整的案例来介绍搭建过程。

Jenkins

启动服务
# $jenkins_home 宿主机目录,挂载容器 /var/jenkins_home
# 我的数据卷目录是 ~/.jenkins
export JENKINS_HOME=~/.jenkins
docker run -d --restart=always -p 8080:8080 -p 50000:50000 -v $JENKINS_HOME:/var/jenkins_home --name jenkins jenkins:2.60.3

# 查看 jenkins 日志
docker logs -f jenkins
初始化
  1. 打开浏览器,访问 http://jenkins.kenny.com:8080

    9.11.34

    # 在日志中找到管理员密码
    docker logs -f jenkins 
    
    # 或者在 $JENKINS_HOME/secrets/initialAdminPassword 文件中找到管理员密码
    cat $JENKINS_HOME/secrets/initialAdminPassword

    9.09.27

    9.11.06

  2. 安装推荐插件 (如果你想自定义安装插件,点击 Select plugins to Install)

    9.13.59

  3. 创建管理员账号

    9.19.17

  4. 初始化完成

    9.19.55

Gitlab

启动服务 (gitlab 集成的服务比较多,因此需要占用较大的内存,官方推荐4GB以上)
# $gitlab_home 宿主机目录
# 我的数据卷目录是 ~/.gitlab
export GITLAB_HOME=~/.gitlab
docker run -d --restart=always -e 'GITLAB_HOST=gitlab.kenny.com' -p 443:443 -p 80:80 -p 22:22 -v $GITLAB_HOME/conf:/etc/gitlab -v $GITLAB_HOME:/var/opt/gitlab -v $GITLAB_HOME/log:/var/log/gitlab --name gitlab gitlab/gitlab-ce:11.1.0-ce.0

# 查看 gitlab 日志
docker logs -f gitlab
初始化
  1. 打开浏览器,访问 http://gitlab.kenny.com

    9.26.59

  2. 设置新密码后,使用 root 用户登录

    9.27.29

    9.27.42

  3. 新建 sonarqube 项目组

    9.29.45

  4. 在 sonarqube 项目组下新建 demo 项目

    9.31.26
    9.32.38

  5. 添加主机公钥到 Gitlab

    # 生成 rsa 公钥和密钥
    ssh-keygen -t rsa
    
    # 查看并复制公钥
    cat ~/.ssh/id_rsa.pub

    9.36.12

    9.37.39

    访问 http://gitlab.kenny.com/profile/keys ,将公钥添加至 Gitlab

    9.38.15

    9.38.18

  6. 将 sonarqube/demo 项目拉至主机的 $GOPATH 下

    # 在 $GOPATH 下创建 gitlab.kenny.com 文件夹
    mkdir -p $GOPATH/src/gitlab.kenny.com && cd $GOPATH/src/gitlab.kenny.com
    
    # clone code
    git clone git@gitlab.kenny.com:sonarqube/demo.git

SonarQube

启动服务
# 由于目前 sonarqube 官方的 Docker images 只有 7.1 版本,不满足 SonarGO 所需 7.2+ 版本,所以我参考7.1 的 Dockerfile 制作了一个 sonarqube 7.2.1 的镜像
# $sonarqube_home 宿主机目录
# 我的数据卷目录是 ~/.sonarqube
export SONARQUBE_HOME=~/.sonarqube
# 正式环境中应启用外部数据库服务来存储必要数据,在启动容器时设置如下JDBC相关参数:
# -e SONARQUBE_JDBC_USERNAME=sonar 
# -e SONARQUBE_JDBC_PASSWORD=sonar 
# -e SONARQUBE_JDBC_URL=jdbc:postgresql://localhost/sonar
docker run -d --restart=always -p 9000:9000 -v $SONARQUBE_HOME:/opt/sonarqube/data --name sonarqube kennyallen/sonarqube:7.2.1

# 查看 sonarqube 日志

Dockerfile:

FROM openjdk:8

ENV SONAR_VERSION=7.2.1 \
    SONARQUBE_HOME=/opt/sonarqube \
    SONARQUBE_JDBC_USERNAME=sonar \
    SONARQUBE_JDBC_PASSWORD=sonar \
    SONARQUBE_JDBC_URL=


# Http port
EXPOSE 9000

RUN groupadd -r sonarqube && useradd -r -g sonarqube sonarqube

# grab gosu for easy step-down from root
RUN set -x \
    && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.10/gosu-$(dpkg --print-architecture)" \
    && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/1.10/gosu-$(dpkg --print-architecture).asc" \
    && export GNUPGHOME="$(mktemp -d)" \
    && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
    && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
    && rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc \
    && chmod +x /usr/local/bin/gosu \
    && gosu nobody true

RUN set -x \
    && cd /opt \
    && wget -O sonarqube.zip https://sonarsource.bintray.com/Distribution/sonarqube/sonarqube-$SONAR_VERSION.zip \
    && unzip sonarqube.zip \
    && mv sonarqube-$SONAR_VERSION sonarqube \
    && chown -R sonarqube:sonarqube sonarqube \
    && rm sonarqube.zip \
    && rm -rf $SONARQUBE_HOME/bin/*

VOLUME "$SONARQUBE_HOME/data"

WORKDIR $SONARQUBE_HOME
COPY run.sh $SONARQUBE_HOME/bin/
ENTRYPOINT ["./bin/run.sh"]

run.sh:

#!/bin/bash

set -e

if [ "${1:0:1}" != '-' ]; then
  exec "$@"
fi

chown -R sonarqube:sonarqube $SONARQUBE_HOME
exec gosu sonarqube \
  java -jar $SONARQUBE_HOME/lib/sonar-application-$SONAR_VERSION.jar \
  -Dsonar.log.console=true \
  -Dsonar.jdbc.username="$SONARQUBE_JDBC_USERNAME" \
  -Dsonar.jdbc.password="$SONARQUBE_JDBC_PASSWORD" \
  -Dsonar.jdbc.url="$SONARQUBE_JDBC_URL" \
  -Dsonar.web.javaAdditionalOpts="$SONARQUBE_WEB_JVM_OPTS -Djava.security.egd=file:/dev/./urandom" \
  "$@"
初始化
  1. 打开浏览器,访问 http://sonarqube.kenny.com:9000

    8.58.40

  2. 使用管理员账号登录

    • 账号 admin
    • 密码 admin

    8.59.06

  3. 生成 token (作为远程连接 SonarQube 的标识,只生成一次,记得备份哦)

    admin_token: 74439d5bc557dcc206fa8b1f2f5516e65680bdc8

    8.59.41

  4. 安装插件 (进入 Administration -> Marketplace)

    9.01.25

    安装完成后点击重启 SonarQube 服务就OK了

集成

  • 将 Jenkins、Gitlab 和 SonarQube 有机整合

Jenkins 安装插件

  1. 点击进入 系统管理 -> 插件管理 -> 可选插件

    9.43.39

  2. 过滤选中 Gitlab、SonarQube Scanner,点击下载待重启后安装

    9.45.12
    9.45.35

    10.19.06

Jenkins 配置

  1. 安装 SonarQube & JDK

    进入 系统管理 -> Global Tool Configuration

    JDK 安装

    ​ 勾选我同意 Java SE Development Kit 的许可协议

    ​ 点击 Please enter your username/password

    11.31.38

    输入你的 oracle 账号密码

    10.20.43

    SonarQube Scanner 安装11.32.15

  2. SonarQube Server

    进入 系统管理 -> 系统设置

    Add SonarQube servers

    Name 随便填写

    Server URL: http://sonarqube.kenny.com:9000

    Server version: 5.3 or higher

    Server authentication token: 填 SonarQube 初始化时生成的 token

    9.53.05

  3. 取消 Gitlab 授权

    取消选中 Enable authentication for '/project' end-point,保存

    11.20.17

  4. 在 jenkins 容器中安装 golang 环境及工具

    # 在 Jenkins 容器中执行命令
    docker exec -it jenkins /bin/bash
    # 临时设置环境变量
    export GOROOT=$JENKINS_HOME/go
    export GOPATH=$JENKINS_HOME/workspace/go
    export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
    export http_proxy=http://192.168.1.100:1087;export https_proxy=http://192.168.1.100:1087;
    # 进入 jenkins 主目录
    cd $JENKINS_HOME
    # 下载 golang
    wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
    # 解压 golang 包
    tar -xvf  go1.10.3.linux-amd64.tar.gz
    # 删除 golang 包
    rm go1.10.3.linux-amd64.tar.gz
    # 安装必要工具
    # vgo
    go get -u -v golang.org/x/vgo
    # gometalinter
    go get -u -v github.com/alecthomas/gometalinter
    gometalinter --install
  5. 配置邮件通知

    进入 系统管理 -> 系统设置

    Jenkins Location

    系统管理员邮件地址修改为你自己的邮箱地址,如 wyh3265@163.com

    11.29.11

    Extend E-mail Notification

    SMTP Server 填写对应的SMTP服务地址,如 smtp.163.com

    点击高级,勾选使用SMTP认证

    用户名 注意不需要加 @xxx.xxx

    密码 填写自己的邮箱密码或授权码

    10.26.50

    11.50.08

    Default Triggers 选中 Always

    11.50.26

新建 Jenkins 构建任务

  1. 新构建一个自由风格的软件项目

    10.35.38

  2. 使用自定义的工作空间

    点击高级,勾选使用自定义的工作空间

    10.28.20

    目录:$JENKINS_HOME/workspace/go/src/gitlab.kenny.com/demo

    10.51.25

  3. 源码管理

    Repository URL:http://gitlab.kenny.com/sonarqube/demo

    Credentials:点击Add ,添加凭据 (Gitlab 用户名密码或 SSH登录等方式都可以)10.37.19

    10.29.32

  4. 构建触发器,选中

    Build when a change is pushed to GitLab. GitLab webhook URL: http://jenkins.kenny.com:8080/project/demo

    Enabled GitLab triggers 选中 Push Events 和 Accepted Merge Request Events ,表示当 Gitlab 有 push 或 merge 操作发生时触发构建。

    10.39.03

  5. 新建 webhook

    在浏览器中打开 http://gitlab.kenny.com/admin/application_settings (请使用 root 登录),找到 Outbound requests ,点击 Expand 后,选中 Allow requests to the local network from hooks and services 并保存更改。 (允许本地网络的 githook)

    10.43.37

    进入 http://gitlab.kenny.com/sonarqube/demo/settings/integrations

    URL: http://jenkins.kenny.com:8080/project/demo

    SecretToken: 不填

    选中 Push eventsMerge request events

    取消选中 Enable SSL verification

    点击 Add web hook

    10.46.50

  6. 增加构建步骤,选中 Execute Shell

    #!/bin/bash
    # 环境变量
    export GOROOT=$JENKINS_HOME/go
    export GOPATH=$JENKINS_HOME/workspace/go
    export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
    export http_proxy=http://192.168.1.100:1087;export https_proxy=http://192.168.1.100:1087;
    
    # 安装依赖
    vgo mod -vendor
    
    # coverage
    go test ./... -coverprofile=coverage.out
    
    # test
    go test ./... -json > report.json
    
    # vet
    go vet ./... 2> govet-report.out
    
    # golint
    golint ./... > golint-report.out
    
    # gometalinter 
    # 执行 gometalinter 会失败,因此加了 || true
    gometalinter ./... > gometalinter-report.out || true
  7. 增加构建步骤,选中 Execute SonarQube Scanner

    Analysis properties

    sonar.projectKey=gitlab.kenny.com
    sonar.projectName=demo
    sonar.sources=.
    sonar.exclusions=**/*_test.go,**/vendor/**
    sonar.tests=.
    sonar.test.inclusions=**/*_test.go
    sonar.test.exclusions=**/vendor/**
    sonar.go.coverage.reportPaths=coverage.out
    sonar.go.tests.reportPaths=report.json
    sonar.go.govet.reportPaths=govet-report.out
    sonar.go.golint.reportPaths=golint-report.out
    sonar.go.gometalinter.reportPaths=gometalinter-report.out
  8. 增加构建后操作,选中 Editable Email Notification

    Project Recipient List 填写接收邮件的Email地址,或使用默认配置

    Default Content 加上 SonarQube URL: http://sonarqube.kenny.com:9000

    11.51.18

测试

# clone demo 代码
cd $GOPATH/src/gitlab.kenny.com && git clone git@github.com:yuhao5/sonarqube-golang.git && rm -rf demo && mv sonarqube-golang demo && cd demo
# push 代码,触发 Jenkins 任务进行自动构建
git remote add gitlab git@gitlab.kenny.com:sonarqube/demo.git
git push -u gitlab master

# 若 gitlab 仓库地址不是 git@gitlab.kenny.com:sonarqube/demo.git ,请根据以下步骤修改:
docker exec -it gitlab /bin/bash
vim /etc/gitlab/gitlab.rb
# 找到 external_url,修改为 external_url 'http://gitlab.kenny.com'
# 然后执行
gitlab-ctl reconfigure

11.53.59

11.35.27

11.09.34

11.10.01

11.10.42

TODO

  1. 解决执行 gometalinter 失败问题
  2. Golang 质量标准,规则自定义
@yangwenmai
Copy link
Member Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants
@yangwenmai and others