这是一个有点虚荣的问题,但BuildBot的输出并不是特别好看.
例如,与...相比
phpUnderControl
詹金斯
哈德森
CruiseControl.rb
..和其他人,BuildBot看起来相当......古老
我目前正在玩Hudson,但它是以Java为中心的(虽然在本指南中,我发现它比BuildBot更容易设置,并产生了更多信息)
基本上:有没有针对python的持续集成系统,它会产生大量闪亮的图形等等?
更新:从那时起,Jenkins项目取代了Hudson作为该软件包的社区版本.原作者也转到了这个项目.Jenkins现在是Ubuntu/Debian,RedHat/Fedora/CentOS等标准软件包.以下更新仍然基本正确.与詹金斯一起做这件事的出发点是不同的.
更新:在尝试了一些替代方案之后,我想我会坚持使用哈德森.诚信很好,很简单,但非常有限.我认为 Buildbot更适合拥有众多构建从服务器,而不是像我使用它一样在一台机器上运行.
为Hudson设置Python项目非常简单:
从http://hudson-ci.org/下载Hudson
运行它 java -jar hudson.war
在默认地址上打开Web界面 http://localhost:8080
转到Manage Hudson,Plugins,单击"更新"或类似内容
安装Git插件(我必须git
在Hudson全局首选项中设置路径)
创建新项目,输入存储库,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
)
Jason Baker.. 41
您可能想要查看Nose和Xunit输出插件.您可以让它运行您的单元测试,并使用此命令进行覆盖检查:
nosetests --with-xunit --enable-cover
如果您想要使用Jenkins路由,或者如果您想使用另一个支持JUnit测试报告的CI服务器,这将非常有用.
同样,您可以使用Jenkins的违规插件捕获pylint的输出
您可能想要查看Nose和Xunit输出插件.您可以让它运行您的单元测试,并使用此命令进行覆盖检查:
nosetests --with-xunit --enable-cover
如果您想要使用Jenkins路由,或者如果您想使用另一个支持JUnit测试报告的CI服务器,这将非常有用.
同样,您可以使用Jenkins的违规插件捕获pylint的输出
不知道是否会这样做:Bitten是由编写Trac并与Trac集成的人制作的.Apache Gump是Apache使用的CI工具.它是用Python编写的.
TeamCity作为我们的CI服务器并使用nose作为我们的测试运行员,我们取得了巨大的成功. 用于nosetests的Teamcity插件可以计算通过/失败,可读显示失败的测试(可以是E-Mailed).您甚至可以在堆栈运行时查看测试失败的详细信息.
当然,如果支持在多台机器上运行,那么设置和维护比buildbot更简单.
Buildbot的瀑布页面可以相当美化.这是一个很好的例子http://build.chromium.org/buildbot/waterfall/waterfall
我想这个帖子已经很老了,但这是我对哈德森的看法:
我决定和pip一起设置一个仓库(痛苦地让工作但很漂亮的鸡蛋),哈德森自动上传到成功的测试.这是我的粗略和准备好的脚本,用于hudson配置执行脚本,如:/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
这个东西假设你有一个repo结构,每个包都设置了setup.py和依赖关系,然后你可以检查一下trunk并在其上运行这些东西.
我希望这可以帮助别人.
------更新---------
我添加了epydoc,它非常适合哈德森.只需使用html文件夹将javadoc添加到您的配置中
请注意,这些天pip不能正确支持-E标志,所以你必须单独创建你的venv
Atlassian's Bamboo绝对值得一试.整个Atlassian套房(JIRA,Confluence,FishEye等)非常甜美.