How to Make a AutoBuild System with Git Server

personal blog: http://finaldie.com/wordpress/

emai: [email protected]


  今天給大家分享一下最近自己的成果, 折騰了一個autobuild系統, 如果您和我有同樣的需求, 不妨跟隨我一起搭建一個這樣的系統, easy and simple, have fun :)

Why:

  事情是這樣開始的, 我自己的項目放置在github上, 這是一個linux項目, 然而我所用來開發的機器是mac, 它不能用來編譯所有的模塊, 每次我都需要push提交之後, 再去server上pull下來, 然後編譯看看結果, 這個過程我持續了一陣子之後再也忍受不了了, 我想要一個這樣的系統:

1. 當我push提交之後, 他能實時的反饋給我編譯的結果, 就像本地編譯一樣,

2. 運行test unit, 並將結果實時反饋給我

3. 隨後發送一封郵件到我的郵箱內, 包含編譯結果以及test unit運行結果

4. 而這次的提交僅僅是爲了測試集成的效果, 而不影響真正的版本庫主幹


How:

  目的明確後, 我想到了git hook, 這裏面的hook有一個可以滿足我的需求-- post-receive, 這是一個server端的hook(shell腳本), 每當接收到applypatch後都會調用一次並將輸出結果反饋給client, 接下來我們將開始利用這個hook搭建這套系統.

  首先我們來看一下工作流程(如下圖):

  

圖1 WorkFlow


  簡單的描述一下這個流程, 相對還算清晰簡潔, 找一臺可以用作build的機器, 建立一個git bare repo 用於接受提交, a clone repo for update & build, 當你向這個repo push後, server收到commit會自動調用post-receive hook, 接下來你需要讓這個hook腳本做4件事:

  1. 定位到clone repo 目錄中進行pull, 更新最後一次提交

  2. 在build目錄中執行make

  3. 執行TestUnit

  4. 將剛纔輸出的信息發送到指定郵箱


  這個腳本完成上述4個步驟, 也就完成了我們制定的目標. 現在所有重點都在這個hook腳本內, 不過你是否有一個疑惑, 這些執行中的信息如何才能反饋給提交的client? 這個也是我最先想問的, 查了git hook的資料後, 發現post-receive執行時, 標準輸出(stdout)和標準錯誤輸出(stderr)都會被git-send-back給當前client, 所以這個傳輸問題我們可以不用擔心,  我們只需要關心哪些信息我們需要收集, 哪些需要丟棄即可.


ToDo:

  目標清楚了, 原理也清楚了, 接下來我會展示如何搭建一個git server ,以及如何編寫這個git hook(post-receive),  到最後測試結果演示.

  1. Git server:

    搭建server很多文章中都有描述, 我稍微提煉一下, 做一個最精簡的. 首先我們找一臺機器(要有root or sudo權限)

   1). mkdir -p git_repo/autobuild   ( git_repo爲git server的根目錄, autobuild爲旗下的其中一個repo )

   2). cd git_repo && git --bare init

   3). sudo git daemon --verbose --export-all --base-path=gir_repo --enable=upload-pack --enable=upload-archive --enable=receive-pack    (這個可以做成一個shell 也可以把git daemon註冊成service, 這個就不再這裏過多討論了 各有喜好)

   完成上述3步後, 一個簡單的git server就搭好了, 現在我們需要將其clone出來到一個目錄中用於接下來做autobuild環境. (今後每次receive commit後我們都會到這個目錄做一次git pull更新最後一次提交, 並進行後續操作)

  比如 我們將其clone到一個名爲"/test_env"的目錄下: 

  git clone git://127.0.0.1/autobuild test_env


  好了到此, 搭建git server並準備autobuild環境目錄已經完成, 接下來我們開始編寫post-receive hook了.

  2. Post-receive Hook:

    剛剛也提到了, 這個腳本就是我們今天的主角, 那麼我們先回到git_repo/autobuild目錄來, 在這裏面, 我們可以看到hooks目錄, 進去之後我們可以找到post-receive.sample 這個模板, 將其rename爲post-receive, 並添加我們需要的工作流程:

    一個簡潔的例子, 內容如下:

mailfile='autobuild.txt'
email='[email protected]'

unset GIT_DIR 

# 1. git pull
cd /git_repo/autobuild
git pull > $mailfile

# 2. build
make clean
make --no-print-directory 2>> $mailfile

# 3. run test unit
make run_test --no-print-directory >> $mailfile

# 4. output to stdout for echo back
cat $mailfile

# 5. send a email to yourself
mail -s "Autobuild `date`" $email < $mailfile

  上面的例子僅僅完成了我們工作流程中的目標, 並沒有進行任何排版工作, 爲了使郵件的格式更加清晰, 你可以在其中放置更多的echo, 比如打上一些橫線作爲分割, 寫上一些提示語句, 這個就看大家自己的喜好了, 我就不在這裏贅贅的描述了 :), 接下來, 你需要將這個repo加入到你本地的git remote列表中(使用remote add命令添加), 每當你想要autobuild的時候, 就將當前branch push到這個remote repo中, 你會在push執行時得到上述我們提到的所有反饋(build info, run test unit, receive a email for backup). That's All.

   最後, 附上一個我的郵件信息格式, 以供參考:

2011年 11月 27日 星期日 23:04:46 EST
hi, This is a Autobuild message, please don't reply!
------------------------Update Info-------------------------------
Merge made by recursive.
 ftu/Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

------------------------Build Result------------------------------
No errors

------------------------Test Result-----------------------------------
( test -d test && cd test && make run_test )
(cd ../final_libraries/bin && ./test )
FINAL TEST UNIT START...

 <<<<<<< CASE NAME:test_list DESCRIBE:for test flist >>>>>>>
[ALL ASSERT PASSED -- 11/11]

 <<<<<<< CASE NAME:test_hash DESCRIBE:for test fhash set and get >>>>>>>
0--2717/2775
1--3238/4163
2--2769/2775
3--3272/4163
4--2742/2775
5--3284/4163
6--2751/2775
7--3260/4163
8--2741/2775
9--3226/4163
total count = 30000 max_size = 34690(cost 589730 byte) use ratio=1.00 avg len=3000
hash iter totoal=30000
hashforeach totoal=30000
[ALL ASSERT PASSED -- 30003/30003]

 <<<<<<< CASE NAME:test_hash_del DESCRIBE:for test hash_del method >>>>>>>
hash del complete
[ALL ASSERT PASSED -- 20000/20000]

 <<<<<<< CASE NAME:test_mem DESCRIBE:for test mempool alloc and free >>>>>>>
main tid=47601252718336
tid=47601254823680
tid=47601256924928
mempool init complete tid=47601254823680
tid=47601254823680 size=4 diff_time:155540usec | 155ms
tid=47601256924928 size=4 diff_time:183863usec | 183ms
tid=47601254823680 size=12 diff_time:153841usec | 153ms
tid=47601256924928 size=12 diff_time:146459usec | 146ms
tid=47601256924928 size=20 diff_time:146551usec | 146ms
tid=47601254823680 size=20 diff_time:170322usec | 170ms
tid=47601256924928 size=30 diff_time:144495usec | 144ms
tid=47601254823680 size=30 diff_time:152498usec | 152ms
tid=47601256924928 size=36 diff_time:148525usec | 148ms
tid=47601254823680 size=36 diff_time:152242usec | 152ms
tid=47601256924928 size=60 diff_time:136363usec | 136ms
tid=47601254823680 size=60 diff_time:136486usec | 136ms
tid=47601256924928 size=100 diff_time:139143usec | 139ms
tid=47601254823680 size=100 diff_time:148458usec | 148ms
tid=47601256924928 size=180 diff_time:155570usec | 155ms
tid=47601254823680 size=180 diff_time:137590usec | 137ms
tid=47601254823680 size=300 diff_time:147943usec | 147ms
tid=47601256924928 size=300 diff_time:154894usec | 154ms
tid=47601254823680 size=600 diff_time:147344usec | 147ms
tid=47601256924928 size=600 diff_time:155993usec | 155ms
tid=47601254823680 size=1000 diff_time:149958usec | 149ms
tid=47601256924928 size=1000 diff_time:146590usec | 146ms
tid=47601254823680 size=1200 diff_time:140344usec | 140ms
tid=47601256924928 size=1200 diff_time:157028usec | 157ms
tid=47601254823680 size=3000 diff_time:154509usec | 154ms
tid=47601256924928 size=3000 diff_time:159357usec | 159ms
tid=47601254823680 size=5000 diff_time:148422usec | 148ms
tid=47601256924928 size=5000 diff_time:147129usec | 147ms
tid=47601254823680 size=8202 diff_time:151623usec | 151ms
tid=47601256924928 size=8202 diff_time:153929usec | 153ms
tid=47601254823680 size=16394 diff_time:146452usec | 146ms
tid=47601256924928 size=16394 diff_time:141301usec | 141ms
tid=47601254823680 size=51200 diff_time:257559usec | 257ms
tid=47601254823680 total diff_time:2651372usec | 2651ms avg=155ms
tid=47601256924928 size=51200 diff_time:243754usec | 243ms
tid=47601256924928 total diff_time:2661121usec | 2661ms avg=156ms
[ALL ASSERT PASSED -- 52094510/52094510]

 <<<<<<< CASE NAME:test_realloc DESCRIBE:for test mempool realloc >>>>>>>
[ALL ASSERT PASSED -- 8/8]

 <<<<<<< CASE NAME:test_log DESCRIBE:for test log system >>>>>>>
log work thread start
read log info:[2011-11-27 23:04:55][debug]:log test final

find ptr=0x7fff5036ce2d
[ALL ASSERT PASSED -- 3/3]

 <<<<<<< CASE NAME:test_mbuf DESCRIBE:for test mbuf of mbuf_seek & rewind & realloc >>>>>>>
[ALL ASSERT PASSED -- 31/31]

 <<<<<<< CASE NAME:test_mbuf1 DESCRIBE:for test mbuf of mbuf_push & mbuf_pop >>>>>>>
[ALL ASSERT PASSED -- 90/90]

 <<<<<<< CASE NAME:test_timer DESCRIBE:for test ftimerfd >>>>>>>
[ALL ASSERT PASSED -- 4/4]

 <<<<<<< CASE NAME:test_fev DESCRIBE:for test fev for create register add del methods >>>>>>>
[ALL ASSERT PASSED -- 18/18]

 <<<<<<< CASE NAME:test_fev_listener DESCRIBE:for test fev listener >>>>>>>
test listener thread startup
wait for poll
net_conn:connect sucess fd = 6
[ALL ASSERT PASSED -- 5/5]

 <<<<<<< CASE NAME:test_fev_buff DESCRIBE:for test fev buff >>>>>>>
wait for poll
net_conn:connect sucess fd = 6
read size=12, read_str=hello final
main recv str=hi final
evbuff error
error happened haha
[ALL ASSERT PASSED -- 22/22]

 <<<<<<< CASE NAME:test_fev_conn DESCRIBE:for test fev asynchronous connect >>>>>>>
main tid=47601252718336
wait for poll
accept sucessful
tid=47601256924928
[ALL ASSERT PASSED -- 2/2]

--------------------------------------
TOTAL CASE 13, PASS 13, FAILED 0

Best Regards! Final Autobuild Team


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章