介绍
代码审核(
1. Code Review 是什么
为什么要 Code Review, 有什么好处?
- 有利于统一代码规范, 代码风格,结构写法,注释风格等;
- 业务逻辑,安全隐患,性能问题等都可以通过 review 的方式发现;
- 编程的时候,如果你知道有同事会检查你的代码,你的态度就会变的不一样, 你会写出更加整洁,有完整注释的代码;
- 更早的发现代码中的问题.越往后,Code Review 的效果越差,修复的成本也越来越高;
- 熟悉别人的代码, 有助于人员备份;
2. Gerrit 简介
- Gerrit 官网: https://www.gerritcodereview.com/
- Gerrit 官方文档: https://gerrit-documentation.storage.googleapis.com/Documentation/3.0.3/index.html
image.png
image.png
通过
工作流程
image.png
使用过 git 的同学,都知道,当我们
那么
无论有新的代码提交待审核,代码审核通过或被拒绝,代码提交者 (
整个流程就是上面这样。 在使用过程中,有两点需要特别注意下:
-
当进行
commit 时,必须要生成一个Change-Id ,否则,push 到gerrit 服务器时,会收到一个错误提醒。 -
提交者不能直接把代码推到远程的
master 主线 (或者其他远程分支) 上去。这样就相当于越过了gerrit 了。gerrit 必须依赖于一个refs/for/* 的分支。假如我们远程只有一个
master 主线,那么只有当你的代码被提交到refs/for/master 分支时,gerrit 才会知道,我收到了一个需要审核的代码推送,需要通知审核员来审核代码了。当审核通过之后,gerrit 会自动将这条分支合并到master 主线上,然后邮件通知相关成员,master 分支有更新,需要的成员再去pull 就好了。而且这条refs/for/master 分支,是透明的,也就是说普通成员其实是不需要知道这条线的,如果你正确配置了sourceTree ,你也应该是看不到这条线的。
这两点很重要!!这两点很重要!!这两点很重要!!
Gerrit 安装和配置
这里安装的gerrit版本是
1. 环境准备
- 系统需要基于
unix 的服务器,包括任何linux 风格的、Mac ,这里使用Mac ; -
JDK ,使用 1.8 版本就行, 官网显示gerrit与java 9或更新版本还不兼容。 -
nginx/apache ,作为认证和反向代理服务器; -
MySQL ,其实这个非必须,Gerrit 自带的有 H2 数据库 -
Maven , 非必须,在安装的过程中会下载一些 jar 文件; -
Git , 用来拉取代码. -
Gitlab , gerrit就是要配合git使用的
2. Java 环境安装
下载:jdk-8 : https://www.oracle.com/technetwork/java/javase/downloads/index.html
这里下载的是:
配置:
1 2 3 4 5 | # java export JAVA_HOME="/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre" export JRE_HOME="$JAVA_HOME/jre" export CLASSPATH="$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH" export PATH="$JAVA_HOME/bin:$JRE_HOME/bin:$PATH” |
3. nginx/git/gitlab安装就不再这里多介绍了
-
nginx 安装参考 : mac brew 安装nginx和php -
gitlab 安装参数:docker 下 gitlab 安装配置使用 (完整版)
4. gerrit安装和配置
下载
1 | $ wget https://www.gerritcodereview.com/download/gerrit-3.0.3.war |
安装
1 | $ java -jar gerrit-3.0.3.war init -d /lnmp/gerrit |
下面是我从网找到的
gerrit 配置项,根据你安装的版本不同gerrit 会出现的配置项是不同的. 安装时如果你不改配置和不确定是什么,可以直接回车忽略.
gerrit支持的数据库有:H2 ,PostgreSQL ,MariaDB ,MySQL .h2 是它自带的数据库;
gerrit登录认证类型支持的有:OpenID ,OpenID_SSO ,HTTP ,HTTP_LDAP ,CLIENT_SSL_CERT_LDAP ,LDAP ,LDAP_BIND ,OAUTH ,DEVELOPMENT_BECOME_ANY_ACCOUNT , 默认是OpenID类型.不过网上很多教程,使用的是HTTP认证类型
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 | 1.Create '/home/sela/review_site' [Y/n]? Y 2.Location of Git repositories [git]: 3.Database server type [h2]: mysql #数据库类型 4.Server hostname [localhost]: #数据库host 5.Server port [(mysql default)]: #数据库端口 6.Database name [reviewdb]: #数据库名 7.Database username [sela]: #数据库用户名 8.Type [LUCENE/?]: 9.Authentication method [OPENID/?]: oauth #认证方式 10.Get username from custom HTTP header [y/N]? 11.SSO logout URL : 12.Enable signed push support [y/N]? 13.Install Verified label [y/N]? 14.SMTP server hostname [localhost]: smtp.163.com #smtp邮箱配置 15.SMTP server port [(default)]: 25 16.SMTP encryption [NONE/?]: 17.SMTP username [sela]: #写完整的邮箱地址 18.Behind reverse proxy [y/N]? y 19.Proxy uses SSL (https://) [y/N]? N 20.Subdirectory on proxy server [/]: 21.Listen on address [*]: http://127.0.0.1 #监听的地址 22.Listen on port [8080]: #监听的端口 23.Canonical URL [https://127.0.0.1:8081/]: http://liuxd.gerrit.com #gerrit的主页地址 其他配置... |
下面是我安装
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | $ java -jar gerrit-3.0.3.war init -d /lnmp/gerrit Using secure store: com.google.gerrit.server.securestore.DefaultSecureStore [2019-10-30 11:18:19,458] [main] INFO com.google.gerrit.server.config.GerritServerConfigProvider : No /lnmp/gerrit/etc/gerrit.config; assuming defaults *** Gerrit Code Review 3.0.3 *** Create '/lnmp/gerrit' [Y/n]? Y *** Git Repositories *** Location of Git repositories [git]: *** Index *** Type [lucene/?]: *** User Authentication *** Authentication method [openid/?]: oauth #认证方式 Git/HTTP authentication [http/?]: http Enable signed push support [y/N]? *** Review Labels *** Install Verified label [y/N]? *** Email Delivery *** SMTP server hostname [localhost]:smtp.163.com #邮箱配置 SMTP server port [(default)]: SMTP encryption [none/?]: SMTP username [edz]:[email protected] #完整的邮箱 [email protected] password : #邮箱密码 confirm password : #确认密码 *** Container Process *** Run as [edz]: #gerrit运行用户 Java runtime [/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre]: Copy gerrit-3.0.3.war to /lnmp/gerrit/bin/gerrit.war [Y/n]? Copying gerrit-3.0.3.war to /lnmp/gerrit/bin/gerrit.war *** SSH Daemon *** Listen on address [*]: #ssh监听地址 Listen on port [29418]: #ssh监听端口 Generating SSH host key ... rsa... ed25519... ecdsa 256... ecdsa 384... ecdsa 521... done *** HTTP Daemon *** Behind reverse proxy [y/N]? Use SSL (https://) [y/N]? y Listen on address [*]: 127.0.0.1 #http监听地址 Listen on port [8080]: 8081 #http监听端口 Canonical URL [https://127.0.0.1:8081/]: http://liuxd.gerrit.com Create new self-signed SSL certificate [Y/n]? #是否生成签名证书 Certificate server name [liuxd.gerrit.com]: Certificate expires in (days) [365]: 36500 *** Cache # 缓存文件 *** *** Plugins # 安装插件 *** Installing plugins. Install plugin codemirror-editor version v3.0.3 [y/N]? y Installed codemirror-editor v3.0.3 Install plugin commit-message-length-validator version v3.0.3 [y/N]? y Installed commit-message-length-validator v3.0.3 Install plugin delete-project version v3.0.3 [y/N]? y Installed delete-project v3.0.3 Install plugin download-commands version v3.0.3 [y/N]? y Installed download-commands v3.0.3 Install plugin gitiles version v3.0.3 [y/N]? y Installed gitiles v3.0.3 Install plugin hooks version v3.0.3 [y/N]? y Installed hooks v3.0.3 Install plugin plugin-manager version v3.0.3 [y/N]? y Installed plugin-manager v3.0.3 Install plugin replication version v3.0.3 [y/N]? y Installed replication v3.0.3 Install plugin reviewnotes version v3.0.3 [y/N]? y Installed reviewnotes v3.0.3 Install plugin singleusergroup version v3.0.3 [y/N]? y Installed singleusergroup v3.0.3 Install plugin webhooks version v3.0.3 [y/N]? y Installed webhooks v3.0.3 Initializing plugins. Initialized /Users/edz/lnmp/gerrit Reindexing projects: 100% (2/2) with: reindex --site-path /lnmp/gerrit --threads 1 --index projects Reindexed 2 documents in projects index in 0.2s (9.7/s) Executing /lnmp/gerrit/bin/gerrit.sh start Starting Gerrit Code Review: FAILED error: cannot start Gerrit: exit status 1 Waiting for server on liuxd.gerrit.com:80 ... OK Opening http://liuxd.gerrit.com/#/admin/projects/ ...OK |
配置文件:
信息文件:
配置文件
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 30 31 | [gerrit] basePath = git # 存放代码的目录 #gerrit的主页地址,这个地址要通过nginx反向代理到下面配置的http监听的地址端口上 canonicalWebUrl = http://liuxd.gerrit.com serverId = f8be05a7-f43d-42e2-9866-f121892516b6 [container] javaOptions = "-Dflogger.backend_factory=com.google.common.flogger.backend.log4j.Log4jBackendFactory#getInstance" javaOptions = "-Dflogger.logging_context=com.google.gerrit.server.logging.LoggingContext#getInstance" user = edz javaHome = /Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre [index] type = LUCENE [auth] type = OAUTH # oauth登录认证类型 gitBasicAuthPolicy = HTTP [receive] enableSignedPush = false [sendemail] smtpServer = smtp.163.com # 邮箱配置 smtpUser = [email protected] smtpServerPort = 25 from = [email protected] # 发送邮箱,这个项目安装配置项内没有,需要手动在配置文件中添加,不然gerrit3.0发送邮件失败 [sshd] listenAddress = *:29418 [httpd] listenUrl = http://127.0.0.1:8081/ # 监听地址和端口 [cache] directory = cache [plugin "gerrit-oauth-provider-gitlab-oauth"] # gitlab oauth认证相关 root-url = http://liuxd.gitlab.com client-id = dd787b8df8c65753e727d3f94b88f9eda2850fda039cdca8c11259b4a6b24f |
信息文件
1 2 3 4 5 6 | [auth] registerEmailPrivateKey = p7N8E0zAJxeyCde+nl9TVmBTwskkFYNEY= [sendemail] smtpPass = email_passwd # 邮箱密码 [plugin "gerrit-oauth-provider-gitlab-oauth"] client-secret = 74df2494d720da4223141251d9694e4d76a195f86d1a7a96095255c98e5822 |
5. nginx反向代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | server { listen 80; server_name liuxd.gerrit.com; index index.html index.htm index.php; access_log /lnmp/log/nginx/gerrit.access.log; error_log /lnmp/log/nginx/gerrit.error.log; #allow all; #deny all; #auth_basic "Welcomme to Gerrit Code Review Site!"; #auth=type认证时,弹出验证登录对话框提示 #auth_basic_user_file /lnmp/gerrit/etc/gerrit.password; #auth=type认证时,登录认证文件存放路径 location / { # 代理的指向的gerrit监听端口 proxy_pass http://127.0.0.1:8081; } } |
重新加载nginx配置
1 | $ nginx -s reload |
修改hosts
1 2 | $ vim /etc/hosts 127.0.0.1 liuxd.gerrit.com |
6. gerrit配置-HTTP认证(不推荐)
配置 gerrit 账户密码 (http登录验证模式)
1 2 3 | # 修改配置文件中的配置项 [auth] type = http # http登录认证类型 |
上面
1 2 3 | $ touch /lnmp/gerrit/etc/gerrit.password $ htpasswd -b /lnmp/gerrit/etc/gerrit.password edz 123456 #管理员 $ htpasswd -b /lnmp/gerrit/etc/gerrit.password gerrit1 123456 #普通用户 |
-c 新增用户, 会提示输入2遍密码, 重复使用会覆盖掉原来的文件
-b 使用命令行中的密码新增用户,而不是提示输入密码。
-m 追加一个用户或修改用户密码
权限问题
由于我的gerrit是安装到了,我的家目录下面, 所以上面的配置的登录用户,只有和我用户名一样的,才能正常登录显示, 不一样的就是登录上了,也是显示
image.png
如果你已经成功登录了gerrit的网页,那么如果你想退出,请直接关闭整个浏览器,gerrit没有做logout的session清除,
7. gerrit配置-oauth认证
我们这里使用一个
构建安装这个插件需要
1 2 3 4 5 6 | # 通过bazel安装 $ cd ~/Downloads $ git clone https://github.com/davido/gerrit-oauth-provider.git $ cd gerrit-oauth-provider $ bazel build gerrit-oauth-provider $ cp bazel-genfiles/oauth.jar /lnmp/gerrit/plugins/ |
1 2 3 4 5 | # 直接下载构建好的release $ wget https://github.com/davido/gerrit-oauth-provider/releases/download/v3.0.0/gerrit-oauth-provider.jar # 注意直接下载jar形式,在copy时一定要将jar的名改成oauth.jar,不然的话oauth回跳的时候是不成功的 $ cp gerrit-oauth-provider.jar /lnmp/gerrit/plugins/oauth.jar |
注意直接下载jar形式,在copy时一定要将jar的名改成oauth.jar,不然的话oauth回跳的时候是不成功的.
详细的
再次配置gerrit的配置项, 这次可以不用修改配置项,一直回车,直到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | $ cd /lnmp/gerrit/bin $ java -jar gerrit.war init -d /lnmp/gerrit … … Use Google OAuth provider for Gerrit login ? [Y/n]? n Use GitHub OAuth provider for Gerrit login ? [Y/n]? n Use Bitbucket OAuth provider for Gerrit login ? [Y/n]? n Use CAS OAuth provider for Gerrit login ? [Y/n]? n Use Facebook OAuth provider for Gerrit login ? [Y/n]? n Use GitLab OAuth provider for Gerrit login ? [Y/n]? Y GitLab Root URL : http://liuxd.gitlab.com Application client id : 5df1920c829ac7d2672c7cf1b08ded84bba4f50734db99fd4ff5ab7f0b380e6c Application client secret : confirm password : Use Dex OAuth provider for Gerrit login ? [Y/n]? n Use Keycloak OAuth provider for Gerrit login ? [Y/n]? n Use Office365 OAuth provider for Gerrit login ? [Y/n]? n Use AirVantage OAuth provider for Gerrit login ? [Y/n]? n Initialized /Users/edz/lnmp/gerrit Reindexing projects: 100% (2/2) with: reindex --site-path /lnmp/gerrit --threads 1 --index projects Reindexed 2 documents in projects index in 0.5s (4.3/s) # 重启gerrit $ ./gerrit.sh restart |
再次登录
8. gerrit配置mysql数据库
gerrit从3.x系统开始采用
如果想更换数据库的话,需要借助MigrateAccountPatchReviewDb来迁移,迁移时要停止gerrit服务.
还要注意,db_name必须是一个新的db,并且不能重用以前2.x站点中的旧reviewdb数据库,否则gerrit的init将删除该表。
下面是官方文档中的说明
[图片上传失败...(image-50f5cd-1573816457127)]
数据库连接配置项
1 2 | [accountPatchReviewDb] url = jdbc:postgresql://<host>:<port>/<db_name>?user=<user>&password=<password> |
使用
- 有利于数据数据管理,mysql有丰富的界面和sql语法.
- 有利于数据的备份,和恢复
- 有利于服务的扩展,如一台服务器增加到多台服务器
Mysql库和用户创建(如果要采用mysql数据库)
如果准备让gerrit采用mysql数据库的话, 我们要先将gerrit连接的用户和库创建出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # 创建数据库reviewdb mysql> create database reviewdb; Query OK, 1 row affected (0.01 sec) mysql> CREATE USER 'gerrit'@'localhost' IDENTIFIED BY 'gerrit'; Query OK, 0 rows affected (0.00 sec) mysql> CREATE USER 'gerrit'@'127.0.0.1' IDENTIFIED BY 'gerrit'; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) mysql> grant all privileges on reviewdb.* to gerrit@localhost identified by 'gerrit'; Query OK, 0 rows affected (0.00 sec) # 10.*.*.*为部署gerrit服务的内网地址 mysql> grant all privileges on reviewdb.* to gerrit@'10.*.*.*' identified by 'gerrit'; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) |
Gerrit常用命令
gerrit.sh {start|stop|restart|check|status|run|supervise|threads} -
gerrit.sh start #启动 -
gerrit.sh stop #停止 -
gerrit.sh restart #重启
关联Gitlab
-
先检测
plugins/replication.jar 扩展有没有安装,没有安装的话,通过java -jar gerrit.war init -d /lnmp/gerrit 来安装扩展. -
配置
gerrit 下的etc/replication.config 文件,如果etc 目录下没有这个文件则创建[remote "liuxd.gitlab.com"]
url = ssh://[email protected]:222/${name}.git
push = +refs/heads/:refs/heads/
push = +refs/tags/:refs/tags/
push = +refs/changes/:refs/changes/
timtout = 30
threads = 3 -
配置
~/.ssh/config 文件,如果.ssh 目录下没有这个文件则创建Host liuxd.gitlab.com
User [email protected]
Port 222
IdentityFile ~/.ssh/id_rsa
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
PreferredAuthentications publickey
- 重启
gerrit
问题
-
Gerrit Replication 报 Invalid privatekey 错误原因:
id_rsa 文件的注释是 -----Begin openssh private key---
需要生成格式是 -----begin RSA private key---的才行
解决:1、使用ssh-keygen -t rsa -m PEM -C '[email protected]' 命令重新生成id_rsa 文件;
2、将id_rsa.pub 重新添加到gerrit 管理员账号秘钥中. -
logs/error_log 文件中没有报错信息,但gerrit 未push 到git . 可以通过查看logs/replication_log 中的报错信息来定位 -
logs/replication_log 中push时报错Failed replicate of refs/heads/master to ssh://[email protected]:222/www/test_project.git, reason: pre-receive hook declined
权限问题,有可能是gerrit push 代码的用户是Develop 角色默认下没有远程访问master的权限.
解决方案:在项目的【Setting】中的【Protected branches】可以设置哪些分支是被保护的,默认情况下【master】分支是处于被保护状态下的,develop角色的人是无法提交到master分支的,在下面的【Developers can push】打上钩就可以了。
image.png
Gerrit的使用
1. 创建项目
使用
image.png
上面是创建的项目目录在: /lnmp/gerrit/git/www/test_project.git
2. gitlab代码同步到gerrit
- 先在其他地方从
gitlab 拉取一份代码
1 2 3 |
- 删除原
gerrit 项目的git 文件
1 2 | $ cd /lnmp/gerrit/git/www/test_project.git $ rm -rf * |
- 将
gitlab 代码下的.git 目录中的文件复制到gerrit 项目中
1 2 3 | $ cd ~/test_project $ cd .git $ cp -R ./* /lnmp/gerrit/git/www/test_project.git/ |
- 现在
gitlab 已经同步到gerrit 了,可能通过gerrit 来拉取代码了
3. 增加SSH Keys
将
1 | $ cat ~/.ssh/id_rsa.pub |
将
image.png
4. 拉取项目代码
使用开发人员账户来登录
通过
image.png
5. gerrit提交代码流程
- 修改过代码后, 用
git add ./ 来添加修改过的文件; - 然后用
git commit -m "提交注释" 提交到本地分支,并且这时gerrit 会通过勾子脚本生成一个Change-Id 用于code review使用; - 如果多次提交可以用
git commit --amend 来追加提交; - 提交到
gerrit 远程分支git push 远程地址 本地分支:refs/for/远程分支 ;
具体代码执行如下
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 | $ git add ./ $ git commit -m '12345' [master f488a3b] 12345 1 file changed, 1 insertion(+) create mode 100644 test.php $ git log commit f488a3b56bf790e904bc4684621f434745fdcee0 (HEAD -> master) Author: liuxiandong <[email protected]> Date: Mon Nov 4 18:54:56 2019 +0800 12345 Change-Id: I394d35d0c2f43fead70b646463e5a806ed5d1ec3 $ git push origin master:refs/for/master Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Writing objects: 100% (3/3), 279 bytes | 279.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) remote: Processing changes: refs: 1, new: 1, done remote: remote: SUCCESS remote: remote: http://liuxd.gerrit.com/c/www/test_project/+/1 12345 [NEW] remote: To ssh://liuxd.gerrit.com:29418/www/test_project * [new branch] master -> refs/for/master |
6. 简化gerrit提交命令
1 2 | $ cd /lnmp/gerrit/bin $ vim gerrit |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #/bin/bash oper=$1; local_branch=$2; origin_branch=$3; if [ $oper = '' ]; then echo '请输入要进行的操作'; exit; fi if [ $local_branch = '' ]; then echo '请输入本地分支名'; exit; fi if [ $origin_branch = '' ]; then echo '请输入远程分支名'; exit; fi /usr/bin/git ${oper} origin ${local_branch}:refs/for/${origin_branch} |
给
1 2 3 4 5 6 7 | $ chmod a+x gerrit $ vim ~/.bash_profile #gerrit export PATH="/lnmp/gerrit/bin:$PATH" $ source ~/.bash_profile |
下次再提交就可以用
Gerrit审核 - code review
审核流程
代码提交后,在gerrit的
image.png
在列表中点击要
注意:提交人不能自己审核自己的代码,需要第二个人来审核
image.png
code review后, 再点击
image.png
参考链接:
- 关于 Gerrit code review 介绍与安装 : https://www.cnblogs.com/chenpingzhao/p/9337117.html
- centos部署配置gerrit+gitlab实现代码的review与自动同步:https://blog.51cto.com/nanfeibobo/2089513