116 votos

"Bastante" Continuous Integration para Python

Esto es un poco.. vano pregunta, pero BuildBot la salida no es muy agradable a la vista..

Por ejemplo, en comparación con el..

..y otros, BuildBot se ve bastante arcaico..

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

Básicamente: ¿hay alguna Continuo de Integración de sistemas orientados a la de python, que producen un montón de shiney gráficos y la talla?


Actualización: Después de probar un par de alternativas, creo que me quedo con el Hudson. La integridad de la era agradable y simple, pero muy limitado. Creo que Buildbot se adapta mejor a numerosos acumulación de esclavos, en lugar de todo lo que se ejecuta en una sola máquina, como yo lo estaba usando.

Configuración de Hudson para un proyecto de Python era bastante simple:

  • Descargar Hudson de http://hudson-ci.org/
  • Ejecutan java -jar hudson.war
  • Abra la interfaz web en la dirección predeterminada de http://localhost:8080
  • Ir a Gestionar Hudson, Complementos, haga clic en "Actualizar" o similar
  • Instalar Git plugin (tuve que establezca la git ruta en el Hudson global de preferencias)
  • Crear un nuevo proyecto, entrar en el repositorio, SCM intervalos de sondeo y así sucesivamente
  • Instale nosetests través easy_install si no ya
  • En el paso de generación, agregue nosetests --with-xunit --verbose
  • Compruebe en "Publicar JUnit informe de resultado de prueba" y ajuste "informe de Prueba de XMLs" para **/nosetests.xml

Eso es todo lo que necesita. Puede configurar las notificaciones de correo electrónico, y los plugins que vale la pena un vistazo. Unos actualmente estoy utilizando para Python proyectos:

  • SLOCCount plugin para contar líneas de código (y el gráfico de ella!) - usted necesita para instalar sloccount por separado
  • Las violaciones a analizar la PyLint de salida (usted puede configurar los umbrales de advertencia, un gráfico del número de violaciones a través de cada generación)
  • Cobertura puede analizar el coverage.py de salida. Nosetest puede reunir la cobertura durante la ejecución de las pruebas, utilizando nosetests --with-coverage (esto escribe el resultado en **/coverage.xml)

41voto

Jason Baker Puntos 56682

Usted puede ser que desee comprobar hacia fuera de la Nariz y la Xunit plugin de salida. Usted puede tener que ejecutar las pruebas unitarias, y la cobertura de los cheques con este comando:

nosetests --with-xunit --enable-cover

Que va a ser útil si quieres ir a la Jenkins ruta, o si desea utilizar otro servidor CI que tiene soporte para JUnit test del informador.

Del mismo modo, usted puede capturar la salida de pylint utilizando las violaciones plugin para Jenkins

10voto

edomaur Puntos 806

No sé si lo haría: mordido es hecha 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.

9voto

Kozyarchuk Puntos 4613

Hemos tenido un gran éxito con TeamCity como nuestro servidor CI y el uso de la nariz como la prueba de nuestro corredor. Teamcity plugin para nosetests da usted cuenta de pasa/falla, legible pantalla de error de la prueba( que puede ser Enviado por Correo electrónico). Usted puede incluso ver los detalles de los fallos de la prueba, mientras que la pila se está ejecutando.

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

8voto

Noufal Ibrahim Puntos 32200

Página de Buildbot cascada puede ser prettified considerablemente. Aquí es un buen ejemplo de http://build.chromium.org/buildbot/waterfall/waterfall

6voto

Nick Holden Puntos 716

Supongo que este hilo es muy antiguo, pero aquí está mi opinión sobre ella con hudson:

Me decidí a ir con pip y establecer un repo (el doloroso para conseguir trabajo, pero de aspecto agradable eggbasket), que hudson automático de cargas con éxito una de las pruebas. Aquí está mi áspero y listo script para el uso con un hudson config ejecutar secuencias de comandos como: /var/lib/hudson/venv/main/bin/hudson_script.py -w $WORKSPACE-p mi.paquete-v $BUILD_NUMBER, acaba de poner en * * */coverage.xml, pylint.txt y nosetests.xml en la configuración de 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 que usted puede hacer algo como:

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

Y, a continuación, las personas pueden desarrollar cosas a través de:

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

Esto supone que un repo estructura por paquete con un setup.py y dependencias de todo el conjunto hasta que sólo puede retirar el tronco y ejecutar este material sobre ella.

Espero que esto ayude a alguien.

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

He añadido epydoc, que encaja muy bien con hudson. Acaba de agregar javadoc para su configuración con la carpeta html

Tenga en cuenta que el pip no es compatible con la opción-E correctamente en estos días, así que tienes que crear tu venv por separado

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X