2008-10-22 116 views
114

持續集成這是一個稍微..徒勞的問題,但BuildBot的輸出功率沒有特別好看..「漂亮」爲Python

例如,相對於..

..和其他人,BuildBot看起來相當陳舊..

我目前哈德森打,但它是非常Java爲中心的(雖然this guide,我發現它更容易安裝比BuildBot,併產生更多的信息)

基本上:是否有任何持續集成系統針對python,產生大量的閃亮的圖形和喜歡?


更新:這段時間以來的詹金斯項目已經取代哈德森包的社區版。最初的作者也轉到了這個項目。 Jenkins現在是Ubuntu/Debian,RedHat/Fedora/CentOS等標準軟件包。以下更新仍然基本正確。與Jenkins做到這一點的起點是不同的。

更新:在嘗試了幾個選擇後,我想我會堅持哈德森。 Integrity很好,很簡單,但相當有限。我認爲Buildbot更適合擁有大量的構建奴隸,而不是像我一直在使用它的單個機器上運行的所有東西。

設置哈德森了一個Python項目是相當簡單:

  • 下載哈德森從http://hudson-ci.org/
  • 運行它java -jar hudson.war
  • 公開賽的http://localhost:8080
  • 轉到默認地址Web界面管理哈德森,插件,點擊「更新」或類似
  • 安裝Git插件(我必須設置在哈得遜全球首0路)
  • 創建一個新的項目,進入倉庫,SCM輪詢間隔等
  • 通過easy_install安裝nosetests如果它尚未
  • 在一個構建步驟,添加nosetests --with-xunit --verbose
  • 檢查「發佈JUnit測試結果報告書」,並設置「測試報告個XML」到**/nosetests.xml
這是所有的需要

。您可以設置電子郵件通知,並且the plugins值得一看。有幾個我目前正在使用Python項目:(!和圖吧)

  • SLOCCount plugin數行代碼 - 你需要安裝sloccount分別
  • Violations解析pylint的輸出(你可以設置警告閾值,繪製每個版本的違規數量)
  • Cobertura可以解析coverage.py輸出。而運行測試,使用nosetests --with-coverage Nosetest可以收集覆蓋率(此輸出寫入**/coverage.xml
+0

偉大的問題,我正在尋找類似的東西就在眼下。如果你走一條路線,你能和我們其他人分享你的經驗嗎? – 2008-10-22 15:02:34

+3

不知道這是否是可用的,當你這樣寫:使用哈德森查克諾里斯插件進一步加強對你的東西的控制! – 2009-12-16 14:59:51

+8

** 2011/2012年更新**:那些考慮Hudson的應該使用[Jenkins](http://jenkins-ci.org/),Hudson項目的開源延續(Hudson現在[由Oracle控制] (http://stackoverflow.com/questions/4973981/how-to-choose-between-hudson-and-jenkins)) – mindthief 2012-07-09 20:27:02

回答

40

您可能想查看Nosethe Xunit output plugin。你可以把它用這個命令來運行你的單元測試,並覆蓋檢查:

nosetests --with-xunit --enable-cover 

,如果你想要去的詹金斯路由將是有幫助的,或者如果你想使用具有支持其他CI服務器JUnit測試報告。

同樣可以使用violations plugin for Jenkins

+36

啊開源應用程序名稱的樂趣.. – dbr 2009-03-21 09:13:51

10

不知道它是否會做:Bitten是誰寫的Trac系統,並與Trac系統集成的傢伙做。 Apache Gump是Apache使用的CI工具。它是用Python編寫的。

9

作爲我們的CI服務器,我們以TeamCity取得了巨大的成功,並且使用鼻子作爲我們的測試跑步者。 Teamcity plugin for nosetests爲您提供計數合格/不合格,可讀的失敗測試顯示(可以通過電子郵件發送)。在堆棧運行時,您甚至可以看到測試失敗的詳細信息。

如果當然支持像在多臺機器上運行一樣的東西,並且比buildbot更容易安裝和維護。

0

我們已經使用了相當多的咬。它非常漂亮,並且與Trac完美集成,但如果您有任何非標準工作流程,定製時會很痛苦。也就是說,沒有像更流行的工具那樣多的插件。目前我們正在評估Hudson作爲替代品。

2

信號是另一種選擇。你可以更多地瞭解它並觀看視頻here

6

我想這個線程是很老,但這裏是我對其採取哈德森:

我決定去與點子,併成立了回購(痛苦得到工作,但好看eggbasket),其中哈德森自動上傳到一個成功的測試。這裏是我粗略和準備好的腳本,用於使用hudson config執行腳本,如:/var/lib/hudson/venv/main/bin/hudson_script.py -w $ WORKSPACE -p my.package -v $ BUILD_NUMBER,只需放入**/coverage.xml,pylint.txt和nosetests。XML的配置位:

#!/var/lib/hudson/venv/main/bin/python 
import os 
import re 
import subprocess 
import logging 
import optparse 

logging.basicConfig(level=logging.INFO, 
        format='%(asctime)s %(levelname)s %(message)s') 

#venvDir = "/var/lib/hudson/venv/main/bin/" 

UPLOAD_REPO = "http://ldndev01:3442" 

def call_command(command, cwd, ignore_error_code=False): 
    try: 
     logging.info("Running: %s" % command) 
     status = subprocess.call(command, cwd=cwd, shell=True) 
     if not ignore_error_code and status != 0: 
      raise Exception("Last command failed") 

     return status 

    except: 
     logging.exception("Could not run command %s" % command) 
     raise 

def main(): 
    usage = "usage: %prog [options]" 
    parser = optparse.OptionParser(usage) 
    parser.add_option("-w", "--workspace", dest="workspace", 
         help="workspace folder for the job") 
    parser.add_option("-p", "--package", dest="package", 
         help="the package name i.e., back_office.reconciler") 
    parser.add_option("-v", "--build_number", dest="build_number", 
         help="the build number, which will get put at the end of the package version") 
    options, args = parser.parse_args() 

    if not options.workspace or not options.package: 
     raise Exception("Need both args, do --help for info") 

    venvDir = options.package + "_venv/" 

    #find out if venv is there 
    if not os.path.exists(venvDir): 
     #make it 
     call_command("virtualenv %s --no-site-packages" % venvDir, 
        options.workspace) 

    #install the venv/make sure its there plus install the local package 
    call_command("%sbin/pip install -e ./ --extra-index %s" % (venvDir, UPLOAD_REPO), 
       options.workspace) 

    #make sure pylint, nose and coverage are installed 
    call_command("%sbin/pip install nose pylint coverage epydoc" % venvDir, 
       options.workspace) 

    #make sure we have an __init__.py 
    #this shouldn't be needed if the packages are set up correctly 
    #modules = options.package.split(".") 
    #if len(modules) > 1: 
    # call_command("touch '%s/__init__.py'" % modules[0], 
    #     options.workspace) 
    #do the nosetests 
    test_status = call_command("%sbin/nosetests %s --with-xunit --with-coverage --cover-package %s --cover-erase" % (venvDir, 
                        options.package.replace(".", "/"), 
                        options.package), 
       options.workspace, True) 
    #produce coverage report -i for ignore weird missing file errors 
    call_command("%sbin/coverage xml -i" % venvDir, 
       options.workspace) 
    #move it so that the code coverage plugin can find it 
    call_command("mv coverage.xml %s" % (options.package.replace(".", "/")), 
       options.workspace) 
    #run pylint 
    call_command("%sbin/pylint --rcfile ~/pylint.rc -f parseable %s > pylint.txt" % (venvDir, 
                        options.package), 
       options.workspace, True) 

    #remove old dists so we only have the newest at the end 
    call_command("rm -rfv %s" % (options.workspace + "/dist"), 
       options.workspace) 

    #if the build passes upload the result to the egg_basket 
    if test_status == 0: 
     logging.info("Success - uploading egg") 
     upload_bit = "upload -r %s/upload" % UPLOAD_REPO 
    else: 
     logging.info("Failure - not uploading egg") 
     upload_bit = "" 

    #create egg 
    call_command("%sbin/python setup.py egg_info --tag-build=.0.%s --tag-svn-revision --tag-date sdist %s" % (venvDir, 
                               options.build_number, 
                               upload_bit), 
       options.workspace) 

    call_command("%sbin/epydoc --html --graph all %s" % (venvDir, options.package), 
       options.workspace) 

    logging.info("Complete") 

if __name__ == "__main__": 
    main() 

當涉及到部署的東西,你可以這樣做:用

pip -E /location/of/my/venv/ install my_package==X.Y.Z --extra-index http://my_repo 

然後人們可以開發的東西:

pip -E /location/of/my/venv/ install -e ./ --extra-index http://my_repo 

這玩意假設你有一個每個軟件包有一個setup.py和依賴關係的repo結構,然後你可以檢查出trunk並運行它。

我希望這可以幫助別人。

------更新---------

我添加epydoc的可以完美融入真的很好哈德森。只需添加的Javadoc到你的配置與HTML文件夾

注意PIP不支持-E標誌正確,這些天,所以你必須創建VENV分別

6

Atlassian的Bamboo也絕對值得一試。整個Atlassian套件(JIRA,Confluence,FishEye等)非常甜美。

3

如果你正在考慮託管CI解決方案,做開源的託管工具,你應該看看Travis CI以及 - 它與GitHub的非常好的整合。雖然它起初是一個Ruby工具,但它們前段時間有added Python support

2

我會考慮CircleCi - 它有很好的Python支持和非常漂亮的輸出。

0

檢查rultor.com。正如this article所解釋的,它爲每個構建使用Docker。多虧了這一點,你可以在你的Docker鏡像中配置任何你喜歡的東西,包括Python。

1

continuum的binstar現在可以從github中觸發構建,並可以編譯爲linux,osx和windows(32/64)。整潔的事情是,它真的可以讓你緊密結合分配和持續集成。這是跨越了t和點綴我的整合。網站,工作流程和工具都非常精緻,AFAIK conda是分發複雜python模塊的最強大和最蟒蛇的方式,您需要將分發給C/C++/Fotran庫。

0

幾乎沒有聲明,我實際上已經爲客戶想要一種方法來自動測試和部署任何代碼,並通過git notes管理問題票據。這也導致我在AIMS project上的工作。

人們很容易只安裝一個光禿禿的節點系統,該系統有一個內置的用戶,並通過make(1)管理自己的身材,expect(1)crontab(1)/systemd.unit(5),並incrontab(1)。人們甚至可以更進一步,使用具有gridfs/nfs文件存儲的分佈式構建的ansible和celery。

雖然,除了Graybeard UNIX傢伙或原理級別工程師/架構師之外,我不希望任何人能夠真正實現這一目標。只是爲了一個好主意和潛在的學習經驗,因爲構建服務器不過是以自動方式任意執行腳本化任務的一種方式。