Integración continua "Pretty" para Python


Esto es un poco.. pregunta vana, pero la salida de BuildBot no es particularmente agradable de ver..

Por ejemplo, en comparación con..

..y otros, BuildBot parece más bien.. arcaico

Actualmente estoy jugando con Hudson, pero es muy centrado en Java (aunque con esto guía , me pareció más fácil de configurar que BuildBot, y produjo más información)

Básicamente: ¿hay algún sistema de Integración Continua dirigido a python, que produzca muchos gráficos brillantes y similares?


Update: Desde entonces el proyecto Jenkins ha reemplazado a Hudson como la versión comunitaria del paquete. Los autores originales también se han trasladado a este proyecto. Jenkins es ahora un paquete estándar en Ubuntu/Debian, RedHat/Fedora/CentOS, y otros. El la siguiente actualización sigue siendo esencialmente correcta. El punto de partida para hacer esto con Jenkins es diferente.

Actualizar: Después de probar algunas alternativas, creo que me quedaré con Hudson. La integridad era agradable y simple, pero bastante limitada. Creo que Buildbot es más adecuado para tener numerosos build-slaves, en lugar de todo lo que se ejecuta en una sola máquina como lo estaba usando.

Configurar Hudson para un proyecto de Python fue bastante simple:

  • Descargar Hudson desde http://hudson-ci.org /
  • Ejecutarlo con java -jar hudson.war
  • Abra la interfaz web en la dirección predeterminada de http://localhost:8080
  • Vaya a Administrar Hudson, Plugins, haga clic en" Actualizar " o similar
  • Instalar el plugin Git (tuve que establecer la ruta git en las preferencias globales de Hudson)
  • Crear un nuevo proyecto, entrar en el repositorio, intervalos de sondeo SCM y así sucesivamente
  • Instalar nosetests a través de easy_install si no es ya
  • En el paso de compilación a, agregue nosetests --with-xunit --verbose
  • Marque" Publish JUnit test result report "y establezca" Test report XMLs " en **/nosetests.xml

Eso es todo lo que se requiere. Puede configurar notificaciones por correo electrónico, y los complementos merecen una mirada. Algunos que estoy usando actualmente para proyectos de Python:

  • SLOCCount plugin para contar líneas de código (y graficarlo!)- es necesario instalar sloccount por separado
  • Violaciones a analizar la salida de PyLint (puede configurar umbrales de advertencia, graficar el número de violaciones en cada compilación)
  • Cobertura puede analizar coverage.py salida. Nosetest puede recopilar cobertura mientras ejecuta sus pruebas, usando nosetests --with-coverage (esto escribe la salida a **/coverage.xml)
Author: rickfoosusa, 2008-10-22

14 answers

Es posible que desee comprobar hacia fuera Nariz y el plugin de salida Xunit. Puede hacer que ejecute sus pruebas unitarias y verificaciones de cobertura con este comando:

nosetests --with-xunit --enable-cover

Eso será útil si desea seguir la ruta Jenkins, o si desea usar otro servidor CI que tenga soporte para informes de pruebas JUnit.

De manera similar, puede capturar la salida de pylint usando el complemento violations para Jenkins

 41
Author: Jason Baker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-09 13:33:56

No sé si sería : Mordido es hecho por los chicos que escriben Trac y está integrado con Trac. Apache Gump es la herramienta de CI utilizada por Apache. Está escrito en Python.

 10
Author: edomaur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-22 13:46:55

Hemos tenido un gran éxito con TeamCity como nuestro servidor de CI y utilizando nose como nuestro corredor de pruebas. Teamcity plugin for nosetests le da cuenta de pasar/fallar, pantalla legible para la prueba fallida( que puede ser enviado por correo electrónico). Incluso puede ver detalles de los errores de prueba mientras se ejecuta la pila.

Si, por supuesto, admite cosas como ejecutarse en varias máquinas, y es mucho más simple de configurar y mantener que buildbot.

 9
Author: Kozyarchuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-23 01:30:17

La página de cascada de Buildbot puede ser considerablemente embellecida. He aquí un buen ejemplo http://build.chromium.org/buildbot/waterfall/waterfall

 8
Author: Noufal Ibrahim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-08 09:16:55

El bambú de Atlassian también merece la pena echarle un vistazo. Toda la suite Atlassian (JIRA, Confluence, FishEye, etc.) es bastante dulce.

 6
Author: Russ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-28 18:08:12

Supongo que este hilo es bastante viejo, pero aquí está mi opinión sobre él con Hudson:

Decidí ir con pip y configurar un repo (el doloroso para conseguir trabajo, pero bonito aspecto eggbasket), que hudson auto carga con una prueba exitosa. Aquí está mi script en bruto y listo para usar con un script de ejecución de configuración de Hudson como: /var/lib/hudson/venv/main/bin/hudson_script.py -w WORKSPACE WORKSPACE-p my.package-v BUIL BUILD_NUMBER, solo tienes que poner * * / coverage.xml, pylint.txt y nosetests.xml en la configuración 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()

Cuando se trata de implementar cosas, puedes hacer algo como:

pip -E /location/of/my/venv/ install my_package==X.Y.Z --extra-index http://my_repo

Y entonces la gente puede desarrollar cosas usando:

pip -E /location/of/my/venv/ install -e ./ --extra-index http://my_repo

Esto supone que tienes una estructura de repo por paquete con un setup.py y todas las dependencias configuradas, entonces puedes simplemente echar un vistazo al tronco y ejecutar estas cosas en él.

Espero que esto ayude a alguien.

------actualización---------

He añadido epydoc que encaja muy bien con Hudson. Simplemente agregue javadoc a su config con la carpeta html

Tenga en cuenta que pip no admite la bandera-E correctamente en estos días, por lo que debe crear su venv por separado

 6
Author: Nick Holden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-25 11:31:26

Otro: Shining Panda es una herramienta alojada para python

 3
Author: edomaur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-20 08:28:42

Si estás considerando una solución de CI alojada, y haciendo código abierto, deberías mirar Travis CI también - tiene una integración muy agradable con GitHub. Si bien comenzó como una herramienta Ruby, ha agregado soporte para Python hace un tiempo.

 3
Author: Alex Dupuy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-28 12:43:00

La señal es otra opción. Puede saber más sobre él y ver un video también aquí.

 2
Author: Diego Carrion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-29 04:05:02

Consideraría CircleCI - tiene un gran soporte de Python, y una salida muy bonita.

 2
Author: Paul Biggar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-08 16:41:53

Continuum binstar ahora es capaz de activar compilaciones desde github y puede compilar para linux, osx y windows ( 32 / 64 ). lo bueno es que realmente le permite acoplar de cerca la distribución y la integración continua. Eso es cruzar las t y salpicar las I de Integración. El sitio, el flujo de trabajo y las herramientas están realmente pulidos y AFAIK conda es la forma más robusta y pitónica de distribuir módulos python complejos, donde necesita envolver y distribuir Bibliotecas C/C++ / Futran.

 1
Author: Jelle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-25 19:01:39

Hemos usado bitten bastante. Es bonito y se integra bien con Trac, pero es un dolor en el trasero para personalizar si tiene cualquier flujo de trabajo no estándar. También simplemente no hay tantos plugins como los hay para las herramientas más populares. Actualmente estamos evaluando a Hudson como reemplazo.

 0
Author: Allen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-06 15:03:28

Compruebe rultor.com. Como este artículo explica, utiliza Docker para cada compilación. Gracias a eso, puedes configurar lo que quieras dentro de tu imagen de Docker, incluyendo Python.

 0
Author: yegor256,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-03 17:27:27

Pequeño descargo de responsabilidad, en realidad he tenido que construir una solución como esta para un cliente que quería una forma de probar e implementar automáticamente cualquier código en un git push además de administrar los tickets de emisión a través de git notes. Esto también llevó a mi trabajo en el proyecto AIMS.

Uno podría fácilmente configurar un sistema de nodo desnudo que tenga un usuario de compilación y administrar su compilación a través demake(1), expect(1), crontab(1)/systemd.unit(5), y incrontab(1). Incluso se podría ir un paso más allá y utilizar ansible y apio para distribuido se construye con un almacén de archivos gridfs / nfs.

Aunque, no esperaría que nadie más que un tipo de UNIX Graybeard o un ingeniero/arquitecto a nivel de Principio llegara realmente tan lejos. Solo es una buena idea y una experiencia de aprendizaje potencial, ya que un servidor de compilación no es más que una forma de ejecutar arbitrariamente tareas con scripts de manera automatizada.

 0
Author: Dwight Spencer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-29 19:14:47