
(Imagem de Harvard University
Olá!
Meu nome é Evgeny Cherkin, eu sou programador da equipe de desenvolvedores de uma empresa de mineração Polymetal.
Ao iniciar qualquer grande projeto, você começa a se perguntar: 'Qual software é melhor utilizar para gerenciá-lo?'. Um projeto de TI passa por várias etapas antes do lançamento de uma nova versão. É ótimo quando a cadeia dessas etapas é automatizada. O próprio processo automatizado de lançamento de uma nova versão de um projeto de TI é chamado de Continuous Integration. BuildBot que se mostrou um bom aliado, implementando esse processo.
Neste artigo, decidi apresentar uma visão geral das capacidades BuildBot. O que esse software pode fazer? Como abordá-lo e como estabelecer um RELACIONAMENTO DE TRABALHO EFETIVO com ele? Você pode aplicar nossa experiência e criar, em sua máquina, um serviço de construção e teste do seu projeto.
Conteúdo
Conteúdo
1. Por que BuildBot?
Anteriormente no habr-e, encontrei artigos sobre a implementação Continuous Integration usando BuildBot. Por exemplo, me pareceu o mais informativo. Há outro exemplo — . Esses artigos podem ser complementados , e também em inglês. No conjunto, isso resulta em um bom ponto de partida. Depois de ler esses artigos, você certamente já vai querer fazer algo em BuildBot .
Pare! Alguém já o usou em seus projetos? Ao que parece, sim, eles o aplicaram em suas tarefas. Você pode encontrá-lo uso BuildBot nos arquivos de códigos do Google.
Então, qual é a lógica das pessoas que utilizam Buildbot? Ведь есть другие инструменты: CruiseControl e Jenkins. Respondendo de forma direta, para a maioria das tarefas Jenkins será realmente suficiente. Por outro lado, BuildBot é mais adaptável, e as tarefas lá são resolvidas tão facilmente quanto em Jenkins. A escolha é sua. Mas já que estamos buscando uma ferramenta para um projeto em desenvolvimento, por que não escolher aquela que permitirá, a partir de passos simples, obter um sistema de construção que tenha interatividade e uma interface única.
Para aqueles cujo projeto alvo é escrito em python, surge a pergunta: "Por que não escolher um sistema de integração que tenha uma interface clara do ponto de vista da linguagem utilizada no projeto?". E aqui é o momento certo para apresentar as vantagens. BuildBot.
Assim, nosso "quarteto instrumental". Para mim, defini um conjunto de quatro características. BuildBot:
- É um framework open source sob a licença GPL.
- É o uso do python como ferramenta de configuração e descrição das ações necessárias.
- É a possibilidade de obter uma resposta da máquina onde a construção está ocorrendo.
- Por fim, há requisitos mínimos para o Host. Para a implementação, são necessários python e twisted; não é necessária uma máquina virtual ou JVM.
2. Conceito liderado pelo BuildMaster

O foco central na arquitetura de distribuição de tarefas é BuildMaster.Ele é um serviço que:
- monitora as mudanças na árvore de origem do projeto.
- envia comandos que devem ser executados pelo serviço Worker para construir e testar o projeto.
- notifica os usuários sobre os resultados das ações realizadas.
BuildMaster. é configurável através de um arquivo master.cfg. Este arquivo está na raiz BuildMaster.. Mais tarde, mostrarei como essa raiz é criada. O arquivo em si master.cfg contém um script em python que utiliza chamadas BuildBot.
O próximo objeto mais importante BuildBot é chamado de SharedWorker. Este serviço pode ser executado em outro host com um sistema operacional diferente, ou pode ser no mesmo onde BuildMaster.. Ele também pode existir em um ambiente virtual especialmente preparado com seus pacotes e variáveis. Esses ambientes virtuais podem ser criados com utilitários python como virtualenv, venv..
BuildMaster. transmite comandos para cada SharedWorker-u, que por sua vez os executa. Isso significa que o processo de construção e teste do projeto pode ocorrer em SharedWorker-e sob o gerenciamento do Windows e em outro Worker sob o gerenciamento do Linux.
O checkout do código fonte do projeto ocorre em cada SharedWorker-e.
3. Instalação
Então, vamos lá. Como host, vou usar o Ubuntu 18.04. Nele, colocarei um BuildMaster.-a e um SharedWorker-a. Mas primeiro, será necessário instalar o python3.7:
sudo apt-get update
sudo apt-get install python3.7
Para aqueles que precisam do python3.7.2 em vez do 3.7.1, é possível fazer o seguinte:
sudo apt-get update
sudo apt-get install 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
Na próxima etapa, instalaremos Twisted. e BuildBot, e pacotes que permitem ativar funcionalidades adicionais 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 BuildMaster.. Ele estará na nossa pasta /home/habr/master.
mkdir master
buildbot create-master master # É aqui que realmente criamosPróximo passo. Vamos criar SharedWorker. Ele estará na nossa pasta /home/habr/worker.
mkdir worker
buildbot-worker create-worker --umask=0o22 --keepalive=60 worker localhost:4000 seuNomeDeTrabalhador senha
Quando você iniciar SharedWorker, por padrão ele criará na /home/habr/worker pasta com o nome do projeto indicado em master.cfg. E na pasta com o nome do projeto ele criará um diretório build, e aí fará checkout. O diretório de trabalho para SharedWorker-a será o diretório /home/habr/yourProject/build.
a ‘Chave Dourada’
E agora, a razão pela qual escrevi o parágrafo anterior: o script que Master exigirá que SharedWorker-a execute remotamente neste diretório não será realizado, pois o script não tem permissões para ser executado. Para consertar isso, será necessária a chave –umask=0o22, que proíbe a gravação neste diretório, mas mantém as permissões de execução. E é isso que precisamos.
BuildMaster. e SharedWorker estabelecem conexão entre si. Às vezes, essa conexão é interrompida e SharedWorker aguarda um tempo pela resposta de BuildMaster.-a. Se não houver resposta, a conexão é reiniciada. A chave –keepalive=60 é necessária para indicar o tempo após o qual conectar é reiniciada.
5. Configuração. Receita passo a passo
Configuração BuildMaster. ocorre do lado da máquina onde executamos o comando create-master. No nosso caso, é o diretório /home/habr/master. O arquivo de configuração master.cfg ainda não existe, mas o comando já criou o arquivo master.cmg.sample. É necessário renomeá-lo para master.cfg.sample em master.cfg
mv master.cfg.sample master.cfgVamos abrir este master.cfg. E analisar do que se compõ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.github.io/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 — dicionário básico do arquivo de configuração. Deve ser obrigatoriamente utilizado no arquivo de configuração. Para facilitar a utilização no código de configuração, seu pseudônimo é introduzido «c». Os nomes em c[«keyFromDist»] são elementos fixos para interação com BuildMaster.. Para cada chave, um objeto correspondente é atribuído como valor.
5.2 trabalhadores
c['workers'] = [worker.Worker("example-worker", "pass")]Desta vez, indicamos BuildMaster.- uma lista de SharedWorker-s. Nós SharedWorker criamos , especificando you-worker-name e senha. Agora eles também devem ser indicados no lugar de example-worker e pass .
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))
Pela chave change_source do dicionário c, obtemos acesso à lista onde o objeto que interroga o repositório do código fonte do projeto deve ser colocado. No exemplo, um repositório Git é utilizado, que é interrogado a cada intervalo.
O primeiro argumento é o caminho para seu repositório.
workdir representa o caminho para a pasta onde, do lado do SharedWorker-a em relação ao caminho /home/habr/worker/yourProject/build o git irá armazenar a versão local do repositório.
branch contém a ramificação específica no repositório que deve ser monitorada.
pollInterval contém o número de segundos após o qual BuildMaster. ele interrogará o repositório em busca de alterações.
Há vários métodos para monitorar alterações no repositório do projeto.
O método mais simples é Polling, que implica que BuildMaster. interroga periodicamente o servidor com o repositório. No caso de commit ter refletido as mudanças no repositório, então BuildMaster. com um certo atraso criará um objeto interno Change e o enviará para o manipulador de eventos Agendador, que iniciará os passos para compilar e testar o projeto em SharedWorker-e. Entre esses passos estará indicado atualizar do repositório. É exatamente em SharedWorker-e que será criada uma cópia local do repositório. Os detalhes desse processo serão revelados abaixo nas duas seções seguintes ( e ).
Um método ainda mais elegante para rastrear mudanças no repositório é o envio direto de mensagens do servidor onde ele está hospedado para BuildMaster.-u sobre a alteração do código fonte do projeto. Nesse caso, assim que o desenvolvedor fizer commit, o servidor com o repositório do projeto enviará uma mensagem BuildMaster.-u. E este, por sua vez, a interceptará criando um objeto PBChangeSource. Em seguida, esse objeto será passado para Agendador, que ativará os passos para compilar e testar o projeto. Uma parte importante desse método é o trabalho com hook-scripts do servidor no repositório. No script hook-u, responsável por tratar as ações em commit-e, é necessário chamar a utilidade sendchange e especificar o endereço de rede BuildMaster.-u. Também é preciso especificar a porta de rede que ficará ouvindo PBChangeSource. PBChangeSource, que, a propósito, é parte de BuildMaster.-u. Este método exigirá permissões admin-a no servidor onde o repositório do projeto está localizado. Será necessário fazer um backup do repositório previamente.
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"]))
schedulers – é o elemento que atua como um gatilho, iniciando toda a cadeia de compilação e teste do projeto.

As alterações que foram registradas change_source, foram transformadas no processo de execução BuildBot-a em um objeto Change e agora cada Sheduler constrói solicitações para iniciar o processo de compilação do projeto com base nelas. No entanto, ele também determina quando essas solicitações devem ser enviadas adiante na fila. O objeto Builder mantém uma fila de solicitações e acompanha o estado da compilação atual em um SharedWorker-e. Builder existe tanto em BuildMaster.-e quanto em SharedWorker-e. Ele também envia de BuildMaster.-a para SharedWorker-a uma série de passos concretos que devem ser executados. build Podemos ver que, no exemplo atual, são criadas 2 unidades. Além disso, cada uma tem seu próprio tipo.
SingleBranchScheduler schedulers – cria 2 unidades, cada uma com seu tipo.
SingleBranchScheduler – uma das classes de agendamento mais populares. Ela observa uma branche e é acionada por uma alteração registrada nela. Quando percebe mudanças, pode postergar o envio de um pedido de construção (adiar por um período determinado em um parâmetro especial treeStableTimer). No nome se estabelece o nome do agendamento, que será exibido no BuildBot-web-interface. No ChangeFilter se define um filtro, com o qual alterações na branche fazem com que o agendamento envie um pedido de construção. No builderNames é especificado o nome builder-a, que definiremos um pouco mais tarde. O nome, no nosso caso, será o mesmo que o nome do projeto: yourProject.
ForceScheduler é uma coisa bastante simples. Este tipo de agendamento é acionado com um clique do mouse através do BuildBot-web-interface. Os parâmetros têm a mesma essência que em SingleBranchScheduler.
P.S. Nº 3. Quem sabe seja útil
Periodic — é um agendamento que é acionado com uma frequência fixa de tempo. A chamada dele se parece mais ou menos assim
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 um específico build, que depois builder é enviado para SharedWorker. No BuildFactory são especificados os passos que devem ser executados SharedWorker-u. Os passos são adicionados através da chamada do método addStep
O primeiro passo adicionado neste exemplo é git clean -d -f -f –x, então git checkout. Essas ações estão embutidas no parâmetro método, que não é explicitamente indicado, mas implica um valor padrão fresh. Parâmetro mode='incremental' indica que os arquivos do diretório, para onde é feito o chechout, permanecem intocados se estiverem ausentes do repositório.
O segundo passo adicionado é a chamada de um script trial com o parâmetro hello do lado SharedWorker-a do diretório /home/habr/worker/yourProject/build c com a variável de ambiente PATHONPATH=… Assim, você pode escrever seus scripts e executá-los do lado SharedWorker-a através do passo util.ShellCommand. Esses scripts podem ser colocados diretamente no repositório. Assim, ao chechout-e eles irão para /home/habr/worker/yourProject/build. No entanto, existem duas ressalvas:
- SharedWorker deve ser criado com a chave para que não bloqueie os direitos de execução após checkout-a.
- Ao git push-e desses scripts, é necessário especificar a propriedade executable, para que após chechout-e os direitos de execução do script Git não sejam perdidos.
5.6 construtores
c['builders'] = []
c['builders'].append(util.BuilderConfig(name="runtests",
workernames=["example-worker"],
factory=factory))
Sobre o que é Builder foi contado . Agora, vou explicar com mais detalhes como criá-lo. BuilderConfig é um construtor builder. Vários desses construtores podem ser definidos em c[‘builders’] , pois é uma lista de objetos do tipo. builder Agora, vamos reescrever um exemplo 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 nome builder-a. Aqui o chamamos de yourProject. Isso significa que no SharedWorker-e será criado esse caminho /home/habr/worker/yourProject/build. Sheduler localiza builder com exatamente esse nome.
workernames contém uma lista SharedWorker-s. Cada um deles deve ser adicionado em c[‘workers’].
factory — um específico build, com o qual está associado builder. Ele enviará um objeto build para SharedWorker para executar todos os passos que fazem parte deste build-a.
6. Exemplo de configuração própria
Aqui está a arquitetura do exemplo de projeto que eu proponho implementar através de BuildBot
.
Usaremos svncomo sistema de controle de versões. O repositório estará em alguma nuvem. Aqui está o endereço dessa nuvem . Na nuvem sob svn há uma conta username: user, passwd: senha. Os scripts, que consistem em passos build-a também estarão localizados na branche svn, em uma pasta separada buildbot/worker_linux. Esses scripts estão no repositório com a propriedade preservada executable.
BuildMaster. e SharedWorker funcionam em um único host project.host .BuildMaster. armazenam seus arquivos na pasta /home/habr/master. SharedWorker também armazena no seguinte caminho /home/habr/worker. A comunicação entre os processos BuildMaster.-a e SharedWorker-a é realizada através do porta 4000 pelo protocolo BuildBot-a, ou seja, ‘pb’ protocolo.
O projeto alvo é totalmente escrito em python. A tarefa é rastrear suas alterações, criar um arquivo executável, gerar documentação e realizar testes. Em caso de falha, é preciso enviar um e-mail a todos os desenvolvedores informando que houve uma ação mal sucedida.
A visualização web BuildBot será conectada na porta 80 para project.host. Apatch não precisa ser instalado. A biblioteca twisted já inclui um servidor web, BuildBot que é utilizado.
Para armazenamento de informações de uso interno para BuildBot vamos usar sqlite.
Para envio de e-mails, precisamos de um host smtp.your.domain — onde é permitido enviar e-mails a partir do endereço projectHost@your.domain sem autenticação. Também no host ‘smtp ‘ o protocolo escuta na porta 1025.
As pessoas envolvidas no processo são duas: admin e user. admin administra BuildBot. user é a pessoa que realiza commit-s.
O arquivo executável é gerado através de pyinstaller. A documentação é gerada através de doxygen.
Para esta arquitetura, eu escrevi o seguinte 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>Status do lançamento construído: {{ summary }}</h4>
<p>Serviço utilizado para a construção: {{ workername }}</p>
<p>Projeto: {{ projects }}</p>
<p>Para visualizar a interface de gerenciamento, acesse o link: {{ buildbot_url }}</p>
<p>Para ver o resultado da construção, acesse o link: {{ build_url }}</p>
<p>Usando WinSCP, é possível conectar ao servidor com o ip:xxx.xx.xxx.xx. Faça login como habr/password e baixe o arquivo executável do diretório ~/worker/yourProject/build/dist.</p>
<p><b>A construção foi realizada através do 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'] = "O processo de construção"
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, é necessário BuildMaster.-a e SharedWorker-a. Em seguida, insira este arquivo master.cfg em /home/habr/master.
O próximo passo é iniciar o serviço BuildMaster.-a
sudo buildbot start /home/habr/master
Então, inicie o serviço SharedWorker-a
buildbot-worker start /home/habr/worker
Pronto! Agora Buildbot irá monitorar mudanças e reagir a commit-u em svn, executando etapas de construção e teste do projeto com a arquitetura indicada acima.
Abaixo, eu descreverei algumas características do mencionado master.cfg.
6.1 No caminho para o seu master.cfg
Durante a escrita do meu master.cfg muitas falhas ocorrerão, portanto será necessário ler o arquivo de log. Ele é armazenado tanto em BuildMaster.-e c com caminho absoluto /home/habr/master/twistd.log, quanto do lado SharedWorker-a com caminho absoluto /home/habr/worker/twistd.log. À medida que você lê os erros e os corrige, será necessário reiniciar o serviço BuildMaster.-a. Veja como fazer isso:
sudo buildbot stop /home/habr/master
sudo buildbot upgrade-master /home/habr/master
sudo buildbot start /home/habr/master
6.2 Trabalhando 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)
Para começar, vamos olhar para svn_poller. Esta é a mesma interface, que consulta o repositório a cada minuto. Neste caso svn_poller está acessando apenas o ramo trunk. O misterioso parâmetro split_file=util.svn.split_file_alwaystrunk define as regras: como dividir a estrutura de pastas svn em ramos. Ele também oferece caminhos relativos. Por sua vez split_file_alwaystrunk facilita o processo, dizendo que no repositório existem apenas trunk.
Em Schedulers indica-se ChangeFilter, que vê Nenhum e associa a ele o ramo trunk por meio da associação definida com split_file_alwaystrunk. Reagindo a mudanças em trunk, inicia builder c com o nome yourProject.
properties aqui é necessário para que o administrador receba notificações sobre os resultados da construção e teste como proprietário do processo.
Passo build-a checkout é capaz de remover completamente quaisquer arquivos que estejam na versão local do repositório SharedWorker-a. E então fazer uma atualização completa svn update. O modo é configurado através do parâmetro mode=full, method=fresh. Parâmetro haltOnTailure significa que se svn update se ocorrer um erro, todo o processo de montagem e teste deve ser pausado, pois ações adicionais não fazem sentido.
6.3 Você tem uma mensagem: os relatórios estão autorizados a declarar
repórteres — é um serviço de envio de notificações por e-mail.
template_html=u'''
<h4>Status do lançamento construído: {{ summary }}</h4>
<p>Serviço utilizado para a construção: {{ workername }}</p>
<p>Projeto: {{ projects }}</p>
<p>Para visualizar a interface de gerenciamento, acesse o link: {{ buildbot_url }}</p>
<p>Para ver o resultado da construção, acesse o link: {{ build_url }}</p>
<p>Usando WinSCP, é possível conectar ao servidor com o ip:xxx.xx.xxx.xx. Faça login como habr/password e baixe o arquivo executável do diretório ~/worker/yourProject/build/dist.</p>
<p><b>A construção foi realizada através do 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]
Ele pode enviar mensagens .
MailNotifier usa e-mail para o envio de notificações.
template_html define o modelo de texto para envio. A formatação é feita usando html. Ele é modificado pelo motor (pode ser comparado a django). BuildBot possui um conjunto de variáveis cujos valores são inseridos no modelo durante a criação do texto da mensagem. Essas variáveis estão inseridas em {{ chaves duplas }}. Por exemplo, sumário exibe o status das operações realizadas, ou seja, sucesso ou falha. E projects exibirá yourProject. Assim, com a ajuda de comandos de controle em jinja2, variáveis BuildBot-a e recursos de formatação de strings python, é possível criar uma mensagem bem informativa.
MailNotifier contém os seguintes argumentos.
fromaddr – é o endereço de onde as notificações serão enviadas.
sendToInterestedUsers=True envia a mensagem ao proprietário e ao usuário que fez commit.
lookup — é o sufixo que deve ser adicionado aos nomes dos usuários que recebem a notificação. Assim admin o usuário receberá a notificação no endereço admin@your.domain.
relayhost define o nome do host onde o servidor está aberto smtp, a smptPort define o número da porta que escuta smtp servidor.
mode="warning" indica que a notificação deve ser enviada apenas se houver pelo menos um passo build-a que terminou com o status de falha ou aviso. No caso de sucesso, não é necessário enviar a notificação.
extraRecipients contém uma lista de pessoas para quem a notificação deve ser enviada além do proprietário e da pessoa que a fez commit.
messageFormatter é um objeto que define o formato da mensagem, seu modelo e um conjunto de variáveis disponíveis a partir de jinja2. Parâmetros como wantProperties=True e wantSteps=True definem esse conjunto de variáveis disponíveis.
s[‘services’]=[sendMessageToAll] fornece uma lista de serviços, entre os quais está nosso reporter.
Conseguimos! Minhas congratulações
Criamos nossa própria configuração e vimos a funcionalidade que este BuildBotpode oferecer. Acho que isso é suficiente para entender se essa ferramenta é necessária para o seu projeto. Isso lhe interessa? Isso será útil para você? É prático trabalhar com isso? Então, não escrevi este artigo em vão.
E mais. Eu gostaria que a comunidade profissional que usa BuildBot, fosse mais ampla, que os manuais fossem traduzidos, e que houvesse ainda mais exemplos.
Agradecemos a todos pela atenção. Boa sorte.
Fonte: habr.com
