การผสานรวมอย่างต่อเนื่อง“ Pretty” สำหรับ Python


116

นี่เป็นคำถามที่ไร้สาระเล็กน้อย แต่ผลลัพธ์ของ BuildBot ไม่ค่อยดีนัก ..

ยกตัวอย่างเทียบกับ ..

.. และอื่น ๆBuildBotดูค่อนข้าง .. คร่ำครึ

ฉันกำลังเล่นกับ Hudson แต่มันเป็น Java เป็นศูนย์กลาง (แม้ว่าจะมีคู่มือนี้แต่ฉันพบว่าการตั้งค่าง่ายกว่า BuildBot และให้ข้อมูลเพิ่มเติม)

โดยพื้นฐานแล้ว: มีระบบการบูรณาการแบบต่อเนื่องใด ๆ ที่มุ่งเป้าไปที่ python ซึ่งสร้างกราฟที่เป็นประกายและสิ่งที่ชอบหรือไม่?


อัปเดต:ตั้งแต่เวลานี้โครงการ Jenkins ได้แทนที่ฮัดสันเป็นเวอร์ชันชุมชนของแพ็คเกจ ผู้เขียนเดิมได้ย้ายมาที่โครงการนี้เช่นกัน ตอนนี้ Jenkins เป็นแพ็คเกจมาตรฐานบน Ubuntu / Debian, RedHat / Fedora / CentOS และอื่น ๆ การอัปเดตต่อไปนี้ยังคงถูกต้องเป็นหลัก จุดเริ่มต้นในการทำสิ่งนี้กับเจนกินส์นั้นแตกต่างกัน

อัปเดต:หลังจากลองทางเลือกอื่น ๆ แล้วฉันคิดว่าฉันจะติดกับฮัดสัน ความซื่อสัตย์เป็นสิ่งที่ดีและเรียบง่าย แต่ค่อนข้าง จำกัด ฉันคิดว่า Buildbotเหมาะกับการมี build-slave จำนวนมากมากกว่าทุกอย่างที่ทำงานบนเครื่องเดียวเหมือนที่ฉันใช้

การตั้งค่าฮัดสันสำหรับโครงการ Python นั้นค่อนข้างง่าย:

  • ดาวน์โหลดฮัดสันจาก http://hudson-ci.org/
  • เรียกใช้ด้วย java -jar hudson.war
  • เปิดเว็บอินเตอร์เฟสตามที่อยู่เริ่มต้นของ http://localhost:8080
  • ไปที่ Manage Hudson, Plugins คลิก "Update" หรือที่คล้ายกัน
  • ติดตั้งปลั๊กอิน Git (ฉันต้องตั้งค่า gitเส้นทางในการตั้งค่าส่วนกลางของฮัดสัน)
  • สร้างโปรเจ็กต์ใหม่ป้อนที่เก็บช่วงเวลาการสำรวจ SCM และอื่น ๆ
  • ติดตั้งnosetestsผ่านeasy_installหากยังไม่ได้ดำเนินการ
  • ในขั้นตอนการสร้างให้เพิ่ม nosetests --with-xunit --verbose
  • ตรวจสอบ "เผยแพร่รายงานผลการทดสอบ JUnit" และตั้งค่า "XML ของรายงานการทดสอบ" เป็น **/nosetests.xml

นั่นคือทั้งหมดที่จำเป็น คุณสามารถตั้งค่าการแจ้งเตือนทางอีเมลและปลั๊กอินก็น่าดู ฉันกำลังใช้บางส่วนสำหรับโครงการ Python:

  • ปลั๊กอิน SLOCCountเพื่อนับบรรทัดของโค้ด (และสร้างกราฟ!) - คุณต้องติดตั้งsloccountแยกต่างหาก
  • การละเมิดในการแยกวิเคราะห์เอาต์พุต PyLint (คุณสามารถตั้งค่าขีด จำกัด คำเตือนกราฟจำนวนการละเมิดในแต่ละบิลด์)
  • Coberturaสามารถแยกวิเคราะห์เอาต์พุต coverage.py Nosetest สามารถรวบรวมความครอบคลุมขณะดำเนินการทดสอบของคุณโดยใช้nosetests --with-coverage(สิ่งนี้เขียนผลลัพธ์ไปที่**/coverage.xml)

เป็นคำถามที่ดีตอนนี้ฉันกำลังมองหาสิ่งที่คล้ายกัน ถ้าคุณไปเส้นทางเดียวคุณสามารถแบ่งปันประสบการณ์ของคุณกับพวกเราที่เหลือได้หรือไม่?
André

3
ไม่ทราบว่ามีให้บริการเมื่อคุณเขียนสิ่งนี้หรือไม่: ใช้ปลั๊กอิน Chuck Norris สำหรับ Hudson เพื่อเพิ่มประสิทธิภาพการควบคุมสิ่งของของคุณ!
Johannes Charra

8
อัปเดตสำหรับปี 2011/2012 : ผู้ที่พิจารณาฮัดสันควรใช้เจนกินส์ซึ่งเป็นความต่อเนื่องของโอเพ่นซอร์สของโครงการฮัดสัน (ขณะนี้ฮัดสันถูกควบคุมโดย Oracle )
mindthief

คำตอบ:


41

คุณอาจต้องการตรวจสอบจมูกและปลั๊กอินเอาท์พุท xUnit คุณสามารถเรียกใช้การทดสอบหน่วยของคุณและการตรวจสอบความครอบคลุมด้วยคำสั่งนี้:

nosetests --with-xunit --enable-cover

ซึ่งจะเป็นประโยชน์หากคุณต้องการไปเส้นทาง Jenkins หรือหากคุณต้องการใช้เซิร์ฟเวอร์ CI อื่นที่รองรับการรายงานผลการทดสอบ JUnit

ในทำนองเดียวกันคุณสามารถจับเอาต์พุตของไพลินต์โดยใช้ปลั๊กอินการละเมิดสำหรับเจนกินส์


4
ตอนนี้ Nose มีปลั๊กอิน xunit โดยค่าเริ่มต้น -nosetests --with-xunit
dbr

3
แล้วเราจะเรียกใช้การตรวจสอบจาก Pylint ได้อย่างไร? เมื่อฉันnosetests --with-xunit --enable-auditได้รับnosetests: error: no such option: --enable-audit
Adam Parkin

2
คำตอบที่ทันสมัยตอนนี้สิ่งที่ NoseXUnit ถูกสร้างขึ้นแล้วและเปลี่ยนชื่อจากโชคร้ายเมื่อลด--with-nosexunitลง--with-xunitเป็น
dbr

10

ไม่รู้ว่าจะทำได้ไหม: Bittenทำโดยคนที่เขียน Trac และรวมเข้ากับ Trac Apache Gumpเป็นเครื่องมือ CI ที่ Apache ใช้ มันเขียนด้วยภาษา Python


9

เราประสบความสำเร็จอย่างมากกับTeamCityในฐานะเซิร์ฟเวอร์ CI ของเราและใช้จมูกเป็นตัวดำเนินการทดสอบของเรา ปลั๊กอิน Teamcity สำหรับการทดสอบ nosetestsช่วยให้คุณสามารถนับการผ่าน / ล้มเหลวการแสดงผลที่อ่านได้สำหรับการทดสอบที่ล้มเหลว (ซึ่งสามารถส่งทางอีเมลได้) คุณยังสามารถดูรายละเอียดของความล้มเหลวในการทดสอบในขณะที่คุณกำลังทำงานอยู่

หากแน่นอนว่ารองรับสิ่งต่างๆเช่นการทำงานบนเครื่องหลายเครื่องและการตั้งค่าและบำรุงรักษาง่ายกว่า buildbot มาก




6

ฉันเดาว่ากระทู้นี้ค่อนข้างเก่า แต่นี่คือสิ่งที่ฉันใช้กับฮัดสัน:

ฉันตัดสินใจใช้ pip และตั้งค่า repo (คนที่เจ็บปวดในการทำงาน แต่ตะกร้าไข่ที่ดูดี) ซึ่งฮัดสันอัปโหลดอัตโนมัติด้วยการทดสอบที่ประสบความสำเร็จ นี่คือสคริปต์คร่าวๆและพร้อมสำหรับการใช้งานกับสคริปต์ดำเนินการกำหนดค่าฮัดสันเช่น: /var/lib/hudson/venv/main/bin/hudson_script.py -w $ WORKSPACE -p my.package -v $ BUILD_NUMBER เพียงแค่ใส่เข้าไป ** / coverage.xml, pylint.txt และ nosetests.xml ใน config bits:

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

สิ่งนี้ถือว่าคุณมีโครงสร้าง repo ต่อแพ็คเกจที่มีการตั้งค่า setup.py และการอ้างอิงทั้งหมดจากนั้นคุณสามารถตรวจสอบลำต้นและเรียกใช้สิ่งนี้ได้

ฉันหวังว่านี่จะช่วยใครบางคนได้

------ ปรับปรุง ---------

ฉันได้เพิ่ม epydoc ซึ่งเข้ากันได้ดีกับฮัดสัน เพียงเพิ่ม javadoc ใน config ของคุณด้วยโฟลเดอร์ html

โปรดทราบว่า pip ไม่สนับสนุนแฟล็ก -E อย่างถูกต้องในปัจจุบันดังนั้นคุณต้องสร้าง venv แยกกัน


คำตอบนี้มีประโยชน์มากและมีรายละเอียดมากมายเกี่ยวกับภายในของ Python CI สิ่งที่คุณจะไม่ได้รับฟรีจาก Jenkins หรืออะไรก็ตาม ขอบคุณ!
maksimov


3

หากคุณกำลังพิจารณาโซลูชัน CI ที่โฮสต์และทำโอเพ่นซอร์สคุณควรพิจารณาTravis CIด้วยเช่นกันซึ่งมีการผสานรวมกับ GitHub ได้เป็นอย่างดี ในขณะที่มันเริ่มต้นเป็นเครื่องมือ Ruby พวกเขาได้เพิ่มการรองรับ Pythonเมื่อไม่นานมานี้


2

Signal เป็นอีกทางเลือกหนึ่ง คุณสามารถทราบข้อมูลเพิ่มเติมเกี่ยวกับมันและดูวิดีโอยังที่นี่



1

ตอนนี้binstarของต่อเนื่องสามารถทริกเกอร์บิวด์จาก github และสามารถคอมไพล์สำหรับ linux, osx และ windows (32/64) สิ่งที่เรียบร้อยก็คือมันช่วยให้คุณสามารถจับคู่การกระจายและการรวมอย่างต่อเนื่องได้อย่างใกล้ชิด นั่นคือการข้าม t และการเติม I's of Integration ไซต์เวิร์กโฟลว์และเครื่องมือได้รับการขัดเกลาอย่างแท้จริงและ AFAIK conda เป็นวิธีที่มีประสิทธิภาพและรวดเร็วที่สุดในการกระจายโมดูล python ที่ซับซ้อนซึ่งคุณต้องห่อและแจกจ่ายไลบรารี C / C ++ / Fotran


0

เราเคยกัดมาพอสมควร มันสวยและเข้ากันได้ดีกับ Trac แต่มันเป็นความเจ็บปวดในการปรับแต่งหากคุณมีขั้นตอนการทำงานที่ไม่เป็นมาตรฐาน นอกจากนี้ยังมีปลั๊กอินไม่มากเท่าที่มีสำหรับเครื่องมือยอดนิยม ขณะนี้เรากำลังประเมินฮัดสันแทน


0

ตรวจสอบrultor.com ตามที่บทความนี้อธิบายมันใช้ Docker สำหรับทุกบิลด์ ด้วยเหตุนี้คุณสามารถกำหนดค่าสิ่งที่คุณต้องการภายในอิมเมจ Docker ของคุณรวมถึง Python


0

ข้อจำกัดความรับผิดชอบเล็กน้อยฉันต้องสร้างโซลูชันเช่นนี้สำหรับลูกค้าที่ต้องการวิธีทดสอบและปรับใช้รหัสใด ๆโดยอัตโนมัติในการกดคอมไพล์บวกจัดการตั๋วปัญหาผ่านบันทึกคอมไพล์ นอกจากนี้ยังนำไปสู่การทำงานของฉันในโครงการ AIMS

หนึ่งสามารถตั้งค่าได้อย่างง่ายดายเพียงแค่ระบบโหนดเปลือยที่มีผู้ใช้สร้างและจัดการสร้างของพวกเขาผ่านmake(1), expect(1), crontab(1)/ และsystemd.unit(5) incrontab(1)เราสามารถก้าวไปอีกขั้นและใช้ ansible และขึ้นฉ่ายสำหรับงานสร้างแบบกระจายด้วยที่เก็บไฟล์ gridfs / nfs

แม้ว่าฉันจะไม่คาดหวังว่าจะมีใครอื่นนอกจากคนที่แต่งตัวประหลาดของ Graybeard UNIX หรือวิศวกร / สถาปนิกระดับ Principle จะไปได้ไกลขนาดนี้ เพียงแค่สร้างความคิดที่ดีและประสบการณ์การเรียนรู้ที่เป็นไปได้เนื่องจากเซิร์ฟเวอร์ที่สร้างขึ้นนั้นไม่มีอะไรมากไปกว่าวิธีดำเนินงานที่มีสคริปต์โดยพลการในรูปแบบอัตโนมัติ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.