Jenkins Gerrit持续集成

〇、概述

0.1 背景及目的

我司新手村任务:

  1. 安装运行gerrit;
  2. 建立一个gerrit仓库,使用git/repo下载上传代码;
  3. 安装运行jenkins;
  4. 在jenkins新建一个item,当gerrit有新的change时自动触发,执行测试用例及代码扫描,输出测试用例/代码覆盖率/代码扫描结果;
  5. 在jenkins新建一个item,当gerrit有新的merge时自动触发,执行构建。

在此记录一下过程。

0.2 概念介绍

  • Gerrit: 一种免费、开放源代码的代码审查软件,使用网页界面。利用网页浏览器,同一个团队的软件程序员,可以相互审阅彼此修改后的程序代码,决定是否能够提交,退回或者继续修改。它使用Git作为底层版本控制系统。它分支自Rietveld,作者为Google公司的Shawn Pearce,原先是为了管理Android计划而产生。(百度百科)
  • Repo: Repo is a tool that we built on top of Git. Repo helps us manage the many Git repositories, does the uploads to our revision control system, and automates parts of the Android development workflow. Repo is not meant to replace Git, only to make it easier to work with Git in the context of Android. The repo command is an executable Python script that you can put anywhere in your path.(https://code.google.com/archive/p/git-repo/)
  • Jenkins: The leading open source automation server, Jenkins provides hundreds of plugins to support building, deploying and automating any project.(https://www.jenkins.io/)

0.3 整体流程

jenkins.png

一、环境安装

1.1 基础环境

  • java
  • git
  • docker & docker-compose

基础环境安装省略。

1.2 安装gerrit

参考 https://hub.docker.com/r/gerritcodereview/gerrit

1.2.1 docker-compose配置

mkdir gerrit & cd gerrit

touch docker-compose.yaml & vim docker-compose.yaml

version: '3'

services:
  gerrit:
    image: gerritcodereview/gerrit
    ports:
      - "29418:29418"
      - "80:8080"
    depends_on:
      - ldap
    volumes:
      - /Users/syrius/workspace/task1/gerrit/data/etc:/var/gerrit/etc
      - /Users/syrius/workspace/task1/gerrit/data/git:/var/gerrit/git
      - /Users/syrius/workspace/task1/gerrit/data/db:/var/gerrit/db
      - /Users/syrius/workspace/task1/gerrit/data/index:/var/gerrit/index
      - /Users/syrius/workspace/task1/gerrit/data/cache:/var/gerrit/cache
    environment:
      - CANONICAL_WEB_URL=http://localhost
#    command: init

  ldap:
    image: osixia/openldap
    ports:
      - "389:389"
      - "636:636"
    environment:
      - LDAP_ADMIN_PASSWORD=secret
    volumes:
      - /Users/syrius/workspace/task1/gerrit/data/ldap/var:/var/lib/ldap
      - /Users/syrius/workspace/task1/gerrit/data/ldap/etc:/etc/ldap/slapd.d

  ldap-admin:
    image: osixia/phpldapadmin
    ports:
      - "6443:443"
    environment:
      - PHPLDAPADMIN_LDAP_HOSTS=ldap

1.2.2 初始化

取消注释docker-compose.yaml中的command: init,然后运行docker-compose up gerrit初始化

1.2.3 运行

注释docker-compose.yaml中的command: init,然后运行docker-compose up -d

1.2.4 新建用户

  1. 访问ldap控制台: https://localhost:6443,输入默认用户名: cn=admin,dc=example,dc=org,默认密码: secret登录。

  2. 新建两个用户,一个提交代码,一个code review:

cn=admin,dc=example,dc=org -> Create a child entry -> Courier Mail: Account -> 填写表单 -> Create Object


image-20220430125154724.png
  1. 访问http://localhost/, 登录gerrit

    image-20220430125611572.png

  2. 配置ssh公钥

    • ssh-keygen -m PEM -t rsa -C "gerrit@syriusrobotics.com"

    • 配置ssh登录用户
      vim ~/.ssh/config

      Host localhost
      Hostname 192.168.0.104
      User gerrit
      Port 29418
      IdentityFile ~/.ssh/id_rsa
      
    • ~/.ssh/id_rsa.pub中的内容配置到gerrit:

      image-20220430132149596.png

  3. 将用户添加到Service User组

    BROWSE -> Group -> Members -> Search & Add

image-20220430135136306.png

1.2.5 新建仓库

  1. BROWSE -> Repository -> CREATE NEW
image-20220430134331330.png
  1. 配置仓库访问权限

赋予Service User用户组 Label Code-Review 与 Label Verified +1/-1 投票权限

image-20220430134607590.png

1.3 安装jenkins

1.3.1 运行

docker run --network=bridge -d --name jenkins -p 8080:8080 -p 50000:50000 -v /Users/syrius/workspace/task1/jenkins_home:/var/jenkins_home -v /Users/syrius/.ssh/:/var/jenkins_home/.ssh/ -v /Users/syrius/softs/apache-maven-3.8.5:/var/jenkins_home/maven jenkins/jenkins

1.3.2 登录

访问地址: http://localhost:8080/

默认用户名: admin

默认密码: cat jenkins_home/secrets/initialAdminPassword

image-20220430130150100.png

1.3.3 安装Gerrit Trigger插件

  1. 在jenkins plugin manger搜索并安装ç插件;

  2. Manage Jenkins -> Gerrit Trigger -> Add new Server,配置gerrit服务

ssh连接信息:

image-20220430131705897.png

http连接信息(需展开Advaned选项):

image-20220430131847346.png

1.3.4 安装juint插件

juint插件用于收集单元测试报告

image-20220430133246400.png

1.3.5 安装cobertura插件

cobertura插件用于收集单元测试代码覆盖率报告

image-20220430133520005.png

1.3.6 安装Warnings Next Generation插件

Warnings Next Generation用于执行代码扫描

image-20220430133757338.png

二、测试流水线

2.1 新建item

image-20220430134056234.png

2.2 配置gerrit

Refspec: refs/changes/:refs/changes/

Branch Specifier: $GERRIT_REFSPEC

image-20220430135446275.png

添加触发事件: Patchset Created

image-20220430135935348.png

2.3 配置执行脚本

/var/jenkins_home/maven/bin/mvn clean compile surefire-report:report cobertura:cobertura checkstyle:checkstyle

image-20220430140412865.png

2.4 测试报告收集

image-20220430140443061.png

2.5 代码覆盖率报告收集

image-20220430140505029.png

2.6 代码扫描结果收集

image-20220430140532692.png

三、构建流水线

与测试流水线相似,但更简单。

  • 添加触发事件: Change Merged
image-20220430140911958.png
  • 配置执行脚本

    /var/jenkins_home/maven/bin/mvn clean package -Dcheckstyle.skip=true

四、演示

4.1 检出仓库

  1. 使用以下命令,检出仓库后添加钩子函数,用于向commit msg添加Change-Id

git clone "ssh://gerrit@localhost:29418/hello-syrius" && scp -p -P 29418 gerrit@localhost:hooks/commit-msg "hello-syrius/.git/hooks/"

git clone "http://gerrit@localhost/a/hello-syrius" && (cd "hello-syrius" && mkdir -p .git/hooks && curl -Logit rev-parse --git-dir/hooks/commit-msg http://gerrit@localhost/tools/hooks/commit-msg; chmod +xgit rev-parse --git-dir/hooks/commit-msg)

  1. 新建一个maven项目,pom.xml如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.syrius.task1</groupId>
        <artifactId>hello-syrius</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <testFailureIgnore>true</testFailureIgnore>
                        <includes>
                            <include>**/*Test.java</include>
                        </includes>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>cobertura-maven-plugin</artifactId>
                    <version>2.5.2</version>
                    <configuration>
                        <outputDirectory>target/report</outputDirectory>
                        <encoding>UTF-8</encoding>
                        <formats>
                            <format>xml</format>
                        </formats>
                        <check/>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-checkstyle-plugin</artifactId>
                    <version>3.0.0</version>
                    <configuration>
                        <!-- XXXX -->
                        <!-- 是否有输出文件 -->
                        <consoleOutput>true</consoleOutput>
                        <!-- 编码方式 -->
                        <encoding>utf-8</encoding>
                        <!-- 是否因为不符合的规范中断mvn进程 -->
                        <failsOnError>false</failsOnError>
                        <linkXRef>false</linkXRef>
                        <violationSeverity>error</violationSeverity>
                    </configuration>
                    <executions>
                        <execution>
                            <id>validate</id>
                            <phase>validate</phase>
                            <goals>
                                <goal>check</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
    
            </plugins>
    
        </build>
        <reporting>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-checkstyle-plugin</artifactId>
                    <version>3.0.0</version>
                    <reportSets>
                        <reportSet>
                            <reports>
                                <report>check</report>
                            </reports>
                        </reportSet>
                    </reportSets>
                </plugin>
            </plugins>
        </reporting>
    
    </project>
    

4.2 commit & push

注意push时需要指定分支为HEAD:refs/for/master,而不是目标分支master。这是gerrit生成review的机制。

截图中可以看到gerrit生成了id为123的change.

image-20220430142117185.png

4.3 gerrit change

image-20220430142451798.png

4.4 jenkins测试流水线

image-20220430142655957.png
image-20220430142749345.png

4.5 gerrit submit

  1. 当前的Code-Review +1 和 Verfied + 1是jenkins流水线返回的
image-20220430142837692.png
  1. 人工Code-Review后,投出+2的票数,Code-Review通过
image-20220430143112385.png
  1. Submit提交变更,Rebase到目前分支
image-20220430143217200.png

4.6 jenkins 构建流水线

image-20220430143338348.png

五、使用repo

5.1 下载安装

curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

5.2 初始化

  1. 在gerrit新建一个manifests仓库,在仓库中放置一个default.xml文件,写入以下内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <manifest>
        <remote fetch="http://localhost" name="origin" review="http://localhost"/>
        <default remote="origin" revision="master"/>
        <project name="hello-syrius" path="hello-syrius"/>
    </manifest>
    
  2. 初始化仓库

    在任意空目录执行以下命令:

    repo init -u http://localhost/manifests --repo-url=https://gerrit-googlesource.lug.ustc.edu.cn/git-repo

  3. 拉取最新代码

    repo sync

5.3 新建一个分支

repo start feature-1

image-20220430144805656.png

5.4 提交一个变更

repo upload

image-20220430145731195.png

六、后续步骤

mvn deploy 或 gradle publish 或 docker push

没装环境,不写了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,302评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,563评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,433评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,628评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,467评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,354评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,777评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,419评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,725评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,768评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,543评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,387评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,794评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,032评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,305评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,741评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,946评论 2 336

推荐阅读更多精彩内容