目錄
- 0x10 概述
- 0x20 我的應(yīng)用環(huán)境
- 0x30 路線(xiàn)圖
- 0x40 安裝
0x41 LNMP環(huán)境的安裝
0x42 Phabricator源碼下載及運(yùn)行- 0x50 配置
0x51 解決基本的配置問(wèn)題
0x52 設(shè)置用戶(hù)登錄認(rèn)證方式
0x53 設(shè)置郵件發(fā)送服務(wù)參數(shù)
0x54 配置代碼倉(cāng)庫(kù)訪(fǎng)問(wèn)方式:SSH/HTTP- 0x60 使用Phabricator進(jìn)行Code Review
0x61 Phabricator Code Review工作流
0x62 進(jìn)行Code Review所用工具
0x63 配置進(jìn)行Code Review- 0x70 與GitHub集成
- 0x80 與Jenkins集成
- 0x90 結(jié)束語(yǔ)
- 0xA0 Q/A
0x10 概述
Phabricator是一套基于Web的軟件開(kāi)發(fā)協(xié)作工具,包括代碼審查工具Differential,資源庫(kù)瀏覽器Diffusion,變更監(jiān)測(cè)工具Herald,Bug跟蹤工具M(jìn)aniphest和維基工具Phriction。Phabricator可與Git、Mercurial、Subversion集成使用。
Phabricator是開(kāi)源軟件,可在A(yíng)pache許可證第2版下作為自由軟件分發(fā)。
Phabricator最初是Facebook的一個(gè)內(nèi)部工具,主要開(kāi)發(fā)者為Evan Priestley。Evan Priestley離開(kāi)Facebook后,在名為Phacility的新公司繼續(xù)Phabricator的開(kāi)發(fā)。
官網(wǎng):https://www.phacility.com/
官網(wǎng)中的文檔很多很全,但是如果對(duì)這個(gè)工具不太了解,或者對(duì)于Code Review不太了解的話(huà),讀起來(lái)可能會(huì)覺(jué)得沒(méi)有頭緒。這篇文章就自己的安裝及使用過(guò)程做一個(gè)梳理,對(duì)于同樣想用這個(gè)工具的讀者,或許起到一些幫助作用。
對(duì)于本文中的一些章節(jié),如果在官方文檔有所提及,我會(huì)把官方文檔地址附上,讀者可以閱讀一下官方文檔,因?yàn)樗麄兊恼Z(yǔ)言和表達(dá)更優(yōu)秀。
0x20 我的應(yīng)用環(huán)境
- 我:一個(gè)做了很多年Android的程序員 (所以當(dāng)這篇文章有幸被所涉及領(lǐng)域的專(zhuān)家看到,又發(fā)現(xiàn)有的部分有所不妥,或者有更好的想法時(shí),請(qǐng)主動(dòng)聯(lián)系我改進(jìn),多謝~~~ 有任何問(wèn)題,歡迎評(píng)論交流)
- 主機(jī):Ubuntu 14.04 PC一臺(tái)
- 網(wǎng)絡(luò):內(nèi)網(wǎng)
- 代碼庫(kù):GitHub
- CI:Jenkins
0x30 路線(xiàn)圖
安裝和使用路線(xiàn)大致如此圖,下面開(kāi)始詳細(xì)說(shuō)明。
0x40 安裝
Phabricator是一個(gè)基于Web的工具軟件,使用PHP語(yǔ)言編寫(xiě)的,為了能讓他運(yùn)行起來(lái),我們需要搭建一個(gè)LNMP(Linux,Nginx,MySQL,PHP)的Web Server環(huán)境。搭建完LNMP的環(huán)境后,下載Phabricator源碼,配置后即可使用。
-
先看我
如果你不想讀那么多文字,在Ubuntu環(huán)境下可以試試下面的腳本,這個(gè)腳本可以安裝LNMP環(huán)境和下載Phabricator源碼,執(zhí)行完腳本并成功后,跳到 0x42 Phabricator源碼下載及運(yùn)行 查看如何讓Phabricator跑起來(lái)。
#!/bin/bash
confirm() {
echo "Press RETURN to continue, or ^C to cancel.";
read -e ignored
}
GIT='git'
LTS="Ubuntu 10.04"
ISSUE=`cat /etc/issue`
if [[ $ISSUE != Ubuntu* ]]
then
echo "This script is intended for use on Ubuntu, but this system appears";
echo "to be something else. Your results may vary.";
echo
confirm
elif [[ `expr match "$ISSUE" "$LTS"` -eq ${#LTS} ]]
then
GIT='git-core'
fi
echo "PHABRICATOR UBUNTU INSTALL SCRIPT";
echo "This script will install Phabricator and all of its core dependencies.";
echo "Run it from the directory you want to install into.";
echo
ROOT=`pwd`
echo "Phabricator will be installed to: ${ROOT}.";
confirm
echo "Testing sudo..."
sudo true
if [ $? -ne 0 ]
then
echo "ERROR: You must be able to sudo to run this script.";
exit 1;
fi;
echo "Installing dependencies: git, nginx, mysql, php...";
echo
set +x
sudo apt-get -qq update
sudo apt-get install \
$GIT nginx mysql-server dpkg-dev \
php5 php5-mysql php5-gd php5-dev php5-curl php-apc php5-cli php5-json
# Enable mod_rewrite
sudo a2enmod rewrite
HAVEPCNTL=`php -r "echo extension_loaded('pcntl');"`
if [ $HAVEPCNTL != "1" ]
then
echo "Installing pcntl...";
echo
apt-get source php5
PHP5=`ls -1F | grep '^php5-.*/$'`
(cd $PHP5/ext/pcntl && phpize && ./configure && make && sudo make install)
else
echo "pcntl already installed";
fi
if [ ! -e libphutil ]
then
git clone https://github.com/phacility/libphutil.git
else
(cd libphutil && git pull --rebase)
fi
if [ ! -e arcanist ]
then
git clone https://github.com/phacility/arcanist.git
else
(cd arcanist && git pull --rebase)
fi
if [ ! -e phabricator ]
then
git clone https://github.com/phacility/phabricator.git
else
(cd phabricator && git pull --rebase)
fi
echo
echo
echo "Install probably worked mostly correctly. Continue with the 'Configuration Guide':";
echo
echo " https://secure.phabricator.com/book/phabricator/article/configuration_guide/";
echo
echo "You can delete any php5-* stuff that's left over in this directory if you want.";
關(guān)于安裝和配置,官方文檔中有所提及(官方介紹的是 LAMP),請(qǐng)參考
https://secure.phabricator.com/book/phabricator/article/installation_guide/
0x41 LNMP環(huán)境的安裝
安裝Linux
關(guān)于Linux的安裝,這里就不說(shuō)了。安裝Nginx
sudo apt-get install nginx
安裝完成后,Nginx 的配置文件存放在 /etc/nginx 目錄下。使用下面的命令可以啟動(dòng)Nginx
sudo service nginx start
在安裝完并啟動(dòng)后,可以使用瀏覽器訪(fǎng)問(wèn) http://127.0.0.1 試試是否可以跳轉(zhuǎn)到Nginx歡迎頁(yè)面
-
安裝MySQL
sudo apt-get install mysql-server
在安裝過(guò)程中,會(huì)兩次提示輸入 root 用戶(hù)密碼。
在安裝完成后,打開(kāi)終端,使用以下命令登錄MySQLmysql -u root -p
安裝PHP
Phabricator需要 PHP 5.2 或者更高版本,但是 不支持 PHP 7 。
可以使用以下命令安裝PHP
sudo apt-get install -y php5 php5-fpm php5-mysql
安裝完成后,可使用以下命令查看是否安裝成功
php -v
安裝成功后,輸出類(lèi)似以下信息
-
安裝其它
如果你使用 git 來(lái)管理代碼庫(kù)的話(huà),你還需要安裝 git
sudo apt-get install git
一些必要的PHP擴(kuò)展
mbstring, iconv, mysql (or mysqli), curl, pcntl(這些擴(kuò)展一般會(huì)以 "php-mysql" 或 "php5-mysql" 方式使用)
一些可選的PHP擴(kuò)展
gd, apc(官方文檔中有詳細(xì)的介紹和安裝說(shuō)明), xhprof(如果你想自己開(kāi)發(fā)Phabricator的話(huà),你需要安裝這個(gè),官方文檔中有詳細(xì)的介紹說(shuō)明)
0x42 Phabricator源碼下載及運(yùn)行
在成功安裝LNMP環(huán)境后,需要下載Phabricator的源碼并配置讓它跑起來(lái)。
-
源碼下載
在你想要存放Phabricator源碼的位置(假設(shè)為 ./path_to_pha),執(zhí)行這些命令
git clone https://github.com/phacility/libphutil.git
git clone https://github.com/phacility/arcanist.git
git clone https://github.com/phacility/phabricator.git
或者,你也可以直接點(diǎn)擊上面的鏈接去GitHub下載壓縮包,下載完成后解壓。
-
Nginx配置
在下載完成后,我們需要配置Nginx,讓Phabricator跑起來(lái)。假設(shè)你想為Phabricator分配這個(gè)域名:http://pha.example.com
在 /etc/nginx/conf.d 目錄下創(chuàng)建文件 pha.example.com.conf,存放Phabricator代理配置信息,以下為我的文件內(nèi)容(注意把 你存放Phabricator的路徑 改為你的實(shí)際路徑)
server {
listen 80;
server_name pha.example.com;
location / {
index index.php;
rewrite ^/(.*)$ /index.php?__path__=/$1 last;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root /你存放Phabricator的路徑/phabricator/webroot;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /你存放Phabricator的路徑/phabricator/webroot$fastcgi_script_name;
include fastcgi_params;
}
}
配置完成后,重啟Nginx
sudo service nginx restart
然后在你的 hosts 文件中,加入 pha.example.com 對(duì)應(yīng)的IP
127.0.0.1 pha.example.com
打開(kāi)瀏覽器,訪(fǎng)問(wèn) http://pha.example.com,會(huì)跳轉(zhuǎn)到Phabricator用戶(hù)注冊(cè)界面,在這個(gè)界面注冊(cè)的第一個(gè)用戶(hù),將會(huì)成為管理員用戶(hù)。
0x50 配置
0x51 解決基本的配置問(wèn)題
使用管理員賬號(hào)登錄,左上角會(huì)出現(xiàn)黃色感嘆號(hào)圖標(biāo),提示有一些配置問(wèn)題未解決
這些問(wèn)題基本都是關(guān)于一些參數(shù)的設(shè)置。點(diǎn)擊每一個(gè)問(wèn)題,顯示的界面中會(huì)有很詳細(xì)的關(guān)于這個(gè)問(wèn)題的描述,和如何解決。
0x52 設(shè)置用戶(hù)登錄認(rèn)證方式
使用管理員賬號(hào)登錄,在左側(cè)的菜單中選擇 Auth ,然后點(diǎn)擊右上側(cè) Add Provider,在列表中選則你需要的認(rèn)證方式。
我選擇是 Username/Password 的方式,即用戶(hù)自己注冊(cè)Phabricator賬號(hào)。為了保障安全,我設(shè)置了只允許公司郵箱地址注冊(cè):Config ---> Core Settings ---> ** Authentication** ---> auth.email-domains。你還可以選擇 auth.require-approval ,即新注冊(cè)用戶(hù)需要管理員批準(zhǔn)。
0x53 設(shè)置郵件發(fā)送服務(wù)參數(shù)
首先,配置 mail-adapter (郵件發(fā)送方式):Config ---> Core Settings ---> Mail ---> metamta.mail-adapter,我選擇的是 PhabricatorMailImplementationPHPMailerAdapter ,通過(guò)SMTP的方式發(fā)送郵件。在選擇完之后,需要設(shè)置SMTP服務(wù)器地址、賬號(hào)和密碼:Config ---> Core Settings ---> PHPMailer ---> metamta.mail-adapter,根據(jù)你自己郵箱的配置,相應(yīng)的設(shè)置 phpmailer.smtp-host、phpmailer.smtp-port、phpmailer.smtp-protocol、phpmailer.smtp-user、phpmailer.smtp-password、phpmailer.smtp-encoding 。
0x54 配置代碼倉(cāng)庫(kù)訪(fǎng)問(wèn)方式:SSH/HTTP
-
SSH
(如果你不打算允許使用SSH的方式訪(fǎng)問(wèn)代碼倉(cāng)庫(kù)的話(huà),請(qǐng)忽略這部分)
1)配置用戶(hù)賬號(hào)
Phabricator需要三個(gè)用戶(hù)賬號(hào)(三種用戶(hù)身份):兩個(gè)用于基本運(yùn)行,一個(gè)用于配置SSH訪(fǎng)問(wèn)。這些賬號(hào)是指Phabricator所運(yùn)行服務(wù)器系統(tǒng)的賬號(hào),不是Phabricator用戶(hù)賬號(hào)。
三個(gè)賬號(hào)分別是:
www-user:Phabricator Web服務(wù)器運(yùn)行身份。
daemon-user :daemons (守護(hù)進(jìn)程)運(yùn)行身份。這個(gè)賬號(hào)是唯一直接與代碼倉(cāng)庫(kù)交互的賬號(hào),其它賬號(hào)需要切換到這個(gè)賬號(hào)身份(sudo)才能操作代碼倉(cāng)庫(kù)。
vcs-user:我們需要以這個(gè)賬號(hào)SSH連接Phabricator。
如果你的服務(wù)器系統(tǒng)中現(xiàn)在沒(méi)有這三個(gè)賬號(hào),需要?jiǎng)?chuàng)建:
www-user:大部分情況下,這個(gè)賬號(hào)已經(jīng)存在了,我們不需要理這個(gè)賬號(hào)。
daemon-user :一般情況下,我們直接使用 root 賬號(hào),因?yàn)闀?huì)需要很多權(quán)限(當(dāng)然這可能不安全)。
vcs-user:可以使用系統(tǒng)中現(xiàn)有的一個(gè)用戶(hù)賬號(hào),直接創(chuàng)建一個(gè)就叫 vcsuser。當(dāng)用戶(hù)克隆倉(cāng)庫(kù)的時(shí)候,需要使用類(lèi)似 vcsuser@pha.example.com 的URI。
2)配置Phabricator
首先,設(shè)置 phd.user 為 daemon-user(root)
./path_to_pha/bin/config set phd.user root
重啟 daemons 以確認(rèn)這個(gè)配置工作正常
./path_to_pha/bin/phd restart
然后,配置SSH用戶(hù)賬號(hào)vcs-user(vcsuser 或其它你想用的用戶(hù))
./path_to_pha/bin/config set diffusion.ssh-user vcsuser
3)配置 Sudo
www-user 和 vcs-user 需要能夠使用 sudo 切換到 daemon-user 用戶(hù)身份才能與倉(cāng)庫(kù)交互,所以我們需要配置更改系統(tǒng)的 sudo 配置。
直接編輯 /etc/sudoers 或者在 /etc/sudoers.d 下創(chuàng)建一個(gè)新文件,然后把這些內(nèi)容寫(xiě)到文件內(nèi)容中
www-user ALL=(root) SETENV: NOPASSWD: /usr/lib/git-core/git, /usr/bin/git, /var/lib/git, /usr/lib/git-core/git-http-backend, /usr/bin/ssh, /etc/ssh, /etc/default/ssh, /etc/init.d/ssh
vcs-user ALL=(root) SETENV: NOPASSWD: /bin/sh, /usr/bin/git-upload-pack, /usr/bin/git-receive-pack
當(dāng)然,別忘了把 www-user 和 vcs-user 替換為你實(shí)際對(duì)應(yīng)的用戶(hù)。
接下來(lái),看看你文件中是不是有這行
Defaults requiretty
如果有的話(huà),請(qǐng)用 # 注釋掉。
4)其它SSH配置
我們還需要查看這兩個(gè)文件 /etc/shadow 和 /etc/passwd 中 vcs-user 對(duì)應(yīng)的配置是否正確。
打開(kāi) /etc/shadow 文件,找到 vcs-user 對(duì)應(yīng)的那行,看一下第二個(gè)字段(密碼),是不是 !! ,如果是,請(qǐng)改為 空值(什么都不寫(xiě)) 或者 NP 。
打開(kāi) /etc/passwd 文件,找到 vcs-user 對(duì)應(yīng)的那行,如果有類(lèi)似于這樣的配置 /bin/false ,請(qǐng)修改為 /bin/sh,否則 sshd 無(wú)法執(zhí)行命令。
5)配置SSHD端口
注意:Phabricator運(yùn)行的服務(wù)器系統(tǒng)中 sshd 的版本 必須高于 6.2。
假設(shè)我們把Phabricator使用的sshd端口設(shè)置為 22,這樣做的好處是我們不需要在倉(cāng)庫(kù)的URI中加入端口號(hào),類(lèi)似ssh://vcs-user@pha.example.com/xxx/xxx/xxx.git。當(dāng)然,如果這樣做需要我們更改系統(tǒng)已存在的sshd配置改為其它端口。下面來(lái)看一下配置的三個(gè)步驟:
i)創(chuàng)建腳本 phabricator-ssh-hook.sh,并且把這個(gè)腳本放到類(lèi)似 /usr/libexec/phabricator-ssh-hook.sh 的目錄中(我直接放在 /etc/ssh/ 中,后面會(huì)要求變更這個(gè)腳本和它的父文件夾所有者,所以這個(gè)腳本和它的父文件夾所在的文件夾的所有者不正確的話(huà)可能會(huì)導(dǎo)致這個(gè)腳本執(zhí)行失敗),腳本內(nèi)容如下
#!/bin/sh
# NOTE: Replace this with the username that you expect users to connect with.
VCSUSER="vcs-user"
# NOTE: Replace this with the path to your Phabricator directory.
ROOT="/path_to_pha"
if [ "$1" != "$VCSUSER" ];
then
exit 1
fi
exec "$ROOT/bin/ssh-auth" $@
注意把 VCSUSER 替換為你實(shí)際的用戶(hù),把 ROOT 值替換為你Phabricator源碼路徑。
創(chuàng)建完腳本后,需要把腳本和它的父文件夾所有者改為 root,并且賦予腳本 755 權(quán)限:
sudo chown root /path/to/somewhere/
sudo chown root /path/to/somewhere/phabricator-ssh-hook.sh
sudo chmod 755 /path/to/somewhere/phabricator-ssh-hook.sh
如果你不這么做,sshd 會(huì)拒絕執(zhí)行 hook。
ii)為Phabricator創(chuàng)建 sshd_config
在 /etc/ssh 中創(chuàng)建文件名類(lèi)似 sshd_config.phabricator 的文件,文件內(nèi)容如下:
# NOTE: You must have OpenSSHD 6.2 or newer; support for AuthorizedKeysCommand
# was added in this version.
# NOTE: Edit these to the correct values for your setup.
AuthorizedKeysCommand /你的腳本路徑/phabricator-ssh-hook.sh
AuthorizedKeysCommandUser vcs-user
AllowUsers vcs-user
# You may need to tweak these options, but mostly they just turn off everything
# dangerous.
Port 你配置的端口號(hào)
Protocol 2
PermitRootLogin no
AllowAgentForwarding no
AllowTcpForwarding no
PrintMotd no
PrintLastLog no
PasswordAuthentication no
AuthorizedKeysFile none
PidFile /var/run/sshd-phabricator.pid
注意把 AuthorizedKeysCommand 值替換為你在上一步中腳本實(shí)際路徑,把 AuthorizedKeysCommandUser 和 AllowUsers 替換為你實(shí)際的用戶(hù),把 Port 替換為你想配置的端口號(hào)。如果你的 Port 值為 22,在你進(jìn)行下面的操作之前,請(qǐng)查看當(dāng)前系統(tǒng)中 22 端口是已否占用
sudo netstat -atlunp | grep ssh
如果已經(jīng)被占用,請(qǐng)修改使用 22 端口的 sshd 配置,一般它們會(huì)在 /etc/ssh 下,名稱(chēng)類(lèi)似 sshd_config,修改完成后,請(qǐng)重啟 ssh 服務(wù)
sudo /etc/init.d/ssh restart
在完成上面的步驟后,我們來(lái)啟動(dòng)Phabricator的 ssh 服務(wù)
sudo /path/to/sshd -f /你的Phabricator sshd配置路徑/sshd_config.phabricator
一般情況下,sshd 路徑為 /usr/sbin。
在啟動(dòng)后,我們需要驗(yàn)證以下配置是否有效:
首先,請(qǐng)把你的公鑰添加到Phabricator自己的賬號(hào)中(你可以自己注冊(cè)一個(gè)新的賬號(hào)),注冊(cè)完成后登錄,然后 點(diǎn)擊你的頭像 ---> 左側(cè)菜單面板 Manage ---> 右側(cè)菜單面板 Edit Settings ---> 左側(cè)菜單面板 SSH Public Keys ---> 右上角 SSH Key Actions ---> Upload Public Key
上傳公鑰后,執(zhí)行下面的命令
echo {} | ssh vcs-user@phabricator.yourcompany.com conduit conduit.ping
如果出現(xiàn)類(lèi)似下面的結(jié)果,說(shuō)明配置有效
{"result":"phabricator.yourcompany.com","error_code":null,"error_info":null}
如果沒(méi)有出現(xiàn)別的情況,請(qǐng)參考官方文檔 Troubleshooting SSH 部分,官方文檔地址如下
https://secure.phabricator.com/book/phabricator/article/diffusion_hosting/
接下來(lái),看一下如何配置 HTTP
-
HTTP
首先,請(qǐng)確認(rèn)Phabricator的配置項(xiàng) diffusion.allow-http-auth 設(shè)置為 true。可以在 左側(cè)菜單面板 All Setttings 中查找 diffusion.allow-http-auth ,點(diǎn)擊之后可設(shè)置,請(qǐng)?jiān)O(shè)置為 Allow HTTP Basic Auth。
然后,所有用戶(hù)需要使用 HTTP 訪(fǎng)問(wèn)倉(cāng)庫(kù)之前,需要設(shè)置自己的密碼:點(diǎn)擊你的頭像 ---> 左側(cè)菜單面板 Manage ---> 右側(cè)菜單面板 Edit Settings ---> 左側(cè)菜單面板 VCS Password
強(qiáng)烈建議不要把這個(gè)密碼設(shè)置為你的Phabricator登錄密碼,因?yàn)?vcs 密碼很容易泄露。
一般來(lái)說(shuō),不需要其它配置就可以使用 HTTP 了,如果有問(wèn)題,請(qǐng)參考官方文檔 Troubleshooting HTTP 部分
https://secure.phabricator.com/book/phabricator/article/diffusion_hosting/
配置完倉(cāng)庫(kù)訪(fǎng)問(wèn)方式后,我們來(lái)看一下如何使用 Phabricator 進(jìn)行 Code Review。
0x60 使用Phabricator進(jìn)行Code Review
在進(jìn)行 Code Review 實(shí)踐前,先說(shuō)一些理論方面的東西(開(kāi)頭和 0x61 ,不喜歡可繞過(guò))
Code Review,有時(shí)候就像打架一樣:我提交了變更,你說(shuō)不行,要修改;我又提交了一次,你說(shuō)還是不行,還要改。我不知道你究竟要怎樣,你也不知道我感覺(jué)受到了打擊有多不爽。所以,大家需要對(duì)Code Review這件事抱有開(kāi)放的態(tài)度:
-
為什么我的代碼需要其他人審查?
因?yàn)槲也皇巧瘢視?huì)制造Bug,我會(huì)當(dāng)局者迷。 -
為什么我要審查其他人的代碼?
因?yàn)槲乙獙?duì)我們的團(tuán)隊(duì)負(fù)責(zé),我要保證我們產(chǎn)品的質(zhì)量,我可能會(huì)看到他人代碼的Bug,在這些Bug顯示出它們的"威力"前,把它們弄死。
Code Review這件事,旨在創(chuàng)造一個(gè)共進(jìn)的團(tuán)隊(duì)氛圍(交流和技術(shù)等),在產(chǎn)品交付給用戶(hù)(包括我們的測(cè)試人員)前,保證產(chǎn)品的質(zhì)量。
在了解如何使用Phabricator進(jìn)行Code Review前,我們先了解一下Phabricator Code Review的流程,對(duì)其有一個(gè)整體上的了解。
0x61 Phabricator Code Review工作流
Phabricator提供兩種Code Review的方式:pre-push,post-push
pre-push 是指審查發(fā)生在變更發(fā)布前;post-push 是指審查發(fā)生在變更已經(jīng)被發(fā)布或者正在發(fā)布。
這里我們認(rèn)為 pre-push 的方式更適合,所以接下來(lái)說(shuō)一下 pre-push 的工作流:
Write, Review, Merge, Publish
從這篇文章,我了解到了這個(gè)流程
如果你之前用過(guò)其它的Code Review工具,可能會(huì)對(duì)這樣的流程感到不習(xí)慣。在其它工具中,變更(代碼,資源文件或其它)會(huì)經(jīng)歷這樣一個(gè)流程: Write, Publish, Review, Merge。首先,你做出一些變更(Write),然后把他們推送到遠(yuǎn)程倉(cāng)庫(kù)(Publish)等待審查者審查。一旦這些代碼被審查(Review)并通過(guò),變更會(huì)合并(Merge)到一個(gè)指定的功能分支。在這個(gè)流程中,被合并的變更恰好是被推送的變更(這句話(huà)有點(diǎn)模模糊糊,不痛不癢,接下來(lái)我們看一下Phabricator的流程,也許會(huì)清晰很多)。
接下來(lái),我們看一下Phabricator略有不同的工作流:Write, Review, Merge, Publish。像上面一樣,開(kāi)始的時(shí)候,你做出一些變更。但是,接下來(lái)的流程就不一樣了。
Phabricator認(rèn)為在開(kāi)發(fā)過(guò)程中審查(Review)是一個(gè)重要的步驟,對(duì)于那些沒(méi)有審查過(guò)的變更,是不可以發(fā)布的。
理論上來(lái)說(shuō),沒(méi)有審查過(guò)的變更不算數(shù):這些變更可能只是臨時(shí)的,易變的。可能方法上不對(duì),可能缺少來(lái)龍去脈,可能根本就是解決錯(cuò)誤的問(wèn)題,等等。審查的參考基礎(chǔ)是建立在開(kāi)發(fā)人員和審查人員擁有一個(gè)共同認(rèn)可的變更處理方式,并且這種處理方式是開(kāi)發(fā)過(guò)程所有參與人員(項(xiàng)目管理、產(chǎn)品、開(kāi)發(fā))都期望的,而不僅僅是僅僅做到最終的產(chǎn)品看起來(lái)沒(méi)問(wèn)題。直到變更經(jīng)過(guò)了這樣的審查,我們才能得到穩(wěn)固的版本。
這樣的工作流跟其它工具的審查流程沒(méi)有實(shí)質(zhì)上的技術(shù)區(qū)別,但是存在明顯的社交活動(dòng)上的不同:由于變更必須經(jīng)過(guò)審查才能被合并、發(fā)布,變更作者需要根據(jù)反饋對(duì)變更進(jìn)行調(diào)整。另外,審查者根據(jù)粗略的草圖(所有開(kāi)發(fā)參與人員共同認(rèn)可的變更方式)進(jìn)行反饋,而不是簡(jiǎn)單的批判一件已經(jīng)完成的變更工作。
Phabricator和其它工具的工作流都有著同樣的目的:未審查的代碼都只是臨時(shí)的變更,沒(méi)有長(zhǎng)久或者明顯的價(jià)值,直到通過(guò)審查。
Phabricator工作流的第二步是審查(Review),審查的對(duì)象是還沒(méi)有發(fā)布的變更。沒(méi)有發(fā)布的變更被發(fā)送到Phabricator等待被審查(通常我們使用 arc diff
命令發(fā)送審查請(qǐng)求),然后審查者做出反饋。變更作者根據(jù)反饋進(jìn)行修改,在修改過(guò)程中,作者不必?fù)?dān)心版本、解決方式這些事情。作者可以自由的復(fù)位、使用、移除或者舍棄老的變更。在從變更提交審核到審核者反饋,以及作者再次修改整個(gè)過(guò)程中,沒(méi)有那種審核者把作者推入一個(gè)必須接受或者只能做少量改變的默認(rèn)發(fā)布狀態(tài)。
一旦通過(guò)審核,變更會(huì)被合并(Merge)和發(fā)布(Publish)(通常,這兩個(gè)步驟由一個(gè)命令完成 arc land
)。
這里,Phabricator也與那些先 Publish 的工具不同:默認(rèn)情況下,Phabricator會(huì)舍棄到達(dá)最后變更前的所做的中間過(guò)程,把最后變更的整個(gè)過(guò)程壓縮成一次提交。總體來(lái)說(shuō),這意味著舍棄checkpoint commits, rebases, squash-merges, 并且把整個(gè)變更過(guò)程做為一次 fast-forward commit 提交到目標(biāo)分支。
Phabricator在一定程度上能做到這些,是因?yàn)椋菏裁炊紱](méi)有被發(fā)布,所以這種工作流可以以任何想要的方式發(fā)布變更。
有了這些,我們可以以我們想要的版本自由的rebase,fast-commit,這些是Phabricator默認(rèn)的行為。
0x62 進(jìn)行Code Review所用工具
做為一般用戶(hù),常用的工具有兩個(gè) Differential 和 Arcanist 。
- Differential-審查代碼的工作臺(tái)
我們?cè)谶@里查看變更審查情況,對(duì)變更進(jìn)行審查或評(píng)論等操作。
這是某次變更界面操作部分截圖
<p>做為 審查人,可進(jìn)行的操作有:
Comment:說(shuō)點(diǎn)什么。可以針對(duì)某行代碼進(jìn)行評(píng)論,直接點(diǎn)擊行號(hào)即可
Accept Revision:接受變更,這哥們代碼寫(xiě)得不錯(cuò),不需要改
Request Changes:不行,還要改
Resign as Reviewer:重新指定審查代碼的人
Commandeer Revision:字面意思是將這個(gè)Revision據(jù)為己有的意思,實(shí)際上這個(gè)時(shí)候Reviewer的身份已經(jīng)變?yōu)镺wner的身份了,不能再進(jìn)行Review了,但是Comment還是可以的
Add Reviewer:添加審查人
Add Subscribers:添加訂閱者,CC
做為 作者,可進(jìn)行的操作有:
Comment:說(shuō)點(diǎn)什么。可以針對(duì)某行代碼進(jìn)行評(píng)論,直接點(diǎn)擊行號(hào)即可
Abandon Revision:廢除版本。廢除后,這個(gè)版本就不需要再審核了
Plan Changes:計(jì)劃變更,我自己發(fā)現(xiàn)了一些問(wèn)題或者需求有變,正在改
Add Reviewer:添加其它審查人(除當(dāng)前審查人外)
Add Subscribers:添加訂閱者,CC
-
Arcanist - 命令交互
我們用這個(gè)工具提交變更和審查請(qǐng)求,對(duì)變更做出更改,或者在通過(guò)審查后發(fā)布到遠(yuǎn)程倉(cāng)庫(kù)分支中。
常用的命令有:
arc diff:發(fā)送變更詳情和審查請(qǐng)求
arc land:推送變更(Git and Mercurial),當(dāng)通過(guò)審查后使用這個(gè)命令
arc list:顯示變更處理的情況
arc cover:查找最有可能審查變更的人
arc patch:給版本打補(bǔ)丁
arc export:從Differential下載補(bǔ)丁
arc amend:更新Git commit
arc commit:提交變更(SVN)
arc branch:查看Git branches更加詳細(xì)的信息
在配置了 lint 和 unit test intergration后,可以用這些命令:
arc lint:靜態(tài)代碼檢查
arc unit:?jiǎn)卧獪y(cè)試
與其它工具交互:
arc upload:上傳文件
arc download:下載文件
arc paste:創(chuàng)建和查看剪貼
還有一些高級(jí)功能:
arc call-conduit:執(zhí)行 Conduit 方法
arc liberate:創(chuàng)建或更新 libphutil 庫(kù)
arc shell-complete:激活 tab 補(bǔ)全
0x63 配置進(jìn)行Code Review
一些基本的配置和安裝 ---> 寫(xiě)代碼 ---> 提交審查請(qǐng)求(arc diff) ---> 審查(Differential) ---> (審查通過(guò)后)合并提交(arc land)
一些基本的配置和安裝
包括:
配置代碼倉(cāng)庫(kù)(Diffusion)
把你本地的Git遠(yuǎn)程URL設(shè)置為Phabricator上代碼倉(cāng)庫(kù)地址
安裝Arcanist
配置Project信息配置代碼倉(cāng)庫(kù)(Diffusion)
在開(kāi)始進(jìn)行代碼審查后,我們的代碼是由Phabricator直接托管的,所以我們需要配置代碼倉(cāng)庫(kù)。
使用管理員賬號(hào)登錄Phabricator,點(diǎn)擊左側(cè)面板菜單 Diffusion ,然后點(diǎn)擊右上側(cè) Create Repository ,選擇你所使用的 Repository 類(lèi)型,填寫(xiě) Name 等信息,在創(chuàng)建完成后即可使用。如果沒(méi)有什么特殊的需求,不需要進(jìn)行特別的配置,這里列舉兩種你可能遇到的打算開(kāi)始使用 Phabricator 時(shí)的場(chǎng)景:
1、代碼之前由 GitHub 或其它托管,現(xiàn)在我需要把之前的代碼導(dǎo)入
點(diǎn)擊 Manage Repository ,點(diǎn)擊左側(cè) URIs,點(diǎn)擊 Add New URI,填寫(xiě)GitHub或其它托管系統(tǒng)對(duì)應(yīng)倉(cāng)庫(kù)的 URI , I/O Type 選擇 Observe,點(diǎn)擊 Create Repository URI 添加新的 URI 。
在添加完新的 URI 后,你還需要點(diǎn)擊 Set Credential 設(shè)置訪(fǎng)問(wèn)新的 URI 的認(rèn)證方式。
如果你打算此時(shí)就開(kāi)始使用 Phabricator ,請(qǐng)務(wù)必通知你的團(tuán)隊(duì),暫停一下,不要再向GitHub等提交代碼。如果你的 GitHub 等也設(shè)置了代碼審查,請(qǐng)督促相關(guān)人員完成代碼審查流程。
稍等片刻,待 Phabricator 同步完之前的代碼后,編輯你添加的 GitHub 或其它代碼托管系統(tǒng)的 URI ,務(wù)必修改 I/O Type:
1)如果你不再需要使用之前的托管系統(tǒng),選擇 No I/O
2)如果你想繼續(xù)把代碼備份到之前的代碼托管系統(tǒng),選擇 Mirror,這時(shí), Phabricator 代碼倉(cāng)庫(kù)的變更會(huì)覆蓋推送到之前的代碼托管系統(tǒng)
如果你不修改 I/O Type,向 Phabricator 代碼倉(cāng)庫(kù)提交代碼會(huì)失敗,因?yàn)槭侵蛔x的。
當(dāng)然,對(duì)于導(dǎo)入之前的代碼,還有別的方式,例如直接把本地的代碼再次向 Phabricator 代碼倉(cāng)庫(kù)再提交一次。
2、開(kāi)始一個(gè)新的項(xiàng)目,創(chuàng)建一個(gè)新的倉(cāng)庫(kù)
參考第1種場(chǎng)景,在 Phabricator 創(chuàng)建代碼倉(cāng)庫(kù)。如果你希望把代碼備份到其它的托管系統(tǒng),只需要添加對(duì)應(yīng)的 URI,并且把 I/O Type 選為 Mirror。
- 把你本地的Git遠(yuǎn)程URL設(shè)置為Phabricator上代碼倉(cāng)庫(kù)地址
git remote set-url 遠(yuǎn)程名稱(chēng) 新的url
- 安裝Arcanist
https://secure.phabricator.com/book/phabricator/article/arcanist_quick_start/
- 配置Project信息
在你項(xiàng)目代碼的根目錄下,創(chuàng)建 .arcconfig 文件,內(nèi)容如下:
{
"phabricator.uri" : "你Phabricator系統(tǒng)訪(fǎng)問(wèn)URL"
}
Windows系統(tǒng)下,創(chuàng)建類(lèi)似這種文件名的文件可能很麻煩,可以使用這條命令創(chuàng)建:
arc set-config phabricator.uri "你Phabricator系統(tǒng)訪(fǎng)問(wèn)URL"
Windows系統(tǒng)下,還需要配置 Editor ,詳情參考:
https://secure.phabricator.com/book/phabricator/article/arcanist_windows/
Arcanist 使用可參考:
https://secure.phabricator.com/book/phabricator/article/arcanist_quick_start/
https://secure.phabricator.com/book/phabricator/article/arcanist/
在進(jìn)行完基本的配置和安裝后,可以開(kāi)始 Code Review 了。
寫(xiě)代碼
當(dāng)然,不只是代碼可以被審查,圖標(biāo)等資源文件的變更也可以被審查。提交審查請(qǐng)求(arc diff)
一般情況下,我們直接使用arc diff
即可,默認(rèn)情況下,Arcanist 會(huì)把本地分支的 HEAD 與遠(yuǎn)程對(duì)應(yīng)分支的 HEAD 進(jìn)行對(duì)比,并生成差異對(duì)比發(fā)送到 Phabricator。當(dāng)你所做的修改沒(méi)有 commit 時(shí),會(huì)提示你進(jìn)行 commit。
在一些情況下,我們并不希望與本地分支的 HEAD 進(jìn)行比較,假設(shè)想要與上次的 commit 比較,上次 commit id 是 8ffc88dc05d31fffd28e3ff1129d1b8c321dffff,那么我們需要在arc diff
后把這個(gè) id 加上:arc diff 8ffc88dc05d31fffd28e3ff1129d1b8c321dffff
。
執(zhí)行這條命令時(shí)我們需要按照模板填寫(xiě)title(必填),summary(必填),Test Plan(必填,沒(méi)有可寫(xiě) N/A 之類(lèi)的標(biāo)識(shí)),Reviewers(必填,且必須為真實(shí)有效的用戶(hù)名),Subscribers(可選),填寫(xiě)完成后關(guān)閉編輯器,Arcanist會(huì)自動(dòng)提交審查請(qǐng)求。審查(Differential)
做為 審查人,需要在 Differential 工作臺(tái)完成代碼審查工作,上面已經(jīng)介紹了 Differential,這里就不再多說(shuō)了。(審查通過(guò)后)合并提交(arc land)
做為 作者,在代碼審查通過(guò)后,需要使用arc land
把變更發(fā)布到遠(yuǎn)程分支。
注意,在首次執(zhí)行這條命令前(不一定非要到這個(gè)步驟,可以是這個(gè)步驟前的任意時(shí)刻,例如開(kāi)始寫(xiě)代碼前),建議請(qǐng)使用git branch -u 遠(yuǎn)程名稱(chēng)/遠(yuǎn)程分支名稱(chēng)
把本地的分支與遠(yuǎn)程分支相關(guān)聯(lián),否則,在執(zhí)行完arc land
后,本地分支會(huì)被刪除。如果你不想這樣做,又需要保留現(xiàn)在分支的話(huà),請(qǐng)使用arc land --keep-branch
。
默認(rèn)情況下,Arcanist 會(huì)把變更推送到與本地分支相關(guān)聯(lián)的遠(yuǎn)程分支,你可以使用 * --remote * 和 * --onto * 參數(shù)推送到你想要的遠(yuǎn)程和遠(yuǎn)程分支。
關(guān)于arc land
的詳細(xì)說(shuō)明,可使用arc land --help
查看。
0x70 與GitHub集成
這里的“集成”其實(shí)說(shuō)的很心虛,因?yàn)樵谑褂?Phabricator 后,GitHub 已經(jīng)變?yōu)橐粋€(gè)文件存儲(chǔ)服務(wù)器了。常見(jiàn)的使用情況已經(jīng)在 ** 0x63 配置進(jìn)行Code Review ** 的 ** 配置代碼倉(cāng)庫(kù)(Diffusion)** 中寫(xiě)出,所以你懂的。
0x80 與Jenkins集成
在很久很久以前,我已經(jīng)搭建了 Jenkins 用于自動(dòng)構(gòu)建,所以這次把 Phabricator 與 Jenkins 做了集成。
在 Jenkins 中安裝完插件:* Phabricator Differential Plugin * 后,請(qǐng)參考這篇文章:
https://github.com/uber/phabricator-jenkins-plugin#phabricator-jenkins-plugin--
0x90 結(jié)束語(yǔ)
從配置完到開(kāi)始試用已經(jīng)有一個(gè)月左右,期間遇到了各種問(wèn)題。經(jīng)歷了這些問(wèn)題的洗禮,算是對(duì) Phabricator 使用入門(mén)了吧。
這篇文章時(shí)隔多日才完成,盡管我想把每個(gè)細(xì)節(jié)寫(xiě)的詳盡,但是記憶總是像被蟲(chóng)蛀過(guò)的木頭,難免有些疏漏。加之文筆水平有限,各位就湊合著看吧。
在安裝和使用過(guò)程中遇到的問(wèn)題,歡迎各位評(píng)論交流。
0xA0 Q/A
1、如何強(qiáng)制用戶(hù) Code Review?
再次強(qiáng)調(diào)一下前提:在開(kāi)始 Code Review 流程前,請(qǐng)先確認(rèn)團(tuán)隊(duì)成員的git remote url已經(jīng)切換為Phabricator上對(duì)應(yīng)倉(cāng)庫(kù)地址。
強(qiáng)制用戶(hù)Code Review,需要?jiǎng)?chuàng)建Herald Rule。在創(chuàng)建時(shí),New Rule for 選:Commit Hook: Commit Content.;Rule Type選:Global,或者根據(jù)自己需要選擇;Conditions中是組合條件,可以根據(jù)自己需要指定一些條件;Action 指定當(dāng)前情況符合你指定的條件組合時(shí)執(zhí)行的動(dòng)作。示例如圖:
示例中定義了以下規(guī)則:在向develop分支提交代碼時(shí),所提交的代碼必須是通過(guò) Code Review 流程審查通過(guò)的,否則會(huì)被拒絕;除非 Commit Message 中包含字符 @bypass-review 。
指定 Commit Message 中包含字符 @bypass-review 這種例外情況,主要考慮到在緊急修復(fù)一些問(wèn)題,沒(méi)時(shí)間等待審查時(shí)使用。
當(dāng)提交被拒絕時(shí),如圖: