"Симпатичная" непрерывная интеграция для Python

Это немного ... напрасный вопрос, но результаты работы BuildBot не особенно хороши для просмотра ..

Например, по сравнению с ..

..и другие, BuildBot выглядит довольно .. архаично

В настоящее время я играю с Hudson, но он очень ориентирован на Java (хотя с это руководство мне было проще настроить, чем BuildBot, и я получил больше информации)

В основном: есть ли какие-либо системы непрерывной интеграции, нацеленные на python, которые создают множество блестящих графиков и тому подобное?


Обновлять: С этого времени проект Jenkins заменил Hudson в качестве версии пакета для сообщества. Первоначальные авторы тоже перешли в этот проект. Jenkins теперь является стандартным пакетом для Ubuntu / Debian, RedHat / Fedora / CentOS и других. Следующее обновление по-прежнему верно. Отправная точка для этого с Дженкинс отличается.

Обновлять: Попробовав несколько альтернатив, я думаю, что остановлюсь на Хадсоне. Честность был красивым и простым, но довольно ограниченным. Я думаю, что Buildbot лучше подходит для наличия большого количества build-slave, чем для всего, что работает на одной машине, как я его использовал.

Настроить Хадсона для проекта Python было довольно просто:

  • Скачать Hudson с сайта http://hudson-ci.org/
  • Запускаем с java -jar hudson.war
  • Откройте веб-интерфейс на адресе по умолчанию http://localhost:8080.
  • Зайдите в Manage Hudson, Plugins, нажмите «Обновить» или аналогичный
  • Установите плагин Git (мне пришлось указать путь git в глобальных настройках Hudson)
  • Создайте новый проект, введите репозиторий, интервалы опроса SCM и т. д.
  • Установите nosetests через easy_install, если это еще не сделано
  • На этапе сборки добавьте nosetests --with-xunit --verbose
  • Установите флажок «Опубликовать отчет о результатах тестирования JUnit» и установите для параметра «XML отчета о тестировании» значение **/nosetests.xml

Это все, что требуется. Вы можете настроить уведомления по электронной почте, и стоит взглянуть на плагины. Некоторые из них я сейчас использую для проектов Python:

  • Плагин SLOCCount для подсчета строк кода (и построения графика!) - вам нужно установить временный счет отдельно
  • Нарушения для синтаксического анализа вывода PyLint (вы можете установить пороги предупреждений, построить график количества нарушений для каждой сборки)
  • Cobertura может анализировать вывод extension.py. Nosetest может собирать данные во время выполнения ваших тестов, используя nosetests --with-coverage (вывод данных записывается в **/coverage.xml).

Отличный вопрос, прямо сейчас я изучаю похожие вещи. Если вы пойдете одним маршрутом, можете ли вы поделиться своим опытом с остальными?

André 22.10.2008 19:02

Не знаю, был ли он доступен, когда вы писали это: используйте плагин Чака Норриса для Hudson, чтобы еще больше усилить контроль над своими материалами!

Johannes Charra 16.12.2009 17:59
Обновление на 2011/2012 гг.: Те, кто рассматривает Hudson, должны использовать Дженкинс, продолжение проекта Hudson с открытым исходным кодом (Hudson теперь контролируется Oracle)
mindthief 10.07.2012 00:27
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
116
3
32 562
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

Не знаю, подойдет ли это: Укушенный создан ребятами, которые пишут Trac, и интегрирован с Trac. Apache Gump - это инструмент CI, используемый Apache. Он написан на Python.

Мы добились большого успеха с TeamCity в качестве нашего CI-сервера и с использованием носа в качестве средства выполнения тестов. Плагин Teamcity для тестов на нос дает вам счетчик пройден / не пройден, читаемый дисплей для неудавшегося теста (который может быть отправлен по электронной почте). Вы даже можете увидеть подробную информацию об ошибках теста во время работы стека.

Если, конечно, поддерживает такие вещи, как запуск на нескольких машинах, и его намного проще настраивать и поддерживать, чем buildbot.

Ответ принят как подходящий

Возможно, вы захотите проверить Нос и плагин вывода Xunit. Вы можете запустить модульные тесты и проверить покрытие с помощью этой команды:

nosetests --with-xunit --enable-cover

Это будет полезно, если вы хотите пойти по маршруту Jenkins или если вы хотите использовать другой сервер CI, который поддерживает отчеты о тестах JUnit.

Точно так же вы можете захватить вывод pylint, используя плагин нарушений для Jenkins

Nose теперь по умолчанию включает плагин xunit - nosetests --with-xunit

dbr 13.10.2009 05:01

Так как же тогда запустить одитинг из Pylint? Когда я делаю nosetests --with-xunit --enable-audit, я получаю nosetests: error: no such option: --enable-audit

Adam Parkin 20.03.2012 03:00

Модернизированный ответ, материал NoseXUnit теперь встроен и переименован из неудачно упавшего --with-nosexunit в --with-xunit.

dbr 09.09.2013 17:35

Страницу водопада Buildbot можно значительно улучшить. Вот хороший пример http://build.chromium.org/buildbot/waterfall/waterfall

Мы использовали немного укушенных. Он красивый и хорошо интегрируется с Trac, но его сложно настроить, если у вас нестандартный рабочий процесс. Кроме того, плагинов не так много, как для более популярных инструментов. В настоящее время мы рассматриваем Hudson в качестве замены.

Сигнал - еще один вариант. Вы можете узнать об этом больше и посмотреть видео также здесь.

Я предполагаю, что эта ветка довольно старая, но вот мой взгляд на нее с Hudson:

Я решил пойти с pip и настроить репо (мучительно работать, но красиво выглядящая корзина для яиц), куда hudson автоматически загружает при успешных тестах. Вот мой грубый и готовый сценарий для использования со сценарием выполнения конфигурации hudson, например: /var/lib/hudson/venv/main/bin/hudson_script.py -w $ WORKSPACE -p my.package -v $ BUILD_NUMBER, просто вставьте ** / охват.xml, pylint.txt и носtests.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 и зависимостями, тогда вы можете просто проверить ствол и запустить на нем все это.

Надеюсь, это кому-то поможет.

------Обновить---------

Я добавил epydoc, который очень хорошо сочетается с Hudson. Просто добавьте javadoc в свою конфигурацию с папкой html

Обратите внимание, что в наши дни pip не поддерживает флаг -E должным образом, поэтому вам нужно создать свой venv отдельно

Этот ответ очень полезен и содержит много подробностей относительно внутреннего устройства Python CI, чего вы не получите бесплатно от Дженкинса или чего-то еще. Спасибо!

maksimov 12.03.2013 21:17

Также определенно стоит попробовать Atlassian Бамбук. Весь пакет Atlassian (JIRA, Confluence, FishEye и т. д.) Довольно хорош.

еще один: Сияющая панда - это размещенный инструмент для Python

Если вы рассматриваете размещенное решение CI и используете открытый исходный код, вам следует также изучить Трэвис Си - он имеет очень хорошую интеграцию с GitHub. Хотя он начинался как инструмент Ruby, некоторое время назад у них был добавлена ​​поддержка Python.

Я бы подумал о CircleCi - у него отличная поддержка Python и очень хороший результат.

Проверьте rultor.com. Как объясняет эта статья, он использует Docker для каждой сборки. Благодаря этому вы можете настроить все, что захотите, внутри своего образа Docker, включая Python.

binstar континуума теперь может запускать сборки из github и может компилироваться для Linux, OSX и Windows (32/64). Самое интересное в том, что он действительно позволяет тесно связать распространение и непрерывную интеграцию. Это пересечение «t» и «I» интеграции. Сайт, рабочий процесс и инструменты действительно отточены, и AFAIK conda - самый надежный и питонический способ распространения сложных модулей Python, где вам нужно обернуть и распространять библиотеки C / C++ / Fotran.

Небольшой отказ от ответственности, мне на самом деле пришлось создать подобное решение для клиента, которому нужен способ автоматического тестирования и развертывания кода Любые на git push, а также для управления билетами с проблемами через git notes. Это также привело к моей работе над Проект AIMS.

Можно легко просто настроить систему с голым узлом, у которой есть пользователь сборки, и управлять их сборкой с помощью make(1), expect(1), crontab(1) / systemd.unit(5) и incrontab(1). Можно даже пойти дальше и использовать ansible и celery для распределенных сборок с файловым хранилищем gridfs / nfs.

Хотя, я бы не ожидал, что кто-то, кроме Седобородого специалиста по UNIX или инженера / архитектора принципиального уровня, действительно зайдет так далеко. Это просто хорошая идея и потенциальный опыт обучения, поскольку сервер сборки - это не что иное, как способ произвольно выполнять задачи по сценарию в автоматическом режиме.

Другие вопросы по теме