web-dev-qa-db-fra.com

"Jolie" intégration continue pour Python

C'est une question un peu .. vaine, mais la sortie de BuildBot n'est pas particulièrement agréable à regarder ..

Par exemple, par rapport à ..

..et autres, BuildBot semble plutôt .. archaïque

Je joue actuellement avec Hudson, mais il est très centré sur Java (bien qu'avec ce guide , j'ai trouvé plus facile à configurer que BuildBot, et j'ai produit plus d'informations)

Fondamentalement: existe-t-il des systèmes d'intégration continue destinés au python, qui produisent beaucoup de graphiques brillants et autres?


Mise à jour: Depuis ce temps, le projet Jenkins a remplacé Hudson en tant que version communautaire du package. Les auteurs originaux sont également passés à ce projet. Jenkins est maintenant un paquet standard sur Ubuntu/Debian, RedHat/Fedora/CentOS et autres. La mise à jour suivante est toujours essentiellement correcte. Le point de départ pour le faire avec Jenkins est différent.

Mise à jour: Après avoir essayé quelques alternatives, je pense que je vais m'en tenir à Hudson. intégrité était agréable et simple, mais assez limité. Je pense que Buildbot est mieux adapté pour avoir de nombreux build-slaves, plutôt que tout ce qui fonctionne sur une seule machine comme je l'utilisais.

Configurer Hudson pour un projet Python était assez simple:

  • Téléchargez Hudson depuis http://hudson-ci.org/
  • Exécutez-le avec Java -jar hudson.war
  • Ouvrez l'interface Web sur l'adresse par défaut de http://localhost:8080
  • Allez dans Gérer Hudson, Plugins, cliquez sur "Mettre à jour" ou similaire
  • Installez le plugin Git (j'ai dû définir le chemin git dans les préférences globales d'Hudson)
  • Créez un nouveau projet, entrez le référentiel, les intervalles d'interrogation SCM, etc.
  • Installez nosetests via easy_install si ce n'est pas déjà fait
  • À l'étape de génération, ajoutez nosetests --with-xunit --verbose
  • Cochez "Publier le rapport des résultats du test JUnit" et définissez "Rapport XML des tests" sur **/nosetests.xml

C'est tout ce qu'il faut. Vous pouvez configurer des notifications par e-mail, et les plugins valent le coup d'œil. Quelques-uns que j'utilise actuellement pour les projets Python:

  • plugin SLOCCount pour compter les lignes de code (et le représenter graphiquement!) - vous devez installer sloccount séparément
  • Violations pour analyser la sortie PyLint (vous pouvez configurer des seuils d'avertissement, représenter graphiquement le nombre de violations sur chaque build)
  • Cobertura peut analyser la sortie coverage.py. Nosetest peut collecter la couverture pendant l'exécution de vos tests, en utilisant nosetests --with-coverage (ceci écrit la sortie dans **/coverage.xml)
116
dbr

Vous voudrez peut-être vérifier Nose et le plugin de sortie Xunit . Vous pouvez lui faire exécuter vos tests unitaires et les contrôles de couverture avec cette commande:

nosetests --with-xunit --enable-cover

Cela sera utile si vous souhaitez suivre la route Jenkins ou si vous souhaitez utiliser un autre serveur CI prenant en charge les rapports de test JUnit.

De même, vous pouvez capturer la sortie de pylint en utilisant le plugin violations pour Jenkins

41
Jason Baker

Je ne sais pas si cela ferait l'affaire: Bitten est fait par les gars qui écrivent Trac et est intégré à Trac. Apache Gump est l'outil CI utilisé par Apache. Il est écrit en Python.

10
edomaur

Nous avons eu beaucoup de succès avec TeamCity comme serveur CI et en utilisant nose comme testeur. plugin Teamcity pour nosetests vous donne le nombre de réussite/échec, un affichage lisible pour le test ayant échoué (qui peut être envoyé par e-mail). Vous pouvez même voir les détails des échecs de test pendant l'exécution de votre pile.

Bien sûr, il prend en charge des choses comme l'exécution sur plusieurs machines, et il est beaucoup plus simple à configurer et à maintenir que buildbot.

9
Kozyarchuk

La page cascade de Buildbot peut être considérablement améliorée. Voici un bel exemple http://build.chromium.org/buildbot/waterfall/waterfall

8
Noufal Ibrahim

Je suppose que ce fil est assez ancien, mais voici mon point de vue avec Hudson:

J'ai décidé d'aller avec pip et de mettre en place un repo (le pénible pour travailler mais le joli corbeille à oeufs), que hudson télécharge automatiquement avec des tests réussis. Voici mon script approximatif et prêt à l'emploi avec un script d'exécution de configuration hudson comme: /var/lib/hudson/venv/main/bin/hudson_script.py -w $ WORKSPACE -p my.package -v $ BUILD_NUMBER, insérez simplement **/coverage.xml, pylint.txt et nosetests.xml dans les bits de configuration:

#!/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 __== "__main__":
    main()

Quand il s'agit de déployer des choses, vous pouvez faire quelque chose comme:

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

Et puis les gens peuvent développer des trucs en utilisant:

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

Ce truc suppose que vous avez une structure de référentiel par paquet avec un setup.py et des dépendances tous configurés, alors vous pouvez simplement vérifier le tronc et exécuter ce truc dessus.

J'espère que ça aide quelqu'un.

------mise à jour---------

J'ai ajouté epydoc qui s'intègre très bien avec hudson. Ajoutez simplement javadoc à votre configuration avec le dossier html

Notez que pip ne prend pas correctement en charge le drapeau -E de nos jours, vous devez donc créer votre venv séparément

6
Nick Holden

Atlassian's Bamboo vaut également le détour. L'ensemble de la suite Atlassian (JIRA, Confluence, FishEye, etc.) est plutôt agréable.

6
Russ

un autre: Shining Panda est un outil hébergé pour python

3
edomaur

Si vous envisagez une solution CI hébergée et que vous faites de l'open source, vous devriez également examiner Travis CI - il a une très belle intégration avec GitHub. Alors qu'il a commencé comme un outil Ruby, ils ont ajouté Python il y a un certain temps).

3
Alex Dupuy

Le signal est une autre option. Vous pouvez en savoir plus à ce sujet et regarder une vidéo également ici .

2
Diego Carrion

Je considérerais CircleCi - il a un grand support Python, et une très jolie sortie.

2
Paul Biggar

binstar de continuum est maintenant capable de déclencher des builds à partir de github et peut compiler pour linux, osx et windows (32/64). ce qui est bien, c'est qu'il vous permet vraiment de coupler étroitement la distribution et l'intégration continue. C'est franchir les t et parsemer les I de l'intégration. Le site, le flux de travail et les outils sont vraiment raffinés et AFAIK conda est le moyen le plus robuste et Pythonique de distribuer des modules complexes python, où vous devez encapsuler et distribue les bibliothèques C/C++/Fotran.

1
Jelle

Vérifiez rultor.com . Comme cet article l'explique, il utilise Docker pour chaque build. Grâce à cela, vous pouvez configurer ce que vous voulez dans votre image Docker, y compris Python.

0
yegor256

Petit avertissement, j'ai en fait dû créer une solution comme celle-ci pour un client qui voulait un moyen de tester et de déployer automatiquement tout code sur un git Push ainsi que gérer les tickets d'émission via des notes git. Cela a également conduit à mon travail sur le projet AIMS .

On pourrait facilement configurer simplement un système de nœuds nus qui a un utilisateur de build et gérer leur build via make(1), expect(1), crontab(1)/systemd.unit(5) et incrontab(1). On pourrait même aller plus loin et utiliser ansible et céleri pour les builds distribués avec un magasin de fichiers gridfs/nfs.

Cependant, je ne m'attendrais pas à ce que quelqu'un d'autre qu'un gars de Graybeard UNIX ou un ingénieur/architecte de niveau principal aille aussi loin. En fait, c'est une bonne idée et une expérience d'apprentissage potentielle, car un serveur de génération n'est rien de plus qu'un moyen d'exécuter arbitrairement des tâches scriptées de manière automatisée.

0
Dwight Spencer

Nous avons utilisé un peu mordu. Il est joli et s'intègre bien avec Trac, mais c'est une douleur dans le cul à personnaliser si vous avez un flux de travail non standard. De plus, il n'y a tout simplement pas autant de plugins que pour les outils les plus populaires. Actuellement, nous évaluons Hudson en remplacement.

0
Allen