2008-10-22 22 views
114

Đây là một chút .. vô ích câu hỏi, nhưng sản lượng BuildBot là không đặc biệt tốt đẹp để nhìn vào .."Pretty" Tích hợp liên tục cho Python

Ví dụ, so với ..

..và những người khác, BuildBot trông khá .. cổ

Tôi hiện đang chơi với Hudson, nhưng nó là rất Java-centric (mặc dù với this guide, tôi tìm thấy nó dễ dàng hơn để thiết lập hơn BuildBot và đã tạo thêm thông tin)

Về cơ bản: có bất kỳ hệ thống Tích hợp liên tục nào nhắm vào python, tạo ra rất nhiều biểu đồ sáng bóng và thích không?


Cập nhật: Kể từ thời điểm này, dự án Jenkins đã thay thế Hudson như các phiên bản cộng đồng của gói. Các tác giả gốc cũng đã chuyển sang dự án này. Jenkins bây giờ là một gói tiêu chuẩn trên Ubuntu/Debian, RedHat/Fedora/CentOS và các gói khác. Bản cập nhật sau vẫn cơ bản đúng. Điểm bắt đầu để làm điều này với Jenkins là khác nhau.

Cập nhật: Sau khi thử một vài lựa chọn thay thế, tôi nghĩ mình sẽ gắn bó với Hudson. Integrity là tốt đẹp và đơn giản, nhưng khá hạn chế. Tôi nghĩ rằng Buildbot phù hợp hơn với việc xây dựng nhiều nô lệ hơn là mọi thứ chạy trên một máy tính đơn lẻ như tôi đang sử dụng nó.

Thiết Hudson lên cho một dự án Python là khá đơn giản:

  • Tải Hudson từ http://hudson-ci.org/
  • Run nó với java -jar hudson.war
  • Mở giao diện web vào địa chỉ mặc định của http://localhost:8080
  • Đến Quản lý Hudson, Plugins, nhấp vào "Cập nhật" hoặc tương tự
  • Cài đặt plugin Git (Tôi phải đặt git con đường trong các ưu đãi toàn cầu Hudson)
  • Tạo một dự án mới, nhập kho, khoảng polling SCM và vân vân
  • Install nosetests qua easy_install nếu nó chưa
  • Trong bước một xây dựng, thêm nosetests --with-xunit --verbose
  • Kiểm tra "Xuất bản báo cáo kết quả kiểm tra JUnit" và đặt "Kiểm tra báo cáo XML" thành **/nosetests.xml

Đó là tất cả những gì bắt buộc.Bạn có thể thiết lập thông báo qua email và the plugins đáng xem. Một vài Tôi hiện đang sử dụng cho các dự án Python: (! Và tạo biểu đồ)

  • SLOCCount plugin để đếm dòng mã - bạn cần phải cài đặt sloccount riêng
  • Violations để phân tích đầu ra pylint (bạn có thể cảnh báo thiết lập ngưỡng, biểu thị số lượng vi phạm trên mỗi công trình xây dựng)
  • Cobertura có thể phân tích đầu ra coverage.py. Nosetest có thể thu thập bảo hiểm khi chạy thử nghiệm của bạn, sử dụng nosetests --with-coverage (điều này viết đầu ra để **/coverage.xml)
+0

Câu hỏi hay, tôi đang tìm kiếm những thứ tương tự ngay bây giờ. Nếu bạn đi một lộ trình, bạn có thể chia sẻ kinh nghiệm của mình với phần còn lại của chúng tôi không? –

+3

Không biết nếu nó có sẵn khi bạn đã viết này: Sử dụng plugin Chuck Norris cho Hudson để tăng cường hơn nữa kiểm soát công cụ của bạn! –

+8

** Cập nhật cho năm 2011/2012 **: Những người xem xét Hudson nên sử dụng [Jenkins] (http://jenkins-ci.org/), sự tiếp tục nguồn mở của dự án Hudson (Hudson bây giờ được [kiểm soát bởi Oracle] (http://stackoverflow.com/questions/4973981/how-to-choose-between-hudson-and-jenkins)) – mindthief

Trả lời

40

Bạn có thể muốn xem Nosethe Xunit output plugin. Bạn có thể có nó chạy thử nghiệm đơn vị của bạn, và kiểm tra vùng phủ sóng với lệnh này:

nosetests --with-xunit --enable-cover 

Đó sẽ là hữu ích nếu bạn muốn đi con đường Jenkins, hoặc nếu bạn muốn sử dụng một máy chủ CI có hỗ trợ cho Báo cáo kiểm tra JUnit.

Tương tự như vậy bạn có thể bắt đầu ra của pylint sử dụng trang thác các violations plugin for Jenkins

+36

Ah niềm vui của tên ứng dụng nguồn mở .. – dbr

+4

Mũi bây giờ bao gồm plugin xunit theo mặc định - 'nosetests --with-xunit' – dbr

+3

Vậy làm thế nào để chạy kiểm tra từ Pylint? Khi tôi thực hiện 'nosetests --with-xunit --enable-audit', tôi nhận được' nosetests: error: không có tùy chọn như vậy: --enable-audit' –

10

Không biết nếu nó sẽ làm: Bitten được thực hiện bởi những kẻ viết Trác và được tích hợp với Trác. Apache Gump là công cụ CI được Apache sử dụng. Nó được viết bằng Python.

9

Chúng tôi đã có thành công lớn với TeamCity là máy chủ CI của chúng tôi và sử dụng mũi làm người thử nghiệm của chúng tôi. Teamcity plugin for nosetests cho bạn số lần vượt qua/thất bại, hiển thị có thể đọc được cho kiểm tra không thành công (có thể là E-Mailed). Bạn thậm chí có thể xem chi tiết các lỗi kiểm tra trong khi bạn đang chạy.

Nếu tất nhiên hỗ trợ những thứ như chạy trên nhiều máy và việc cài đặt và bảo trì đơn giản hơn nhiều so với buildbot thì đơn giản hơn rất nhiều.

0

Chúng tôi đã sử dụng khá nhiều cắn. Nó là khá và tích hợp tốt với Trac, nhưng nó là một nỗi đau trong mông để tùy chỉnh nếu bạn có bất kỳ công việc không chuẩn. Cũng có không chỉ là nhiều plugin như có cho các công cụ phổ biến hơn. Hiện tại chúng tôi đang đánh giá Hudson như một sự thay thế.

+0

Bạn đã làm gì? – Russ

2

Tín hiệu là một tùy chọn khác. Bạn có thể biết thêm về nó và xem video cũng here.

6

Tôi đoán chủ đề này là khá cũ nhưng đây là quan điểm của tôi về nó với hudson:

Tôi quyết định đi với pip và thiết lập một repo (những đau đớn để có được làm việc nhưng cái nhìn tốt đẹp eggbasket), mà hudson tự động tải lên với một thử nghiệm thành công. Đây là kịch bản thô và sẵn sàng của tôi để sử dụng với một tập lệnh cấu hình hudson thực thi như: /var/lib/hudson/venv/main/bin/hudson_script.py -w $ WORKSPACE -p my.package -v $ BUILD_NUMBER, chỉ cần đưa vào **/coverage.xml, pylint.txt và nosetests.xml trong các bit cấu hình:

#!/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() 

Khi nói đến việc triển khai những thứ bạn có thể làm điều gì đó như:

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

Và sau đó mọi người có thể phát triển các công cụ sử dụng:

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

thứ này giả định bạn có một cấu trúc repo cho mỗi gói với một setup.py và phụ thuộc tất cả các thiết lập sau đó bạn chỉ có thể kiểm tra thân cây và chạy công cụ này trên đó.

Tôi hy vọng điều này sẽ giúp ai đó ra ngoài.

------ cập nhật ---------

Tôi đã thêm epydoc phù hợp thực sự độc đáo với hudson. Chỉ cần thêm javadoc để cấu hình của bạn với các thư mục html

Lưu ý rằng pip không hỗ trợ cờ -E đúng những ngày này, vì vậy bạn phải tạo venv của bạn riêng

+0

Câu trả lời này rất hữu ích và có rất nhiều chi tiết liên quan đến nội bộ của Python CI, một cái gì đó bạn sẽ không nhận được miễn phí từ Jenkins hoặc bất cứ điều gì. Cảm ơn! – maksimov

6

Atlassian của Bamboo cũng chắc chắn là đáng để thử qua. Toàn bộ bộ Atlassian (JIRA, Confluence, FishEye, vv) khá ngọt ngào.

3

Nếu bạn đang cân nhắc giải pháp CI tổ chức, và làm mã nguồn mở, bạn nên xem xét Travis CI cũng - nó có tích hợp rất tốt đẹp với GitHub. Trong khi nó bắt đầu như một công cụ Ruby, họ có added Python support một trong khi trước đây.

2

Tôi sẽ xem xét CircleCi - nó có hỗ trợ tuyệt vời về Python và đầu ra rất đẹp.

0

Kiểm tra rultor.com. Khi this article giải thích, nó sử dụng Docker cho mọi công trình xây dựng. Nhờ đó, bạn có thể cấu hình bất cứ điều gì bạn thích bên trong hình ảnh Docker của bạn, bao gồm cả Python.

1

liên tục binstar hiện có thể kích hoạt các bản dựng từ github và có thể biên dịch cho linux, osx và windows (32/64). điều gọn gàng là nó thực sự cho phép bạn kết hợp chặt chẽ việc phân phối và tích hợp liên tục. Đó là vượt qua của t và nằm rải rác của tôi tích hợp. Trang web, quy trình làm việc và các công cụ thực sự được đánh bóng và AFAIK conda là cách mạnh mẽ nhất để phân phối các mô-đun python phức tạp, nơi bạn cần phải bọc phân phối các thư viện C/C++/Fotran.

0

Tuyên bố từ chối trách nhiệm, tôi thực sự phải xây dựng giải pháp như thế này cho khách hàng muốn tự động kiểm tra và triển khai mã số trên git push và quản lý vé phát hành qua ghi chú git. Điều này cũng dẫn đến công việc của tôi trên AIMS project.

Một có thể dễ dàng chỉ cần thiết lập một hệ thống nút trần có một người sử dụng xây dựng và quản lý xây dựng của họ thông qua make(1), expect(1), crontab(1)/systemd.unit(5), và incrontab(1). Một thậm chí có thể đi một bước xa hơn và sử dụng ansible và cần tây cho xây dựng phân phối với một cửa hàng tập tin gridfs/nfs.

Mặc dù, tôi sẽ không mong đợi bất kỳ ai khác ngoài một anh chàng Graybeard UNIX hoặc kỹ sư/kiến ​​trúc sư nguyên tắc thực sự đi xa này.Chỉ cần làm cho một ý tưởng tốt đẹp và kinh nghiệm học tập tiềm năng từ một máy chủ xây dựng là không có gì hơn là một cách để tự ý thực hiện các tác vụ theo kịch bản một cách tự động.