Ejemplo de implementación de integración continua con BuildBot

Configuración de prueba de BuildBot
(Imagen de Computerizer de Pixabay)

Hola

Mi nombre es Evgeny Cherkin , soy el programador del equipo de desarrollo de la empresa minera Polymetal .

Al comenzar cualquier proyecto importante, comienza a pensar: "¿Qué software es mejor usar para su mantenimiento?". Un proyecto de TI antes del lanzamiento de la próxima versión pasa por una serie de etapas. Es bueno cuando la cadena de estos pasos está automatizada. El proceso automatizado de lanzamiento de una nueva versión de un proyecto de TI se llama Integración continua . BuildBot resultó ser un buen ayudante para nosotros, implementando este proceso.

En este artículo, decidí proporcionar una descripción general de las características de BuildBot . ¿De qué es capaz este software? ¿Cómo acercarse a él y cómo construir una RELACIÓN DE TRABAJO EFECTIVA normal con él? También puede aplicar nuestra experiencia a usted mismo creando en su máquina un servicio de trabajo para ensamblar y probar su proyecto.


1. ¿Por qué es BuildBot?



Anteriormente en habr-e, me encontré con artículos sobre la implementación de la integración continua usando BuildBot . Por ejemplo, este me pareció el más informativo. Hay otro ejemplo, más simple . Estos artículos pueden ser sazonados con un ejemplo del manual , y esto es después, en inglés. El coupé es un buen punto de partida. Después de leer estos artículos, probablemente querrá hacer algo en BuildBot de inmediato .

Basta! ¿Alguien lo usó en sus proyectos? Resulta que sí, muchos lo han aplicado en sus tareas. Puede encontrar ejemplos de uso de BuildBot en los archivos de código de Google.

Entonces, ¿cuál es la lógica de las personas que usan buildbot ? Después de todo, hay otras herramientas: CruiseControl y Jenkins . Contestaré de esta manera. Para la mayoría de las tareas, Jenkins realmente será suficiente. BuildBot , a su vez, es más adaptable y las tareas allí se resuelven tan fácilmente como en Jenkins . Elígete a ti. Pero como estamos buscando una herramienta para un proyecto objetivo en desarrollo, ¿por qué no elegir la que nos permite, a partir de simples pasos, obtener un sistema de compilación que tenga interactividad y una interfaz única?

Para aquellos cuyo proyecto objetivo está escrito en python, surge la pregunta: "¿Por qué no elegir un sistema de integración que tenga una interfaz clara en términos del lenguaje utilizado en el proyecto?". Y luego es hora de presentar los beneficios de BuildBot .
Entonces, nuestro "cuarteto instrumental". Para mí, definí las cuatro características de BuildBot :
  1. Este es un marco de código abierto bajo la GPL
  2. Esto utiliza Python como herramienta de configuración y describe las acciones requeridas.
  3. Esta es una oportunidad para recibir una respuesta de la máquina en la que se realiza el montaje.
  4. Estos son finalmente los requisitos mínimos para el Host. La implementación requiere Python y Twisted, y no se requiere una máquina virtual o Java.

2. Concepto liderado por BuildMaster



BuildBot BuildMaster

El centro de la arquitectura de distribución de tareas es BuildMaster . Es un servicio que:

  • realiza un seguimiento de los cambios en el árbol fuente del proyecto
  • envía los comandos que el servicio Worker debería ejecutar para construir un proyecto y probarlo
  • notifica a los usuarios los resultados de las acciones tomadas

BuildMaster se configura a través del archivo master.cfg . Este archivo está en la raíz de BuildMaster . Más adelante mostraré cómo se crea esta raíz. El archivo master.cfg en sí contiene python, un script que usa llamadas BuildBot .

El siguiente BuildBot más importante se llama Worker . Este servicio se puede ejecutar en un host diferente con un sistema operativo diferente, o tal vez en donde está BuildMaster . También puede existir en un entorno virtual especialmente preparado con sus propios paquetes y variables. Estos entornos virtuales se pueden preparar utilizando utilidades de python como vertualenv, venv .

BuildMaster transmite comandos a cada trabajador , que, a su vez, los ejecuta. Es decir, resulta que el proceso de compilación y prueba del proyecto puede ir al Trabajador en Windows y en otro Trabajador en Linux.

El pago del código fuente del proyecto ocurre en cada trabajador .

3. Instalación



Entonces vamos. Usaré Ubuntu 18.04 como el host. En él colocaré un BuildMaster -a y un Worker -a. Pero primero necesitará instalar python3.7:

sudo apt-get update sudo apt-get install python3.7 

Para aquellos que necesitan python3.7.2 en lugar de 3.7.1, pueden hacer lo siguiente:

 sudo apt-get update sudo apt-get software-properties-common sudo add-apt-repository ppa:deadsnakes/ppa sudo apt-get install python3.7 sudo ln -fs /usr/bin/python3.7 /usr/bin/python3 pip3 install --upgrade pip 

El siguiente paso es instalar Twited y BuildBot , así como paquetes que permitan la funcionalidad adicional BuildBot -a.

 /*   sudo        /usr/local/lib/python3.7/dist-packages*/ #     Worker- sudo pip install twisted # twisted sudo pip install buildbot #BuildMaster #  pip install pysqlite3 #  sqllite    pip install jinja2 #framework  django,  web     pip install autobahn #Web c   BuildMaster->Worker pip install sqlalchemy sqlalchemy-migrate #     # Web  BuildBot-a pip install buildbot-www buildbot-grid-view buildbot-console-view buildbot-waterfall-view pip install python-dateutil #   web #         pip install buildbot-worker #Worker #  sudo pip install virtualenv #  

4. Primeros pasos



Es hora de crear un BuildMaster . Lo tendremos en la carpeta / home / habr / master .
 mkdir master buildbot create-master master #     

El proximo paso. Crea un trabajador . Lo tendremos en la carpeta / home / habr / worker .
 mkdir worker buildbot-worker create-worker --umask=0o22 --keepalive=60 worker localhost:4000 yourWorkerName password 

Cuando inicia Worker , de manera predeterminada creará una carpeta en / home / habr / worker con el nombre del proyecto, que se especifica en master.cfg . Y en la carpeta con el nombre del proyecto, creará el directorio de compilación y luego se realizará el pago . El directorio de trabajo para Worker será el directorio / home / habr / yourProject / build .

Llave de oro
Y ahora, para lo que escribí en el párrafo anterior: el script que Master requerirá que Worker haga de forma remota en este directorio no se ejecutará, ya que el script no tiene permiso para ejecutarse. Para solucionar la situación, necesitas una llave --umask = 0o22 , que impone una prohibición de escritura en este directorio, pero deja derechos de inicio. Y solo necesitamos esto.

BuildMaster y Worker establecen una conexión entre ellos. Sucede que se interrumpe y Worker espera una respuesta de BuildMaster por algún tiempo. Si no se recibe respuesta, la conexión se reinicia. La clave --keepalive = 60 es justo lo que necesita para indicar el tiempo después del cual se reinicia la conexión .

5. Configuración. Receta paso a paso



La configuración de BuildMaster se realiza en el lado de la máquina, donde ejecutamos el comando create-master . En nuestro caso, este es el directorio / home / habr / master . El archivo de configuración master.cfg aún no existe, pero el comando en sí ya ha creado el archivo master.cmg.sample . Debe cambiarle el nombre en master.cfg.sample a master.cfg
 mv master.cfg.sample master.cfg 

Abramos este master.cfg . Y analizaremos en qué consiste. Y después de eso intentaremos crear nuestro propio archivo de configuración.

master.cfg
 c['change_source'] = [] c['change_source'].append(changes.GitPoller( 'git://github.com/buildbot/hello-world.git', workdir='gitpoller-workdir', branch='master', pollInterval=300)) c['schedulers'] = [] c['schedulers'].append(schedulers.SingleBranchScheduler( name="all", change_filter=util.ChangeFilter(branch='master'), treeStableTimer=None, builderNames=["runtests"])) c['schedulers'].append(schedulers.ForceScheduler( name="force", builderNames=["runtests"])) factory = util.BuildFactory() factory.addStep(steps.Git(repourl='git://github.com/buildbot/hello-world.git', mode='incremental')) factory.addStep(steps.ShellCommand(command=["trial", "hello"], env={"PYTHONPATH": "."})) c['builders'] = [] c['builders'].append( util.BuilderConfig(name="runtests", workernames=["example-worker"], factory=factory)) c['services'] = [] c['title'] = "Hello World CI" c['titleURL'] = "https://buildbot.imtqy.com/hello-world/" c['buildbotURL'] = "http://localhost:8010/" c['www'] = dict(port=8010, plugins=dict(waterfall_view={}, console_view={}, grid_view={})) c['db'] = { 'db_url' : "sqlite:///state.sqlite", } 


5.1 BuildmasterConfig


 c = BuildmasterConfig = {} 

BuildmasterConfig : el diccionario básico del archivo de configuración. Debe estar involucrado en el archivo de configuración. Para facilitar su uso, su alias "c" se ingresa en el código de configuración. Los nombres clave en c ["keyFromDist"] son elementos fijos para interactuar con BuildMaster . Debajo de cada clave, el objeto correspondiente se sustituye como un valor.

5.2 trabajadores


 c['workers'] = [worker.Worker("example-worker", "pass")] 

Esta vez señalamos la lista de trabajadores de BuildMaster . Creamos Worker arriba especificando su nombre de trabajador y contraseña . Ahora deben especificarse en lugar de ejemplo-trabajador y pasar .

5.3 change_source


 c['change_source'] = [] c['change_source'].append(changes.GitPoller( 'git://github.com/buildbot/hello-world.git', workdir='gitpoller-workdir', branch='master', pollInterval=300)) 

Usando la clave change_source del diccionario c , tenemos acceso a la lista donde desea colocar el objeto que sondea el repositorio con el código fuente del proyecto. El ejemplo utiliza el repositorio de Git, que se sondea con cierta periodicidad.

El primer argumento es el camino a su repositorio.

workdir es la ruta a la carpeta donde, en el lado del trabajador , en relación con la ruta / home / habr / worker / yourProject / build, git almacenará la versión local del repositorio.

La rama contiene una rama específica en el repositorio que debe ser monitoreada.

pollInterval contiene el número de segundos después de los cuales BuildMaster sondeará los cambios en el repositorio.

Existen varios métodos para rastrear los cambios en un repositorio de proyectos.

El método más fácil es el sondeo , lo que implica que BuildMaster sondea periódicamente el servidor con el repositorio. Si commit refleja los cambios en el repositorio, BuildMaster con cierto retraso creará un objeto de cambio interno y lo enviará al controlador de eventos del Programador , que comenzará los pasos para compilar y probar el proyecto en Worker . Entre estos pasos, se indicará la actualización del repositorio. Es en Worker donde se creará una copia local del repositorio. Los detalles de este proceso se divulgarán a continuación en las siguientes dos secciones ( 5.4 y 5.5 ) .

Un método aún más elegante para rastrear los cambios en el repositorio es enviar mensajes directamente desde el servidor en el que está ubicado a BuildMaster para cambiar los códigos fuente del proyecto. En este caso, tan pronto como el desarrollador realice una confirmación , el servidor con el repositorio del proyecto enviará un mensaje a BuildMaster . Y eso, a su vez, será interceptado creando un objeto PBChangeSource . Además, este objeto se transferirá al Programador , que activa los pasos para el ensamblaje del proyecto y su prueba. Una parte importante de este método es trabajar con scripts de enlace de servidor en el repositorio. En el script de enlace responsable de manejar las acciones durante la confirmación , debe llamar a la utilidad sendchange y especificar la dirección de red de BuildMaster . Debe especificar el puerto de red que escuchará PBChangeSource . PBChangeSource , por cierto, es parte de BuildMaster . Este método requerirá privilegios de administrador -a en el servidor donde se encuentra el repositorio del proyecto. Primero necesitas hacer un repositorio de respaldo.

5.4 shedulers


 c['schedulers'] = [] c['schedulers'].append(schedulers.SingleBranchScheduler( name="all", change_filter=util.ChangeFilter(branch='master'), treeStableTimer=None, builderNames=["runtests"])) c['schedulers'].append(schedulers.ForceScheduler( name="force", builderNames=["runtests"])) 

Los planificadores son un elemento que actúa como un disparador que ejecuta toda la cadena de ensamblaje y prueba de un proyecto.
Buildbot shedulers

Esos cambios que fueron registrados por change_source se convirtieron durante la operación de BuildBot -a en el objeto Change y ahora cada Sheduler basado en ellos crea solicitudes para comenzar el proceso de construcción del proyecto. Sin embargo, también determina cuándo enviar estas solicitudes a la cola. Objeto Builder mantiene una cola de solicitudes y monitorea el estado del ensamblaje actual en un Worker -e separado. El generador existe tanto en BuildMaster -e como en Worker -e. Envía una compilación específica de BuildMaster a Worker , una serie de pasos que deben seguirse.
Vemos que en el ejemplo actual de tales programadores , se crean 2 piezas. Además, cada uno tiene su propio tipo.

SingleBranchScheduler es una de las clases de programación más populares. Monitorea una rama y se activa por un cambio registrado en ella. Cuando ve los cambios, puede posponer el envío de una solicitud de construcción (posponer para el período especificado en el parámetro especial treeStableTimer ). El nombre especifica el nombre de la programación que se mostrará en la interfaz BuildBot -web. Se establece un filtro en ChangeFilter , después de pasar por qué cambios en la rama solicitan la programación para enviar una solicitud de compilación. El nombre constructor -a se especifica en builderNames , que especificaremos un poco más adelante. El nombre en nuestro caso será el mismo que el nombre del proyecto: yourProject .

ForceScheduler es una cosa muy simple. Este tipo de programación se activa con un clic del mouse a través de la interfaz BuildBot -web. Los parámetros tienen la misma esencia que en SingleBranchScheduler .

PS No. 3. De repente es útil
Periódico es un cronograma que se activa a una frecuencia específica de tiempo fijo. Parece una llamada como esta
 from buildbot.plugins import schedulers nightly = schedulers.Periodic(name="daily", builderNames=["full-solaris"], periodicBuildTimer=24*60*60) c['schedulers'] = [nightly] 

5.5 BuildFactory


 factory = util.BuildFactory() factory.addStep(steps.Git(repourl='git://github.com/buildbot/hello-world.git', mode='incremental')) factory.addStep(steps.ShellCommand(command=["trial", "hello"], env={"PYTHONPATH": "."})) 

periodicBuildTimer establece el tiempo de esta periodicidad en segundos.

BuildFactory crea una construcción concreta, que el constructor luego envía al Trabajador . BuildFactory indica los pasos que debe seguir un trabajador . Los pasos se agregan llamando al método addStep.


El primer paso agregado en este ejemplo es git clean -d -f -f –x , luego git checkout . Estas acciones están integradas en el parámetro del método , que no se indica claramente, pero implica el valor predeterminado de fresh . El parámetro mode = 'incremental' indica que los archivos del directorio donde se realiza el chechout , aunque faltan en el repositorio, permanecen intactos.

El segundo paso agregado es llamar al script de prueba con el parámetro hello en el lado Worker desde el directorio / home / habr / worker / yourProject / build con la variable de entorno PATHONPATH = ... Para que pueda escribir sus propios scripts y ejecutarlos en el lado Worker -a a través del paso util.ShellCommand . Estas secuencias de comandos se pueden colocar directamente en el repositorio. Luego, durante el chechout , irán a / home / habr / worker / yourProject / build . Sin embargo, hay dos "peros":
  1. El trabajador debe crearse con el modificador --umask para que no bloquee los derechos de ejecución después del pago -a.
  2. Cuando git empuja estos scripts, es necesario especificar la propiedad ejecutable , de modo que con chechout -e Git no pierda el derecho de ejecutar el script.


5.6 constructores


 c['builders'] = [] c['builders'].append(util.BuilderConfig(name="runtests", workernames=["example-worker"], factory=factory)) 

Sobre lo que Builder fue descrito aquí . Ahora hablaré con más detalle sobre cómo crearlo. BuilderConfig es un constructor de constructores . Puede especificar varios constructores de este tipo en c ['constructores'] , ya que esta es una lista de objetos de tipo constructor . Ahora reescribiremos ligeramente el ejemplo de BuildBot , acercándolo a nuestra tarea.
 c['builders'] = [] c['builders'].append(util.BuilderConfig(name="yourProject", workernames=["yourWorkerName"], factory=factory)) 

Ahora contaré sobre los parámetros BuilderConfig .

nombre establece el generador de nombres -a. Aquí lo llamamos yourProject . Esto significa que en el Worker se creará esta ruta / home / habr / worker / yourProject / build . Sheduler busca un constructor con ese nombre.

nombres de trabajadores contiene una lista de trabajadores . Cada uno de los cuales debe agregarse a c ['trabajadores'] .

factory es la compilación específica con la que está asociado el constructor . Enviará un objeto de compilación a Worker para completar todos los pasos que componen esta compilación -a.

6. Ejemplo de configuración propia



Aquí está la arquitectura de un proyecto de muestra que propongo implementar a través de BuildBot
.

Usaremos svn como sistema de control de versiones. El repositorio en sí estará en una determinada nube. Aquí está la dirección de esta nube svn.host/svn/yourProject/trunk . En la nube debajo de svn hay un nombre de usuario : usuario , contraseña : cuenta de contraseña . Las secuencias de comandos que son los pasos build -a también se ubicarán en la rama svn , en una carpeta buildbot / worker_linux separada. Estas secuencias de comandos están en el repositorio con la propiedad ejecutable guardada.

BuildMaster y Worker trabajan en el mismo host project.host . BuildMaster almacena sus archivos en la carpeta / home / habr / master . El trabajador almacena la siguiente ruta / hogar / habr / trabajador . La comunicación entre los procesos BuildMaster y Worker se realiza a través del puerto 4000 utilizando el protocolo BuildBot -a, es decir, el protocolo 'pb' .

El proyecto de destino está completamente escrito en python. La tarea es rastrear sus cambios, crear un archivo ejecutable, generar documentación, realizar pruebas. En caso de falla, todos los desarrolladores deben enviar un mensaje al correo de que hay una acción fallida.

Conectaremos el mapeo web BuildBot al puerto 80 para project.host . Apatch es opcional. La biblioteca retorcida ya tiene un servidor web, BuildBot lo usa.

Usaremos sqlite para almacenar información interna para BuildBot .

Para enviar por correo, necesita el host smtp.your.domain , que permite enviar correos electrónicos desde projectHost@your.domain sin autenticación. También en el host ' smtp ' se escucha el protocolo en 1025.

Hay dos personas involucradas en el proceso: administrador y usuario . admin administra BuildBot . usuario es la persona que comete el compromiso .

Se genera un archivo ejecutable a través de pyinstaller . La documentación se genera a través de doxygen .

Para esta arquitectura, escribí este master.cfg :

master.cfg
 import os, re from buildbot.plugins import steps, util, schedulers, worker, changes, reporters c= BuildmasterConfig ={} c['workers'] = [ worker.Worker('yourWorkerName', 'password') ] c['protocols'] = {'pb': {'port': 4000}} svn_poller = changes.SVNPoller(repourl="https://svn.host/svn/yourProject/trunk", svnuser="user", svnpasswd="password", pollinterval=60, split_file=util.svn.split_file_alwaystrunk ) c['change_source'] = svn_poller hourlyscheduler = schedulers.SingleBranchScheduler( name="your-project-schedulers", change_filter=util.ChangeFilter(branch=None), builderNames=["yourProject"], properties = {'owner': 'admin'} ) c['schedulers'] = [hourlyscheduler] checkout = steps.SVN(repourl='https://svn.host/svn/yourProject/trunk', mode='full', method='fresh', username="user", password="password", haltOnFailure=True) projectHost_build = util.BuildFactory() cleanProject = steps.ShellCommand(name="Clean", command=["buildbot/worker_linux/pyinstaller_project", "clean"] ) buildProject = steps.ShellCommand(name="Build", command=["buildbot/worker_linux/pyinstaller_project", "build"] ) doxyProject = steps.ShellCommand(name="Update Docs", command=["buildbot/worker_linux/gendoc", []] ) testProject = steps.ShellCommand(name="Tests", command=["python","tests/utest.py"], env={'PYTHONPATH': '.'} ) projectHost_build.addStep(checkout) projectHost_build.addStep(cleanProject) projectHost_build.addStep(buildProject) projectHost_build.addStep(doxyProject) projectHost_build.addStep(testProject) c['builders'] = [ util.BuilderConfig(name="yourProject", workername='yourWorkerName', factory=projectHost_build) ] template_html=u'''\ <h4>  : {{ summary }}</h4> <p>   : {{ workername }}</p> <p>: {{ projects }}</p> <p>         : {{ buildbot_url }}</p> <p>         : {{ build_url }}</p> <p> WinSCP     c ip:xxx.xx.xxx.xx.   habr/password,   executable    ~/worker/yourProject/build/dist.</p> <p><b>    Buildbot</b></p> ''' sendMessageToAll = reporters.MailNotifier(fromaddr="projectHost@your.domain", sendToInterestedUsers=True, lookup="your.domain", relayhost="smtp.your.domain", smtpPort=1025, mode="warnings", extraRecipients=['user@your.domain'], messageFormatter=reporters.MessageFormatter( template=template_html, template_type='html', wantProperties=True, wantSteps=True) ) c['services'] = [sendMessageToAll] c['title'] = "The process of bulding" c['titleURL'] = "http://project.host:80/" c['buildbotURL'] = "http://project.host" c['www'] = dict(port=80, plugins=dict(waterfall_view={}, console_view={}, grid_view={})) c['db'] = { 'db_url' : "sqlite:///state.sqlite" } 


Primero necesitas crear BuildMaster y Worker -a. Luego pegue este archivo master.cfg en / home / habr / master .

El siguiente paso es iniciar el servicio BuildMaster
 sudo buildbot start /home/habr/master 

Luego inicie el trabajador -un servicio
 buildbot-worker start /home/habr/worker 

Hecho Ahora Buildbot hará un seguimiento de los cambios y se ejecutará en commit en svn , siguiendo los pasos de compilación y prueba del proyecto con la arquitectura anterior.

A continuación, describiré algunas características del master.cfg anterior .


6.1 En el camino a tu master.cfg


Mientras escribe su master.cfg, se cometerán muchos errores, por lo que deberá leer el archivo de registro. Se almacena tanto en la ruta absoluta BuildMaster -ec /home/habr/master/twistd.log como en el lado Worker -a con la ruta absoluta /home/habr/worker/twistd.log . A medida que lea el error y lo corrija, deberá reiniciar el servicio BuildMaster -a. Aquí se explica cómo hacerlo:
 sudo buildbot stop /home/habr/master sudo buildbot upgrade-master /home/habr/master sudo buildbot start /home/habr/master 

6.2 Trabajar con svn


 svn_poller = changes.SVNPoller(repourl="https://svn.host/svn/yourProject/trunk", svnuser="user", svnpasswd="password", pollinterval=60, split_file=util.svn.split_file_alwaystrunk ) c['change_source'] = svn_poller hourlyscheduler = schedulers.SingleBranchScheduler( name="your-project-schedulers", change_filter=util.ChangeFilter(branch=None), builderNames=["yourProject"], properties = {'owner': 'admin'} ) c['schedulers'] = [hourlyscheduler] checkout = steps.SVN(repourl='https://svn.host/svn/yourProject/trunk', mode='full', method='fresh', username="user", password="password", haltOnFailure=True) 

Primero, eche un vistazo a svn_poller . Esta es la misma interfaz que sondea regularmente el repositorio una vez por minuto. En este caso, svn_poller solo accede a la rama troncal . El misterioso parámetro split_file = util.svn.split_file_alwaystrunk establece las reglas: cómo dividir la estructura de las carpetas svn en ramas. Les ofrece formas relativas. A su vez, split_file_alwaystrunk simplifica el proceso al decir que solo el enlace troncal está en el repositorio.

En Schedulers , se especifica ChangeFilter , que ve None y asocia la rama troncal de acuerdo con la asociación especificada a través de split_file_alwaystrunk . Respondiendo a los cambios en el tronco , inicia el generador llamado yourProject .

Aquí se necesitan propiedades para que el administrador reciba el boletín del ensamblaje y los resultados de las pruebas como propietario del proceso.

El paso build -a checkout es capaz de eliminar completamente cualquier archivo que se encuentre en la versión local del repositorio de Worker . A luego haga la actualización completa de svn . El modo se configura a través del parámetro mode = full , method = fresh . El parámetro haltOnTailure indica que si la actualización de svn no tiene éxito , entonces se debe suspender todo el proceso de ensamblaje y prueba, ya que los pasos adicionales no tienen sentido.

6.3 Una carta para usted: los periodistas están autorizados a declarar


Reporteros es un servicio de notificación por correo.
 template_html=u'''\ <h4>  : {{ summary }}</h4> <p>   : {{ workername }}</p> <p>: {{ projects }}</p> <p>         : {{ buildbot_url }}</p> <p>         : {{ build_url }}</p> <p> WinSCP     c ip:xxx.xx.xxx.xx.   habr/password,   executable    ~/worker/yourProject/build/dist.</p> <p><b>    Buildbot</b></p> ''' sendMessageToAll = reporters.MailNotifier(fromaddr="projectHost@your.domain", sendToInterestedUsers=True, lookup="your.domain", relayhost="smtp.your.domain", smtpPort=1025, mode="warnings", extraRecipients=['user@your.domain'], messageFormatter=reporters.MessageFormatter( template=template_html, template_type='html', wantProperties=True, wantSteps=True) ) c['services'] = [sendMessageToAll] 

Puede enviar mensajes de muchas maneras .

MailNotifier usa el correo para enviar notificaciones.

template_html establece la plantilla de texto para el boletín. Para crear marcas, use html. Está modificado por el motor jinja2 (se puede comparar con django ). BuildBot tiene un conjunto de variables, cuyos valores se sustituyen en la plantilla en el proceso de formar el texto del mensaje. Estas variables están inscritas en {{llaves dobles "}. Entonces, por ejemplo, el resumen muestra el estado de las operaciones completadas, es decir, éxito o fracaso. Y los proyectos generarán su proyecto . Entonces, usando comandos de control en jinja2 , variables BuildBot y formateadores de cadenas de python, puede crear un mensaje muy informativo.

MailNotifier contiene los siguientes argumentos.

fromaddr : la dirección desde la cual todos recibirán el boletín.

sendToInterestedUsers = True envía un mensaje al propietario y al usuario que realizó la confirmación .

búsqueda : sufijo que se agregará a los nombres de los usuarios que reciben el boletín. Por lo tanto, admin como usuario recibirá el boletín en admin@your.domain.

relayhost especifica el nombre de host en el que está abierto el servidor smtp , y smptPort especifica el número de puerto en el que escucha el servidor smtp .

mode = "warning" dice que el envío de correos debe hacerse solo si hay al menos un paso de compilación que haya finalizado con un estado de falla o advertencia. En caso de éxito, no se requiere correo.

extraRecipients contiene una lista de las personas a las que se debe enviar el correo además del propietario y la persona que realizó el compromiso .

messageFormatter es un objeto que define el formato del mensaje, su plantilla y el conjunto de variables disponibles en jinja2 . Parámetros como wantProperties = True y wantSteps = True especifican este conjunto de variables disponibles.

with ['services'] = [sendMessageToAll] proporciona una lista de servicios, entre los cuales estará nuestroreportero .

Lo hicimos! Mis felicitaciones



Creamos nuestra propia configuración y vimos la funcionalidad que BuildBot es capaz de hacer . Esto, creo, es suficiente para entender si esta herramienta es necesaria para crear su proyecto. ¿Es interesante para ti? ¿Te será útil? ¿Es conveniente trabajar con ellos? Entonces escribo este artículo por una buena razón.

Y una cosa más.Me gustaría que la comunidad profesional que usa BuildBot sea ​​más amplia, traduzca manuales y más ejemplos.

Gracias a todos por su atención. Buena suerte

Source: https://habr.com/ru/post/460501/


All Articles