ChatGPT解决这个技术问题 Extra ChatGPT

Python 的“漂亮”持续集成

这是一个有点......徒劳的问题,但BuildBot的输出并不是特别好看......

例如,相比..

phpUnderControl

詹金斯·哈德森

哈德逊

CruiseControl.rb

..和其他人,BuildBot 看起来相当.. 陈旧

我目前正在使用 Hudson,但它非常以 Java 为中心(尽管使用 this guide,我发现它比 BuildBot 更容易设置,并且产生了更多信息)

基本上:是否有任何针对 python 的持续集成系统,可以产生大量闪亮的图表等?

更新: 自此以来,Jenkins 项目已取代 Hudson 作为该软件包的社区版本。原作者也已移至该项目。 Jenkins 现在是 Ubuntu/Debian、RedHat/Fedora/CentOS 等的标准软件包。以下更新基本上仍然是正确的。使用 Jenkins 执行此操作的起点不同。

更新:在尝试了一些替代方案后,我想我会坚持使用 Hudson。 Integrity 很好很简单,但非常有限。我认为 Buildbot 更适合拥有大量构建从属,而不是像我使用它那样在一台机器上运行所有东西。

为 Python 项目设置 Hudson 非常简单:

从 http://hudson-ci.org/ 下载 Hudson

使用 java -jar hudson.war 运行它

在默认地址 http://localhost:8080 打开网页界面

转到管理 Hudson,插件,单击“更新”或类似

安装 Git 插件(我必须在 Hudson 全局首选项中设置 git 路径)

新建项目,进入仓库,SCM轮询间隔等

如果尚未安装,请通过 easy_install 安装鼻子测试

在构建步骤中,添加 nosetests --with-xunit --verbose

勾选“发布 JUnit 测试结果报告”并将“测试报告 XMLs”设置为 **/nosetests.xml

这就是所有需要的。您可以设置电子邮件通知,the plugins 值得一看。我目前用于 Python 项目的一些:

SLOCCount 插件用于计算代码行数(并绘制图表!) - 您需要单独安装 sloccount

解析 PyLint 输出的违规行为(您可以设置警告阈值,绘制每个构建的违规数量)

Cobertura 可以解析 coverage.py 输出。 Nosetest 可以在运行测试时收集覆盖率,使用 nosetests --with-coverage(这会将输出写入 **/coverage.xml)

好问题,我现在正在研究类似的事情。如果你走一条路,你能和我们分享你的经验吗?
不知道您写这篇文章时是否可用:使用 Hudson 的 Chuck Norris 插件来进一步增强对您的东西的控制!
2011/2012 年更新:考虑使用 Hudson 的人应该使用 Jenkins,它是 Hudson 项目的开源延续(Hudson 现在是 controlled by Oracle

d
dbr

您可能想查看 Nosethe Xunit output plugin。你可以让它运行你的单元测试,并使用这个命令检查覆盖率:

nosetests --with-xunit --enable-cover

如果您想走 Jenkins 路线,或者如果您想使用另一个支持 JUnit 测试报告的 CI 服务器,这将很有帮助。

同样,您可以使用 violations plugin for Jenkins 捕获 pylint 的输出


Nose 现在默认包含 xunit 插件 - nosetests --with-xunit
那么如何从 Pylint 进行审计呢?当我做 nosetests --with-xunit --enable-audit 我得到 nosetests: error: no such option: --enable-audit
现代化的答案,NoseXUnit 的东西现在是内置的,并从 unfortunate-when-downcased --with-nosexunit 重命名为 --with-xunit
e
edomaur

不知道会不会:Bitten 由编写 Trac 的人制作并与 Trac 集成。 Apache Gump 是 Apache 使用的 CI 工具。它是用 Python 编写的。


K
Kozyarchuk

我们使用 TeamCity 作为我们的 CI 服务器并使用鼻子作为我们的测试运行程序取得了巨大的成功。 Teamcity plugin for nosetests 为您提供通过/失败计数,失败测试的可读显示(可以通过电子邮件发送)。您甚至可以在堆栈运行时查看测试失败的详细信息。

如果当然支持在多台机器上运行之类的东西,那么它的设置和维护要比 buildbot 简单得多。


N
Noufal Ibrahim

Buildbot 的瀑布页面可以大大美化。这是一个很好的例子http://build.chromium.org/buildbot/waterfall/waterfall


R
Russ

Atlassian 的 Bamboo 也绝对值得一试。整个 Atlassian 套件(JIRA、Confluence、FishEye 等)非常可爱。


N
Nick Holden

我想这个线程已经很老了,但这是我对哈德森的看法:

我决定使用 pip 并设置一个 repo(开始工作很痛苦但看起来很漂亮的蛋篮),hudson 自动上传到成功的测试。这是我的粗略和准备好的脚本,可与 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 和依赖项,然后你可以检查主干并在其上运行这些东西。

我希望这可以帮助某人。

- - - 更新 - - - - -

我添加了 epydoc,它非常适合 hudson。只需使用 html 文件夹将 javadoc 添加到您的配置中

请注意,这些天 pip 不正确支持 -E 标志,因此您必须单独创建 venv


这个答案非常有用,并且有很多关于 Python CI 内部的详细信息,这是您从 Jenkins 或其他任何东西无法免费获得的。谢谢!
e
edomaur

另一个:Shining Panda 是 python 的托管工具


A
Alex Dupuy

如果您正在考虑托管 CI 解决方案并进行开源,那么您也应该查看 Travis CI - 它与 GitHub 的集成非常好。虽然它最初是一个 Ruby 工具,但他们在 added Python support 前有一段时间。


来自 Travis CI org 网页:“自 2021 年 6 月 15 日起,travis-ci.org 上的建设已停止。请从现在开始使用 travis-ci.com。”
D
Diego Carrion

信号是另一种选择。您可以了解更多信息并观看视频here


P
Paul Biggar

我会考虑 CircleCi - 它有很好的 Python 支持和非常漂亮的输出。


J
Jelle

continuum 的 binstar 现在能够从 github 触发构建,并且可以为 linux、osx 和 windows ( 32 / 64 ) 编译。巧妙的是,它确实允许您将分布和持续集成紧密结合在一起。那是跨越 t 并点缀 I 的整合。站点、工作流程和工具都非常完善,AFAIK conda 是分发复杂 Python 模块的最强大和最 Python 的方式,您需要在其中包装分发 C/C++/Fotran 库。


A
Allen

我们已经用过很多次了。它很漂亮并且与 Trac 很好地集成在一起,但是如果你有任何非标准的工作流程,定制是一件很痛苦的事情。此外,插件也没有更流行的工具那么多。目前,我们正在评估 Hudson 作为替代品。


y
yegor256

检查rultor.com。正如 this article 所解释的,它对每个构建都使用 Docker。多亏了这一点,您可以在 Docker 映像中配置任何您喜欢的内容,包括 Python。


D
Dwight Spencer

一点免责声明,我实际上必须为想要一种在 git push 上自动测试和部署 any 代码并通过 git notes 管理问题票证的方法的客户构建这样的解决方案。这也导致了我在 AIMS project 上的工作。

人们可以轻松地设置一个具有构建用户的裸节点系统,并通过 make(1)expect(1)crontab(1)/systemd.unit(5)incrontab(1) 管理他们的构建。甚至可以更进一步,将 ansible 和 celery 用于带有 gridfs/nfs 文件存储的分布式构建。

虽然,除了 Graybeard UNIX 人员或原理级工程师/架构师之外,我不希望任何人真正走到这一步。因为构建服务器只不过是一种以自动化方式任意执行脚本任务的方式,因此只是一个不错的想法和潜在的学习体验。