Exemplo de implementação de integração contínua usando o BuildBot

Configuração de avaliação do BuildBot
(Imagem por Computerizer por Pixabay)

Oi

Meu nome é Evgeny Cherkin , sou o programador da equipe de desenvolvimento da empresa de mineração Polymetal .

Ao iniciar qualquer projeto importante, você começa a pensar: “Qual software é melhor usar para sua manutenção?”. Um projeto de TI antes do lançamento da próxima versão passa por uma série de estágios. É bom quando a cadeia dessas etapas é automatizada. O processo automatizado de lançamento de uma nova versão de um projeto de TI é chamado de Integração Contínua . O BuildBot acabou sendo um bom ajudante para nós, implementando esse processo.

Neste artigo, decidi fornecer uma visão geral dos recursos do BuildBot . Do que esse software é capaz? Como abordá-lo e como construir um RELACIONAMENTO DE TRABALHO EFICAZ normal com ele? Você também pode aplicar nossa experiência criando em sua máquina um serviço funcional para montar e testar seu projeto.


1. Por que o BuildBot?



Anteriormente, encontrei artigos sobre a implementação da Integração Contínua usando o BuildBot . Por exemplo, este me pareceu o mais informativo. Há outro exemplo - mais simples . Esses artigos podem ser temperados com um exemplo do manual , e depois em inglês. O cupê é um bom ponto de partida. Depois de ler esses artigos, você provavelmente desejará fazer algo no BuildBot imediatamente .

Pare com isso! Alguém o usou em seus projetos? Acontece que sim, muitos o aplicaram em suas tarefas. Você pode encontrar exemplos de uso do BuildBot nos arquivos de código do Google.

Então, qual é a lógica das pessoas que usam o buildbot ? Afinal, existem outras ferramentas: CruiseControl e Jenkins . Eu vou responder dessa maneira. Para a maioria das tarefas, Jenkins realmente será suficiente. O BuildBot , por sua vez, é mais adaptável e as tarefas são resolvidas com a mesma facilidade que no Jenkins . Escolha você. Mas como estamos procurando uma ferramenta para um projeto de destino em desenvolvimento, por que não escolher a que nos permite, a partir de etapas simples, obter um sistema de compilação que tenha interatividade e uma interface exclusiva.

Para aqueles cujo projeto de destino está escrito em python, surge a pergunta: “Por que não escolher um sistema de integração que tenha uma interface clara em termos da linguagem usada no projeto?”. E então é hora de apresentar os benefícios do BuildBot .
Então, nosso "quarteto instrumental". Para mim, defini os quatro recursos do BuildBot :
  1. Esta é uma estrutura de código aberto sob a GPL
  2. Isso está usando python como uma ferramenta de configuração e descrevendo as ações necessárias.
  3. Esta é uma oportunidade para receber uma resposta da máquina na qual a montagem ocorre.
  4. Estes são finalmente os requisitos mínimos para o Host. A implantação requer python e twisted, e nenhuma máquina virtual ou máquina java é necessária.

2. Conceito liderado pelo BuildMaster



BuildBot BuildMaster

O ponto central da arquitetura de distribuição de tarefas é o BuildMaster . É um serviço que:

  • rastreia alterações na árvore de origem do projeto
  • envia os comandos que o serviço Worker deve executar para criar um projeto e testá-lo
  • notifica os usuários dos resultados das ações tomadas

O BuildMaster é configurado através do arquivo master.cfg . Este arquivo está na raiz do BuildMaster . Mais tarde mostrarei como essa raiz é criada. O próprio arquivo master.cfg contém python, um script que usa chamadas BuildBot .

O próximo BuildBot mais importante é chamado Worker . Este serviço pode ser executado em um host diferente com um sistema operacional diferente ou talvez onde o BuildMaster esteja . Também pode existir em um ambiente virtual especialmente preparado com seus próprios pacotes e variáveis. Esses ambientes virtuais podem ser preparados usando utilitários python como vertualenv, venv .

O BuildMaster transmite comandos para cada Trabalhador , que, por sua vez, os executa. Ou seja, acontece que o processo de construção e teste do projeto pode ir para o Worker no Windows e em outro Worker no linux.

A verificação do código-fonte do projeto ocorre em todos os trabalhadores .

3. Instalação



Então vamos lá. Vou usar o Ubuntu 18.04 como host. Nele colocarei um BuildMaster -a e um Worker -a. Mas primeiro você precisará instalar o python3.7:

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

Para aqueles que precisam de python3.7.2 em vez de 3.7.1, você pode fazer o seguinte:

 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 

O próximo passo é instalar o Twited e o BuildBot , além de pacotes que permitem a funcionalidade adicional do 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. Primeiros passos



Hora de criar um BuildMaster . Nós o teremos na pasta / home / habr / master .
 mkdir master buildbot create-master master #     

O próximo passo. Crie um trabalhador . Nós o teremos na pasta / home / habr / worker .
 mkdir worker buildbot-worker create-worker --umask=0o22 --keepalive=60 worker localhost:4000 yourWorkerName password 

Quando você inicia o Worker , por padrão, ele cria uma pasta em / home / habr / worker com o nome do projeto, especificado em master.cfg . E na pasta com o nome do projeto, ele criará o diretório de compilação e o checkout será feito nele. O diretório de trabalho do Worker será o diretório / home / habr / yourProject / build .

Chave de Ouro
E agora, para o que escrevi no parágrafo anterior: o script que o Master exigirá que o Worker faça remotamente neste diretório não será executado, pois o script não tem permissão para executar. Para corrigir a situação, você precisa de uma chave --umask = 0o22 , que impõe uma proibição de gravação neste diretório, mas deixa direitos de inicialização. E nós só precisamos disso.

BuildMaster e Worker estabelecem uma conexão entre si. Acontece que ele é interrompido e o Worker aguarda uma resposta do BuildMaster por algum tempo. Se nenhuma resposta for recebida, a conexão será reiniciada. A chave --keepalive = 60 é exatamente o que você precisa para indicar o tempo após o qual a conexão é reiniciada.

5. Configuração. Receita passo a passo



A configuração do BuildMaster é feita no lado da máquina, onde executamos o comando create-master . No nosso caso, este é o diretório / home / habr / master . O arquivo de configuração master.cfg ainda não existe, mas o próprio comando já criou o arquivo master.cmg.sample . Você precisa renomeá-lo em master.cfg.sample para master.cfg
 mv master.cfg.sample master.cfg 

Vamos abrir este master.cfg . E vamos analisar em que consiste. E depois disso, tentaremos criar nosso próprio arquivo de configuração.

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 - o dicionário básico do arquivo de configuração. Ele deve estar envolvido no arquivo de configuração. Para facilitar o uso, seu apelido "c" é inserido no código de configuração. Os nomes de chave em c ["keyFromDist"] são elementos fixos para interagir com o BuildMaster . Sob cada chave, o objeto correspondente é substituído como um valor.

5.2 trabalhadores


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

Desta vez, apontamos a lista de trabalhadores do BuildMaster . Criamos Worker acima especificando você-worker-name e a senha . Agora eles devem ser especificados em vez de exemplo-worker e passar .

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 a chave change_source do dicionário c , obtemos acesso à lista em que você deseja colocar o objeto que consulta o repositório com o código-fonte do projeto. O exemplo usa o repositório Git, que é pesquisado em alguma periodicidade.

O primeiro argumento é o caminho para o seu repositório.

workdir é o caminho para a pasta onde, no lado do trabalhador , em relação ao caminho / home / habr / worker / yourProject / build, o git armazenará a versão local do repositório.

branch contém uma ramificação específica no repositório que deve ser monitorada.

pollInterval contém o número de segundos após os quais o BuildMaster pesquisará o repositório em busca de alterações.

Existem vários métodos para rastrear alterações em um repositório de projeto.

O método mais fácil é Polling , o que implica que o BuildMaster realiza pesquisas periodicamente no servidor com o repositório. Se a confirmação refletiu as alterações no repositório, o BuildMaster, com algum atraso, criará um objeto Change interno e o enviará ao manipulador de eventos do Scheduler , que iniciará as etapas para criar e testar o projeto no Worker . Entre essas etapas, a atualização do repositório será indicada. É no Worker que uma cópia local do repositório será criada. Os detalhes desse processo serão divulgados abaixo nas próximas duas seções ( 5.4 e 5.5 ) .

Um método ainda mais elegante de rastrear alterações no repositório é enviar mensagens diretamente do servidor no qual está localizado ao BuildMaster sobre a alteração dos códigos-fonte do projeto. Nesse caso, assim que o desenvolvedor fizer uma confirmação , o servidor com o repositório do projeto enviará uma mensagem ao BuildMaster . E isso, por sua vez, será interceptado através da criação de um objeto PBChangeSource . Além disso, esse objeto será transferido para o Agendador , que ativa as etapas para a montagem do projeto e seus testes. Uma parte importante desse método é trabalhar com scripts de gancho do servidor no repositório. No script de gancho responsável por manipular ações durante a confirmação , você precisa chamar o utilitário sendchange e especificar o endereço de rede do BuildMaster . Você deve especificar a porta de rede que escutará o PBChangeSource . PBChangeSource , a propósito, faz parte do BuildMaster . Este método exigirá um privilégio de administrador no servidor em que o repositório do projeto está localizado. Primeiro você precisa criar um repositório de backup.

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"])) 

agendadores é um elemento que atua como um gatilho que executa toda a cadeia de montagem e teste de um projeto.
Shedulers do buildbot

Essas mudanças que foram registradas por change_source foram convertidas durante a operação do BuildBot -a no objeto Change e agora cada Sheduler baseado nelas cria solicitações para iniciar o processo de criação do projeto. No entanto, também determina quando enviar essas solicitações para a fila. Object O Builder mantém uma fila de pedidos e monitora o status da montagem atual em um Worker -e separado. O Builder existe no BuildMaster -e e Worker -e. Ele envia uma compilação específica do BuildMaster para Worker , uma série de etapas que devem ser seguidas.
Vemos que no exemplo atual de tais agendadores , 2 partes são criadas. Além disso, cada um tem seu próprio tipo.

SingleBranchScheduler é uma das classes de agendamento mais populares. Ele monitora uma ramificação e é acionado por uma alteração registrada nela. Quando ele vê as alterações, ele pode adiar o envio de uma solicitação de construção (adiar pelo período especificado no parâmetro especial treeStableTimer ). O nome especifica o nome do agendamento que será exibido na interface BuildBot -web. Um filtro é definido no ChangeFilter , depois de passar pelas alterações na ramificação que solicitam que o agendamento envie uma solicitação de construção. O nome construtor -a é especificado em builderNames , que especificaremos um pouco mais tarde. O nome no nosso caso será o mesmo que o nome do projeto: yourProject .

ForceScheduler é uma coisa muito simples. Esse tipo de agendamento é acionado por um clique do mouse na interface BuildBot -web. Os parâmetros têm a mesma essência que em SingleBranchScheduler .

PS No. 3. De repente, vem a calhar
Periódico é um planejamento que é acionado em uma frequência específica de tempo determinado. Parece uma chamada 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 define o tempo dessa periodicidade em segundos.

BuildFactory cria uma construção concreta, que o construtor envia ao Trabalhador . BuildFactory indica as etapas que um trabalhador deve seguir. As etapas são adicionadas chamando o método addStep.


A primeira etapa adicionada neste exemplo é git clean -d -f -f –x e , em seguida, git checkout . Essas ações são incorporadas no parâmetro method , que não é claramente indicado, mas implica o valor padrão de fresh . O parâmetro mode = 'incremental' indica que os arquivos do diretório em que o chechout é feito, embora ausentes no repositório, permanecem intocados.

A segunda etapa adicionada é chamar o script de avaliação com o parâmetro hello no lado Worker do diretório / home / habr / worker / yourProject / build com a variável de ambiente PATHONPATH = ... Para que você possa escrever seus próprios scripts e executá-los no lado Worker -a através da etapa util.ShellCommand . Esses scripts podem ser colocados diretamente no repositório. Depois, durante o chechout, eles irão para / home / habr / worker / yourProject / build . No entanto, existem dois "buts":
  1. O trabalhador deve ser criado com a opção --umask para que não bloqueie os direitos de execução após o checkout -a.
  2. Quando o git envia esses scripts, é necessário especificar a propriedade exacutável , para que, com chechout -e, o Git não perca o direito de executar o script.


5.6 construtores


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

Sobre o que o Builder foi descrito aqui . Agora vou falar com mais detalhes sobre como criá-lo. BuilderConfig é um construtor de construtores . Você pode especificar vários desses construtores em c ['builders'] , pois esta é uma lista de objetos do tipo construtor . Agora vamos reescrever um pouco o exemplo do BuildBot , aproximando-o da nossa tarefa.
 c['builders'] = [] c['builders'].append(util.BuilderConfig(name="yourProject", workernames=["yourWorkerName"], factory=factory)) 

Agora vou falar sobre os parâmetros BuilderConfig .

nome define o construtor de nomes -a. Aqui chamamos de seu projeto . Isso significa que no Worker esse mesmo caminho / home / habr / worker / yourProject / build será criado. Sheduler procura um construtor com esse nome.

nomes de trabalho contém uma lista de trabalhadores . Cada um dos quais deve ser adicionado a c ['trabalhadores'] .

factory é a construção específica à qual o construtor está associado. Ele enviará um objeto de construção ao Worker para concluir todas as etapas que compõem essa construção -a.

6. Exemplo de configuração própria



Aqui está um exemplo de arquitetura de projeto que proponho implementar através do BuildBot
.

Usaremos o svn como um sistema de controle de versão. O próprio repositório estará em uma determinada nuvem. Aqui está o endereço dessa nuvem svn.host/svn/yourProject/trunk . Na nuvem em svn, existe um nome de usuário : user , passwd: password account. Os scripts que são as etapas de construção -a também estarão no ramo svn , em uma pasta buildbot / worker_linux separada. Esses scripts estão no repositório com a propriedade executável salva.

BuildMaster e Worker trabalham no mesmo host project.host . O BuildMaster armazena seus arquivos na pasta / home / habr / master . Worker armazena o seguinte caminho / home / habr / worker . A comunicação entre os processos BuildMaster e Worker é realizada através da porta 4000 usando o protocolo BuildBot -a, ou seja, o protocolo 'pb' .

O projeto de destino é inteiramente escrito em python. A tarefa é rastrear suas alterações, criar um arquivo executável, gerar documentação, realizar testes. Em caso de falha, todos os desenvolvedores precisam enviar uma mensagem para o e-mail informando que há uma ação com falha.

Vamos conectar o mapeamento da Web BuildBot à porta 80 para project.host . O Apatch é opcional. A biblioteca distorcida já possui um servidor web, o BuildBot a utiliza.

Usaremos o sqlite para armazenar informações internas para o BuildBot .

Para enviar correio, você precisa do host smtp.seu.domínio - ele permite enviar e-mails de projectHost@seu.domínio sem autenticação. Também no host ' smtp ', o protocolo é escutado em 1025.

Há duas pessoas envolvidas no processo: administrador e usuário . admin administra o BuildBot . usuário é a pessoa que confirma o commit .

Um arquivo exacutável é gerado através do pyinstaller . A documentação é gerada através do doxygen .

Para esta arquitetura, escrevi 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" } 


Primeiro você precisa criar BuildMaster e Worker -a. Em seguida, cole este arquivo master.cfg em / home / habr / master .

O próximo passo é iniciar o serviço BuildMaster
 sudo buildbot start /home/habr/master 

Em seguida, inicie o serviço Worker-a
 buildbot-worker start /home/habr/worker 

Feito! Agora o Buildbot rastreia as alterações e executa no commit no svn , seguindo as etapas de criação e teste do projeto com a arquitetura acima.

Abaixo, descreverei alguns recursos do master.cfg acima .


6.1 A caminho do seu master.cfg


Ao escrever seu master.cfg, muitos erros serão cometidos; portanto, você precisará ler o arquivo de log. Ele é armazenado no caminho absoluto BuildMaster -ec /home/habr/master/twistd.log e no lado Worker-a com o caminho absoluto /home/habr/worker/twistd.log . Ao ler o erro e corrigi-lo, você precisará reiniciar o serviço BuildMaster -a. Veja como fazê-lo:
 sudo buildbot stop /home/habr/master sudo buildbot upgrade-master /home/habr/master sudo buildbot start /home/habr/master 

6.2 Trabalhar com 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) 

Primeiro, dê uma olhada no svn_poller . Essa é a mesma interface que consulta regularmente o repositório uma vez por minuto. Nesse caso, svn_poller acessa apenas a ramificação do tronco . O misterioso parâmetro split_file = util.svn.split_file_alwaystrunk define as regras: como dividir a estrutura das pastas svn em ramificações. Ele lhes oferece maneiras relativas. Por sua vez, split_file_alwaystrunk simplifica o processo dizendo que apenas o tronco está no repositório.

Nos Agendadores , o ChangeFilter é especificado , que vê None e associa a ramificação do tronco a ela de acordo com a associação especificada por meio de split_file_alwaystrunk . Respondendo a alterações no tronco , inicia o construtor chamado yourProject .

aqui as propriedades são necessárias para que o administrador receba o boletim da montagem e teste os resultados como o proprietário do processo.

A etapa build -a checkout é capaz de excluir completamente todos os arquivos que estão na versão local do repositório Worker . A então faça a atualização completa do svn . O modo é configurado através do parâmetro mode = full , method = fresh . O parâmetro haltOnTailure indica que, se o svn update não for bem - sucedido , todo o processo de montagem e teste deverá ser suspenso, pois etapas adicionais não fazem sentido.

6.3 Uma carta para você: os repórteres estão autorizados a declarar


repórteres é um serviço de notificação por correio.
 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] 

Pode enviar mensagens de várias maneiras .

MailNotifier usa email para enviar notificações.

template_html define o modelo de texto para o boletim. Para criar marcação, use html. É modificado pelo mecanismo jinja2 (pode ser comparado com o django ). O BuildBot possui um conjunto de variáveis, cujos valores são substituídos no modelo no processo de formação do texto da mensagem. Essas variáveis ​​são inscritas em {{double curly chaves}}. Assim, por exemplo, o resumo exibe o status das operações concluídas, ou seja, sucesso ou falha. E os projetos produzirão o seu projeto . Portanto, usando comandos de controle no jinja2 , variáveis BuildBot e formatadores de string python, você pode criar uma mensagem muito informativa.

MailNotifier contém os seguintes argumentos.

fromaddr - o endereço do qual todos receberão o boletim.

sendToInterestedUsers = True envia uma mensagem ao proprietário e usuário que efetuou a confirmação .

lookup - sufixo a ser adicionado aos nomes dos usuários que recebem o boletim. Portanto, o administrador como usuário receberá a newsletter em admin@seu.domínio.

relayhost especifica o nome do host no qual o servidor smtp está aberto e smptPort especifica o número da porta na qual o servidor smtp atende.

mode = "warning" diz que a correspondência deve ser feita apenas se houver pelo menos uma etapa de construção que terminou com falha ou status de aviso. Em caso de sucesso, a correspondência não é necessária.

extraRecipients contém uma lista de indivíduos para quem a correspondência deve ser feita, além do proprietário e da pessoa que fez o commit .

messageFormatter é um objeto que define o formato da mensagem, seu modelo e o conjunto de variáveis ​​disponíveis no jinja2 . Parâmetros como wantProperties = True e wantSteps = True especificam este conjunto de variáveis ​​disponíveis.

with ['services'] = [sendMessageToAll] fornece uma lista de serviços, entre os quais estarão nossosrepórter .

Nós conseguimos! Meus parabéns



Criamos nossa própria configuração e vimos a funcionalidade que o BuildBot é capaz . Acho que isso é suficiente para entender se essa ferramenta é necessária para criar seu projeto. Ele é interessante para você? Será útil para você? É conveniente trabalhar? Então escrevo este artigo por um bom motivo.

E mais uma coisa.Gostaria que a comunidade profissional usando o BuildBot se tornasse mais ampla, os manuais sejam traduzidos e há ainda mais exemplos.

Obrigado a todos pela atenção. Boa sorte

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


All Articles