關於Gerrit code review 介紹與安裝


代碼審核(Code Review)是軟件研發質量保障機制中非常重要的一環,但在實際項目執行過程中,卻因為種種原因被Delay甚至是忽略。在實踐中,給大家推薦一款免費、開放源代碼的代碼審查軟件Gerrit。

一、 Code Review是什么

Code Review最直觀的解釋即看代碼。常規的做法為自己看,有時代碼邏輯問題可能自己看不出來,需要找同事一起看,在大家知識體系相對平均的情況下可能需要花錢專門的公司幫助查看。

Code Review需要看哪些?對於剛入職場或者剛接觸到Coding的新人來說,代碼風格是比較重要的一塊。除此之外,編碼規范及代碼結構寫法,框架和工具的選型,具體項目的業務邏輯,安全隱患,性能問題等都可以通過review的方式發現。Code Review從前往后大致分為結對編程,提交代碼后,測試之前,發版之前,發版之后等幾個階段,越往后,Code Review的效果越差,修復的成本也越來越高。

為什么一定要做入庫前Code Review?

首先,代碼審查的最大的功用是純社會性的。如果你在編程,而且知道將會有同事檢查你的代碼,你編程態度就完全不一樣了。你寫出的代碼將更加整潔,有更好的注釋和程序結構。

其次,偷懶是人的天性,從節約成本的角度考慮,大家一般會選擇在測試之前無限制的Delay Code Review。入庫前做Code Review便是成本和效果之間最佳平衡點,它能及時發現問題,進行修改后確保代碼質量。

最后,代碼審查能傳播知識。在很多開發團隊里,經常每個人負責一個核心模塊,每個人都只關注自己的模塊。除非是同事的模塊影響了自己的程序,他們從不相互交流。這種情況的后果是,每個模塊只有一個人熟悉里面的代碼。如果這個人休假或辭職了,其他人則束手無策。通過代碼審查,至少會有兩個人熟悉這些程序——作者,以及審查者。審查者並不能像程序的作者一樣對程序十分了解,但至少他會熟悉程序的設計和架構,這是極其重要的。

二、 Gerrit簡介

Gerrit是Google為Android系統研發量身定制的一套免費開源的代碼審核系統,它在傳統的源碼管理協作流程中強制性引入代碼審核機制,通過人工代碼審核和自動化代碼驗證過程,將不符合要求的代碼屏蔽在代碼庫之外,確保核心代碼多人校驗、多人互備和自動化構建核驗。

Gerrit之前的系統架構:

 

Gerrit之后的系統架構:

 

通過Gerrit機制將代碼做分隔。

Gerrit適用性

幾乎任何需要正式發布的項目都應當使用Gerrit來進行代碼審查,如果Team中有新人,必須使用Gerrit確保代碼質量。

 

工作流程

 

使用過git的同學,都知道,當我們git add --> git commit --> git push 之后,你的代碼會被直接提交到repo,也就是代碼倉庫中,就是圖中橘紅色箭頭指示的那樣。

那么gerrit就是上圖中的那只鳥,普通成員的代碼是被先push到gerrit服務器上,然后由代碼審核人員,就是左上角的integrator在web頁面進行代碼的審核(review),可以單人審核,也可以邀請其他成員一同審核,當代碼審核通過(approve)之后,這次代碼才會被提交(submit)到代碼倉庫(repo)中去。

無論有新的代碼提交待審核,代碼審核通過或被拒絕,代碼提交者(Contributor)和所有的相關代碼審核人員(Integrator)都會收到郵件提醒。
gerrit還有自動測試的功能,和主線有沖突或者測試不通過的代碼,是會被直接拒絕掉的,這個功能似乎就是右下角那個老頭(Jenkins)的任務。

整個流程就是這樣。 在使用過程中,有兩點需要特別注意下:

  1. 當進行commit時,必須要生成一個Change-Id,否則,push到gerrit服務器時,會收到一個錯誤提醒。
  2. 提交者不能直接把代碼推到遠程的master主線(或者其他遠程分支)上去。這樣就相當於越過了gerrit了。 gerrit必須依賴於一個refs/for/*的分支。

    假如我們遠程只有一個master主線,那么只有當你的代碼被提交到refs/for/master分支時,gerrit才會知道,我收到了一個需要審核的代碼推送,需要通知審核員來審核代碼了。
    當審核通過之后,gerrit會自動將這條分支合並到master主線上,然后郵件通知相關成員,master分支有更新,需要的成員再去pull就好了。而且這條refs/for/master分支,是透明的,也就是說普通成員其實是不需要知道這條線的,如果你正確配置了sourceTree,你也應該是看不到這條線的。

這兩點很重要!!這兩點很重要!!這兩點很重要!!

三、Gerrit安裝

3.1. 環境准備

  • ①. Linux,Gerrit需要Linux環境,ubuntu 或者  centos,這里使用Ubuntu;

  • ②. JDK,使用1.7版本就行

  • ③. MySQL,其實這個非必須,Gerrit自帶的有H2數據庫

  • ④. nginx/apache,作為認證和反向代理服務器;

  • ⑤. Maven, 在安裝的過程中會下載一些jar文件;

  • ⑥. Git,用來拉取代碼

3.2 java環境安裝

下載:jdk-7u79-linux-x64.tar.gz http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html

安裝:sudo tar zxvf ./jdk-7u79-linux-x64.tar.gz -C /opt

配置:vim ~/.bashrc(針對當前用戶) or vim /etc/profile(針對所有用戶,推薦)

export JAVA_HOME=/opt/jdk1.7.0_79
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

驗證:

java -version

java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

3.3 git環境

gerrit依賴,用來操作git repository

sudo apt-get install git

3.4 下載gerrit

wget  https://www.gerritcodereview.com/download/gerrit-2.12.4.war

3.5 apache2安裝

sudo apt-get install apache2 

驗證:

service apache2 start

3.6 gerrit管理帳號

gerrit依賴,用來管理gerrit。

sudo adduser gerrit
sudo passwd gerrit

並將gerrit加入sudo權限

sudo visudo

gerrit  ALL=(ALL:ALL) ALL (為了測試方便,開最大權限)

3.7 配置gerrit

默認安裝:

java -jar gerrit-2.12.4.war init --batch -d ~/review_site

更新配置文件:sudo vim ~/review_site/etc/gerrit.config

[gerrit]
        basePath = git
        canonicalWebUrl = http://47.120.74.47:8081/
[database]
        type = h2
        database = /home/gerrit/review_site/db/ReviewDB
[index]
        type = LUCENE
[auth]
        type = http
[receive]
        enableSignedPush = false
[sendemail]
        smtpServer = smtp.163.com
        smtpServerPort = 465
        smtpEncryption = ssl
        smtpUser = avcd@163.com
        smtpPass = avcd123123123
        sslVerify = false
        from = code review<avcd@163.com>
[container]
        user = gerrit
        javaHome = /opt/jdk1.7.0_79/jre
[sshd]
        listenAddress = *:29418
[httpd]
        listenUrl = http://*:8081/
[cache]
        directory = cache

[http]
        proxy = http://47.120.74.47:8090
        proxyUsername = gerrit1 #proxy user & password
        proxyPassword = 123456

3.8 配置apache2反向代理

a、如果apache目錄結構如下:

apache2.conf conf-enabled magic mods-enabled ports.conf sites-enabled conf-available envvars mods-available sites-available

開啟SSL、Proxy、Rewrite等模塊:

cd /etc/apache2/mods-enabled
ln -s ../mods-available/proxy.load
ln -s ../mods-available/proxy.conf
ln -s ../mods-available/proxy_http.load
ln -s ../mods-available/proxy_balancer.conf
ln -s ../mods-available/proxy_balancer.load
ln -s ../mods-available/rewrite.load
ln -s ../mods-available/ssl.conf
ln -s ../mods-available/ssl.load
ln -s ../mods-available/socache_shmcb.load #
ln -s ../mods-available/slotmem_shm.load #

更新配置文件:sudo vim /etc/apache2/sites-enabled/gerrit-httpd.conf

ServerName 47.200.74.47
<VirtualHost *:8090>
    ProxyRequests Off
    ProxyVia Off
    ProxyPreserveHost On
    AllowEncodedSlashes On
    RewriteEngine On
    RewriteRule ^/(.*) http://47.200.74.47:8081/$1 [NE,P]

    <Proxy *>
          Order deny,allow
          Allow from all
    </Proxy>

    <Location /login/>
        AuthType Basic
        AuthName "Gerrit Code Review"
        Require valid-user
        AuthBasicProvider file
        AuthUserFile /etc/apache2/passwords
    </Location>

    ProxyPass / http://127.0.0.1:8081/

</VirtualHost> 

b、如果apache目錄結構如下:

bin  build  cgi-bin  conf  error  htdocs  icons  include  lib  logs  man  manual  modules

開啟SSL、Proxy、Rewrite等模塊:

# Open LoadModule
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule rewrite_module modules/mod_rewrite.so
# Gerrit config
Include conf/extra/gerrit-httpd.conf 

其中apache2/conf/extra/gerrit-httpd.conf內容同上,apache2/sites-enabled/gerrit-httpd.conf。

3.9 配置gerrit賬戶密碼

touch /etc/apache2/passwords
htpasswd -b /etc/apache2/passwords admin 123456(管理員)
htpasswd -b /etc/apache2/passwords gerrit1 123456(普通用戶)

3.10 啟動gerrit&啟動apache2

sudo ~/review_site/bin/gerrit.sh start
sudo /etc/init.d/apache2 start

四、如何使用gerrit

前提:需要git使用端 / gerrit服務端配合使用。

4.1 添加項目(gerrit 服務端)

ssh -p 29418 gerrit1@47.200.74.47 gerrit create-project --empty-commit --name demo-project

#建議采用管理界面添加

 

4.2 使用gerrit添加已有項目:(適用於已有項目下移植到gerrit中)

ssh -p 29418 gerrit1@192.168.199.112 gerrit create-project --name exist-project #建議采用管理界面添加

或者使用gerrit管理界面

然后將已有項目與gerrit上建立的exist-project關聯,即將已有代碼庫代碼push到gerrit中進行管理。

cd ~/exist-project

git push ssh://gerrit1@47.200.74.47:29418/exist-project *:*

4.3.生成sshkey(git使用端)

在開發賬戶中生成sshkey,用作與gerrit服務器連接。

ssh-keygen -t rsa #生成sshkey

4.4.添加sshkey到gerrit服務器(gerrit 服務端)

此步驟與git流程類似,即將id_rsa.pub內容上傳到git repository,gerrit中幫我們管理git repository.

4.5 拉取代碼&配置git hooks(git client端)

驗證sshkey是否配置成功:ssh gerrit1@47.200.74.47 -p 29418

  ****    Welcome to Gerrit Code Review    ****

  Hi gerrit1, you have successfully connected over SSH.

  Unfortunately, interactive shells are disabled.
  To clone a hosted Git repository, use:

  git clone ssh://gerrit1@47.200.74.47:29418/REPOSITORY_NAME.git

Connection to 47.200.74.47 closed.

拉取代碼: 

git clone ssh://gerrit1@47.200.74.47:29418/REPOSITORY_NAME.git

更新githooks:

gitdir=$(git rev-parse --git-dir); scp -p -P 29418 gerrit1@47.200.74.47:hooks/commit-msg ${gitdir}/hooks/

該過程用來在commit-msg中加入change-id,gerrit流程必備。

修改代碼並提交,推送時與原有git流程不一致,采用 git push origin HEAD:refs/for/master 。

[root@iZ62j8121e5Z abcd]# git push origin HEAD:refs/for/master
Counting objects: 3, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 710 bytes | 710.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Processing changes: new: 1, refs: 1, done    
remote: 
remote: New Changes:
remote:   http://47.200.74.47:8081/5 xxxx
remote: 
To ssh://47.200.74.47:29418/abcd
 * [new branch]      HEAD -> refs/for/master

如果不加會提示一下錯誤:

[root@iZ62j8121e5Z abcd]# git push origin HEAD:refs/for/master
Counting objects: 3, done.
Writing objects: 100% (3/3), 239 bytes | 239.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Processing changes: refs: 1, done    
remote: ERROR: missing Change-Id in commit message footer
remote: 
remote: Hint: To automatically insert Change-Id, install the hook:
remote:   gitdir=$(git rev-parse --git-dir); scp -p -P 29418 admin@47.200.74.47:hooks/commit-msg ${gitdir}/hooks/
remote: And then amend the commit:
remote:   git commit --amend
remote: 
To ssh://47.200.74.47:29418/abcd
 ! [remote rejected] HEAD -> refs/for/master (missing Change-Id in commit message footer)
error: failed to push some refs to 'ssh://admin@47.200.74.47:29418/abcd'

五.使用gerrit website完成code review

當完成push后,可在gerrit管理界面看到當前提交code review的change。

查看某次提交的詳細信息(審核者+2可通過本次提交,提交者可通過Abandon本次提交):

如果審核者+2通過后,可提交該次commit.

 

六 注意事項

  • 需要為每個使用者分配gerrit賬號,不要都使用admin賬號,因為admin賬號可直接push master

  • pull代碼后需要配置githooks文件,以便在commit時自動生成change-id,否則無法push

  • push代碼時需要使用git push origin HEAD:refs/for/master(branch),gerrit默認關閉非admin賬號的push direct權限

  • push代碼時需要commit email與gerrit account email一致,否則無法push成功,可選擇關閉email notify,並開啟forge user權限,或者通過修改gerrit數據庫account email信息

  • gerrit數據庫與gitlab同步,需要安裝replication插件,並開啟該功能 

 

參考鏈接:

Java SDK Download: http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html

Gerrit Code Review - Releases Download: https://gerrit-releases.storage.googleapis.com/index.html

Gerrit Code Review -  Quick get started guide: https://git.eclipse.org/r/Documentation/install-quick.html

Gerrit代碼審核流程 http://www.worldhello.net/gotgit/images/gerrit-workflow.png

Gerrit代碼審核原理 http://www.worldhello.net/gotgit/05-git-server/055-gerrit.html

Gerrit代碼審核權限管理 https://gerrit-review.googlesource.com/Documentation/access-control.html#category_forge_committer

Gerrit修改數據庫email信息 http://www.cnblogs.com/kevingrace/p/5624122.html

Gerrit安裝replication插件 https://gerrit-review.googlesource.com/Documentation/cmd-plugin-install.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM