2012年9月18日 星期二

push to gerrit


http://www.infoq.com/cn/articles/Gerrit-jenkins-hudson

Git、Gerrit與Jenkins/Hudson CI服務器

作者 Alex Blewitt 譯者 丁雪豐 發佈於 2011年9月6日
領域
過程 & 實踐,
語言 & 開發
主題
團隊協作 ,
Java ,
協作 ,
分佈式團隊 ,
團隊工作 ,
敏捷
本文講述了如何為基於團隊的代碼審查系統配置Git、Gerrit與Jenkins/Hudson,正如我在《Git, Gerrit and Jenkins for iOS development》《Gerrit Git Review with Jenkins CI Server》演講(以及第一次提出這種做法的《Someday...》)中所倡導的那樣。 文中的範例假定你所使用的操作系統是OS X或Linux,但是如果你願意,也可以在Windows上運行它們。

配置Git

很多系統(例如Linux)已經默認提供了Git,在Git主頁也可以找到安裝程序。對於Windows用戶,最好的選擇是MsysGit。請注意,如果你安裝了Apple Developer Tools (for Xcode 4),那麼其中已經自帶Git二進制包了。如果遇到了問題,help.github.com中可以找到很多非常出色的指南。
因為所有的Git提交都帶有作者和電子郵件地址,如果你還沒有設置過這些內容,請執行以下命令進行配置:
$ git config --global user.name "Alex Blewitt"
$ git config --global user.email Alex.Blewitt@example.com
最好有一個Git代碼庫。Gerrit在初始化階段會自動掃瞄Git代碼庫,這樣做比在後期配置代碼庫容易一些,因此最好在初始化Gerrit前準備好Git代碼庫。
如果還沒有Git代碼庫,可以創建一個:
git init --bare /path/to/gits/example.git

Gerrit

可以從http://code.google.com/p/gerrit/下載到Gerrit,那是一個WAR文件。Gerrit有很好的文檔(目前的最新文檔是2.2.1,但也可用於2.1.7)和安裝指南
Gerrit在運行時需要用到數據庫(用於存儲代碼審查的信息)。目前支持的數據庫包括H2、PostgreSQL和MySQL。在沒有進行額外配置的情況下,它默認使用H2。
請注意,Gerrit 2.2.x正把項目配置、權限和其他元數據移到Git存儲中,這樣就可以通過Git進行訪問和版本控制。在2.2.x中,這個轉變會慢慢擴展到其他類型的元數據上,包含代碼評審內容。詳見2.2.0版本的發布說明
要初始化Gerrit,運行java -jar gerrit.war init -d /path/to/location會在指定路徑上安裝Gerrit運行時。
如果是在交互終端中運行的,安裝程序會提幾個問題,例如:
  • Git代碼庫的位置 [git]
  • 導入現有代碼庫 [Y/n]
  • 數據庫服務器類型 [H2/?]
  • 身份驗證方法 [OPENID/?]
  • SMTP服務器主機名 [localhost]
  • SMTP服務器端口 [(default)]
  • SMTP加密 [NONE/?]
  • SMTP用戶名
  • 以何種身份運行 [you]
  • Java運行時 [/path/to/jvm]
  • 將gerrit.war複製到/path/to/location/bin/gerrit.war [Y/n]
  • 監聽地址 [*]
  • 監聽端口 [29418]
  • 下載並安裝Bouncy Castle [Y/n]
  • 位於HTTP反向代理之後 [y/N]
  • 使用SSL [y/N]
  • 監聽地址 [*]
  • 監聽端口 [8080]
其中大部分可以保留默認值,但是有幾個需要重點關注。
  • Git代碼庫的位置要指向正確的位置。默認值是位於安裝目錄中的'git'目錄,也可以是其他不同位置(例如/var/gits等等)。應該先配置好這個路徑,因為在Gerrit啟動時它會先掃瞄該目錄來添加新項目。
  • 監聽地址對有多個地址(例如IPv4和IPv6)的主機很有用,它可以限定使用哪個地址。*表示本地主機上的任意地址。
  • 監聽端口是一個端口號。29418是默認的Gerrit SSH端口,而8080是默認的Gerrit Web端口。但是如果8080已經被別的應用程序佔用了,那麼你可能會想修改第二個端口。
  • 身份驗證方法確定了如何登錄Gerrit。如果你想掛入某個現有的身份驗證提供方(例如Google Accounts),那麼可以使用OpenID。但對測試而言(還有上面提到的範例),可以使用 development_become_any_account。鍵入?會顯示一個可用方法的列表。
Gerrit啟動後,會打開一個瀏覽器,顯示Gerrit主頁。登錄的第一個用戶將自動成為管理員;所有後續登錄的用戶都是無權限用戶。如果你選擇 了development_become_any_account,在頁面頂端會有一個Become鏈接,通過它可以進入註冊/登錄頁面。

註冊用戶

為了使用Gerrit,你需要一個賬號,生成一個SSH密鑰對。在命令行中運行 ssh-keygen -t rsa -b 2048可以生成密鑰對,將其放到你的.ssh目錄中。如果你需要更多信息,可以訪問這篇博文,這是我六年前寫的SSH密鑰相關文章。此外,GitHub 幫助頁面中也有更多相關信息。
默認文件名為id_rsa(這是私鑰)和id_rsa.pub(這是公鑰)。你只能給別人公鑰,千萬別給別人私鑰。
有了密鑰,你就可以在Gerrit中註冊新賬戶了。點擊頂部右端的「Become」鏈接,然後再點擊「New account」按鈕,輸入Git知道的名稱和電子郵件(即上面用git config配置的),這些內容要完全匹配(包括大小寫)。保存變更,然後選擇一個唯一的用戶名(填入了名稱後點擊'select username',例如demo)。
頭痛的電子郵件 就算是development_become_any_account模式,Gerrit也會給你發送電子郵件以驗證郵件地址。不通過驗證的話就無法使用該電子郵件地址,你也無法提交代碼。
我們可以很快處理掉這個問題,因此如果Gerrit目前不讓你註冊你的郵箱地址,請不用擔心。
在'add SSH public key'文本框中,添加.pub文件中的公鑰。如果你使用的是OS X,pbcopy < ~/.ssh/id_rsa.pub就可輕鬆搞定。記住要點擊「Add」保存公鑰。
點擊Continue後應該就能登錄到Gerrit的主窗口了。到目前為止一切還不錯,現在可以測試SSH的連通性了。
鍵入ssh -p 29418 demo@localhost會嘗試連接Gerrit服務器,會出現以下三者之一:
  1. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
    
    這並沒有看上去那麼糟。它只是說你的~/.ssh/known_hosts文件中有舊的密鑰。最懶的一種修複方法是刪除這個文件(這是GitHub推薦的做法)。更好的方法是找到提示出錯的那一行,把它刪了:
    Offending key in /Users/demo/.ssh/known_hosts:123
    
    你可以用任何文本編輯器來刪除known_hosts文件中的第123行。在標準UNIX配置下,可以用以下命令自動刪除:
    sed -i '' '123d' ~/.ssh/known_hosts
  2. The authenticity of host '[localhost]:29418 ([::1]:29418)' can't be established.
    RSA key fingerprint is e8:e2:fe:19:6f:e2:db:c1:05:b5:bf:a6:ad:4b:04:33.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '[localhost]:29418' (RSA) to the list of known hosts.
    Permission denied (publickey).
    
    如果看到這個消息,說明Gerrit沒有識別出你提交的任何密鑰。ssh默認會發送id_rsa,要確認它的確發送了該值,可以查看.ssh/config,文件頭上有一行IdentityFile ~/.ssh/id_rsa。可以運行ssh -v查看發送的內容:
    debug1: Next authentication method: publickey
    debug1: Trying private key: /Users/demo/.ssh/id_dsa
    debug1: Offering public key: /Users/demo/.ssh/id_rsa
    
    假設已經發送了正確的密鑰,那麼在settings - ssh public keys菜單項中檢查該密鑰是否關聯了Gerrit中的用戶。如果沒有的話點擊'Add Key'並和之前一樣粘貼公鑰。
    如果Gerrit還是說你未經身份驗證,檢查用戶名和配置頁面裡的用戶名是否一致。如果用戶名不同,試試ssh -p 29418 username@localhost。
    最後,要驗證具體的密鑰,可以運行ssh -i ~/.ssh/id_rsa顯式地選擇要使用的密鑰,而不是讓它自動選擇密鑰。如果這樣可以工作,但不帶-i參數卻不行的話,那麼問題出在你的~ /.ssh/config文件裡──你需要保證選擇了合適的IdentityFile。
  3.   ****    Welcome to Gerrit Code Review    ****
    
      Hi demo, you have successfully connected over SSH.
    
      Unfortunately, interactive shells are disabled.
      To clone a hosted Git repository, use:
    
      git clone ssh://demo@localhost:29418/REPOSITORY_NAME.git
    
    Connection to localhost closed.
    
    如果看到這個提示,說明Gerrit已經正常工作了。

修正電子郵件地址

如果之前你無法在Gerrit中註冊電子郵件地址,那麼可以手工進行註冊。我們可以停止Gerrit,運行GSQL工具更新特定數據字段。
$ bin/gerrit.sh stop
$ java -jar bin/gerrit.war gsql
Welcome to Gerrit Code Review 2.1.6.1
(H2 1.2.134 (2010-04-23))

Type '\h' for help.  Type '\r' to clear the buffer.

gerrit> select * from ACCOUNT_EXTERNAL_IDS;
 ACCOUNT_ID | EMAIL_ADDRESS          | PASSWORD | EXTERNAL_ID
 -----------+------------------------+----------+------------------------------------------
 1000000    | NULL                   | NULL     | uuid:ac1b8a08-2dd1-4aa1-8449-8b2994dffaed
 1000000    | NULL                   | NULL     | username:demo
(2 rows; 23 ms)
gerrit> update ACCOUNT_EXTERNAL_IDS set EMAIL_ADDRESS='alex.blewitt@example.com' where ACCOUNT_ID=1000000;
UPDATE 2; 5 ms
gerrit> select * from ACCOUNT_EXTERNAL_IDS;
 ACCOUNT_ID | EMAIL_ADDRESS          | PASSWORD | EXTERNAL_ID
 -----------+------------------------+----------+------------------------------------------
 1000000    | alex.blewitt@example.com | NULL     | uuid:ac1b8a08-2dd1-4aa1-8449-8b2994dffaed
 1000000    | alex.blewitt@example.com | NULL     | username:demo
(2 rows; 23 ms)
gerrit> \q
Bye
$ bin/gerrit.sh start

創建項目,克隆並推送代碼

開始前,我們需要先在Gerrit中創建一個項目。如果Gerrit沒有在你的範例目錄中檢測到項目,在它運行時,我們可以創建一個項目。
$ ssh -p 29418 demo@localhost gerrit create-project --name example.git
上述命令會創建一個名為example的項目,在之前指定的Git目錄裡初始化一個空的代碼庫。如果已經有一個代碼庫了,Gerrit不允許創建同名代碼庫——但你可以先對它進行臨時重命名,隨後再把名字改回來。
隨後,可以創建一個克隆:
$ git clone ssh://demo@localhost:29418/example.git
Cloning into example...
warning: You appear to have cloned an empty repository.
我們可以向代碼庫進行提交和推送,就和其他Git系統一樣:
$ cd example
$ echo hello > world
$ git add world
$ git commit -m "The World"
[master (root-commit) 06bf85e] The World
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 world
$ git push
No refs in common and none specified; doing nothing.
Perhaps you should specify a branch such as 'master'.
$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 217 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://me@localhost:29418/example.git
 ! [remote rejected] master -> master (prohibited by Gerrit)
error: failed to push some refs to 'ssh://demo@localhost:29418/example.git'
這是什麼情況?Gerrit不希望我們直接覆寫Git代碼庫中的任何分支,而是將變更推送到另一個refspec中,這讓Gerrit有機會在代碼審查中修改代碼。最簡單的方法是為推送配置一個默認的refspec:
$ git config remote.origin.push refs/heads/*:refs/for/*
$ git push origin
Counting objects: 3, done.
Writing objects: 100% (3/3), 217 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://demo@localhost:29418/example.git
 * [new branch]      master -> refs/for/master

沒有留言:

張貼留言