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:
Java -jar hudson.war
http://localhost:8080
git
dans les préférences globales d'Hudson)nosetests
via easy_install
si ce n'est pas déjà faitnosetests --with-xunit --verbose
**/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:
nosetests --with-coverage
(ceci écrit la sortie dans **/coverage.xml
)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
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.
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.
La page cascade de Buildbot peut être considérablement améliorée. Voici un bel exemple http://build.chromium.org/buildbot/waterfall/waterfall
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
Atlassian's Bamboo vaut également le détour. L'ensemble de la suite Atlassian (JIRA, Confluence, FishEye, etc.) est plutôt agréable.
un autre: Shining Panda est un outil hébergé pour python
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).
Le signal est une autre option. Vous pouvez en savoir plus à ce sujet et regarder une vidéo également ici .
Je considérerais CircleCi - il a un grand support Python, et une très jolie sortie.
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.
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.
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.
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.