«Красивая» непрерывная интеграция для Python

116

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

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

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

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

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


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

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

Настроить Хадсона для проекта 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 для подсчета строк кода (и построения графика!) - вам необходимо установить sloccount отдельно
  • Нарушения для анализа вывода PyLint (вы можете установить пороги предупреждений, графически отображать количество нарушений для каждой сборки)
  • Cobertura может анализировать вывод extension.py . Nosetest может собирать покрытие во время выполнения ваших тестов, используя nosetests --with-coverage(это записывает вывод в **/coverage.xml)
DBR
источник
Отличный вопрос, прямо сейчас я изучаю похожие вещи. Если вы пойдете одним маршрутом, можете ли вы поделиться своим опытом с остальными?
Андре
3
Не знаю, был ли он доступен, когда вы писали это: используйте плагин Чака Норриса для Hudson, чтобы еще больше усилить контроль над своими материалами!
Йоханнес Чарра
8
Обновление на 2011/2012 : Те, кто считает, что Hudson должны использовать Jenkins , продолжение проекта Hudson с открытым исходным кодом (Hudson теперь контролируется Oracle )
mindthief 09

Ответы:

41

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

nosetests --with-xunit --enable-cover

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

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

Джейсон Бейкер
источник
4
Nose теперь по умолчанию включает плагин xunit -nosetests --with-xunit
dbr
3
Так как же тогда запустить одитинг из Pylint? Когда я это сделаю, nosetests --with-xunit --enable-auditя получуnosetests: error: no such option: --enable-audit
Адам Паркин
2
Модернизированный ответ, материал NoseXUnit теперь встроен и переименован из неудачно-когда-вниз --with-nosexunitв --with-xunit.
dbr 09
10

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

edomaur
источник
9

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

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

Kozyarchuk
источник
6

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

Russ
источник
6

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

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

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

Алекс Дюпюи
источник
2

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

Диего Каррион
источник
1

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

Элле
источник
0

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

Аллен
источник
0

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

yegor256
источник
0

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

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

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

Дуайт Спенсер
источник