Пример за изпълнение на Continuous Integration с помощта на BuildBot

Пример за изпълнение на Continuous Integration с помощта на BuildBot
(Изображение от Computerizer from Pixabay)

Здравейте!

Казвам се Евгений Черкин, аз съм програмист в екипа на разработчиците на миннодобивната компания Polymetal.

Когато започваш всеки голям проект, започваш да се чудиш: "Какъв софтуер да използвам за поддръжка на проекта?". IT проектите преминават през редица стъпки преди издаването на нова версия. Добре е, когато веригата от тези стъпки е автоматизирана. Автоматизираният процес на издаване на нова версия на IT проект се нарича Continuous Integration. BuildBot , който се оказа добър помощник за реализацията на този процес.

В тази статия реших да предоставя преглед на възможностите на BuildBot. Какво може този софтуер? Как да се доближим до него и как да изградим нормални ЕФЕКТИВНИ РАБОТНИ ОТНОШЕНИЯ с него? Нашият опит можете да приложите и в собствения си проект, като изградите работен сервис за компилация и тестване на вашия проект.

Съдържание

Съдържание

1. Защо BuildBot?
2. Концепция, ръководена от BuildMaster
3. Инсталация
4. Първи стъпки

5. Конфигурация. Стъпка по стъпка рецепта

5.1 BuildmasterConfig
5.2 workers
5.3 change_source
5.4 shedulers

5.5 BuildFactory
5.6 builders

6. Пример за конфигурация

6.1 Пътят към master.cfg
6.2 Работа с svn
6.3 Получавате писмо: reporters е упълномощен да заяви

Справихме се! Моите поздравления

1. Защо BuildBot?

По-рано на habr-e срещнах статии за реализиране на Continuous Integration с използване на BuildBot. Например, този ми се стори най-информативен. Има и друг пример — по-прост. Тези статии могат да бъдат подправени с пример от ръководство, а е междувременно, на английски език. В комбинация се получава добра отправна точка. След прочитането на тези статии, сигурно веднага ще искате да направите нещо на BuildBot .

Стоп! Но някой изобщо използвал ли е това в своите проекти? Оказва се, че да, много го приложили в своите задачи. Може да се намери примерите използването на BuildBot и в архивите на кодовете на Google.

Каква е логиката на хората, използващи Buildbot? Ведь есть другие инструменты: CruiseControl и Jenkins? Ще отговоря така. За повечето задачи Jenkins е наистина достатъчно. От своя страна, BuildBot е по-адаптивен, като задачите там се решават толкова лесно, колкото и в Jenkins. Вие решавате. Но понеже търсим инструмент за развиващ се целеви проект, защо да не изберем такъв, който ще позволи, основавайки се на простите стъпки, да получим система за компилация с интерактивност и уникален интерфейс.

За проектите, написани на Python, възниква въпросът: 'Защо да не изберем система за интеграция с интерфейс, разбираем от гледна точка на езика, използван в проекта?'. И тук е време да представим предимствата BuildBot.

И така, нашият 'инструментален квартет'. Сам за себе си определих четири основни характеристики BuildBot:

  1. Това е фреймуърк с отворен код под лиценз GPL
  2. Това е използването на Python като инструмент за конфигуриране и описание на изискуемите действия
  3. Това е възможността да се получи отговор от машината, на която се извършва сборката
  4. И накрая, минималните изисквания към хостинга. За разгръщане са нужни Python и Twisted, без необходимост от виртуална машина или Java машина.

2. Концепция, ръководена от BuildMaster

Пример за изпълнение на Continuous Integration с помощта на BuildBot

Централното място в архитектурата за разпределение на задачите заема BuildMaster. Той представлява услуга, която:

  • проследява промените в дървото на изходния код на проекта
  • изпраща команди, които трябва да бъдат изпълнени от услугата Worker за построяване на проекта и тестването му
  • уведомява потребителите за резултатите от извършените действия

BuildMaster конфигурира се чрез файл master.cfg. Този файл е в корена BuildMaster. По-късно ще покажа как този корен се създава. Самият файл master.cfg съдържа Python – скрипт, използващ повиквания BuildBot.

Следващият най-важен обект BuildBot има име Worker. Тази услуга може да бъде стартирана на друг хост с друга операционна система, или на същия, където BuildMaster. Също така, тя може да съществува в специално приготвена виртуална среда със свои пакети и променливи. Тези виртуални среди могат да бъдат приготвени с помощта на Python инструменти като virtualenv, venv.

BuildMaster предава командите на всеки Worker-у, а той, от своя страна, ги изпълнява. Тоест, процесът на построяване и тестване на проекта може да продължава на Worker-е под управление на Windows и на друг Worker под управление на Linux.

Checkout на изходния код на проекта се извършва на всеки Worker-е.

3. Инсталация

И така, да започнем. Като хост ще използвам Ubuntu 18.04. На него ще разположа един BuildMaster-a и един Worker-a. Но първо трябва да инсталирам Python 3.7:

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

За тези, които имат нужда от Python 3.7.2 вместо 3.7.1, могат да направят следното:


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

Следващата стъпка е да инсталираме Twisted и BuildBot, както и пакети, които позволяват използването на допълнителна функционалност 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. Първи стъпки

Време е да създадем BuildMaster. Той ще бъде в нашата папка /home/habr/master.

mkdir master
buildbot create-master master # Всъщност тук създаваме

Следваща стъпка. Ще създадем Worker. Той ще бъде в нашата папка /home/habr/worker.

mkdir worker
buildbot-worker create-worker --umask=0o22 --keepalive=60 worker localhost:4000 yourWorkerName password

Когато стартирате Worker, по подразбиране той ще създаде в /home/habr/worker папка с името на проекта, който е посочен в master.cfg. В папката с името на проекта той ще създаде директория build, и след това ще извършва checkout. Работната директория за Worker-а ще стане директорията /home/habr/yourProject/build.

„Златният“ ключ
А сега това, за което написах предишния абзац: скриптът, който Master ще поиска от Worker-а да извърши действия отдалечено в тази директория, няма да бъде изпълнен, тъй като скриптът няма права за стартиране. За да се разреши ситуацията, ще е необходим ключ —umask=0o22, който налага забрана за запис в тази директория, но ще остави правото за изпълнение. А именно това ни е нужно.

BuildMaster и Worker установяват свързаност помежду си. Понякога тя се прекъсва и Worker очаква известно време за отговор от BuildMaster-а. Ако отговор не последва, връзката се рестартира. Ключът —keepalive=60 всъщност е необходим, за да зададе времето, след което connect се презарежда.

5. Конфигурация. Стъпка по стъпка рецепта

Конфигурация BuildMaster стигаме от страна на машината, където сме изпълнили командата create-master. В нашия случай това е каталогът /home/habr/master. Конфигурационният файл master.cfg все още не съществува, но самата команда вече е създала файла master.cmg.sample. Необходимо е да го преименувате на master.cfg.sample в master.cfg

mv master.cfg.sample master.cfg

Отваряме този master.cfg. И ще разгледаме от какво е съставен. А след това ще опитаме да направим своя конфигурационен файл.

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 — основен речник на конфигурационния файл. Той трябва задължително да бъде включен в конфигурационния файл. За удобство в кода на конфигурацията се въвежда неговият псевдоним «c». Имената ключове в c[«keyFromDist»] са фиксирани елементи за взаимодействие с BuildMaster. За всеки ключ се задава съответстващ обект като стойност.

5.2 workers

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

Този път посочваме BuildMaster- списък от Worker-и. Самият Worker създадохме по-горе, посочвайки your-worker-name и password. Сега същите трябва да бъдат заменени вместо example-worker и 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))                

По ключа change_source на речника c получаваме достъп до списъка, в който трябва да се постави обект, който опитва да опита репозиторий с изходния код на проекта. В примера се използва Git репозиторий, който се опитва с определена периодичност.

Първият аргумент е пътят до вашия репозиторий.

workdir представлява пътя до папката, където на страната Worker-а относително до пътя /home/habr/worker/yourProject/build ще на git пази локална версия на репозиторий.

branch съдържа конкретна клон в репозитория, за която трябва да следи.

pollInterval съдържа броя секунди, след изминатото време BuildMaster ще се опитва да опита репозитория за наличие на изменения.

Има няколко метода за следене на изменения в репозитория на проекта.

Най-лесният метод е Polling, който предполага, че BuildMaster периодично запитва сървъра с репозитория. В случай, че commit отрази промените в репозитория, то BuildMaster с известно забавяне ще създаде вътрешен обект Change и ще го изпрати към обработчика на събития Планирател, който ще стартира стъпките за компилация и тестване на проекта на Worker-то. Сред тези стъпки ще бъде посочено актуализиране репозитория. Именно на Worker-то ще се създаде локална копия на репозитория. Подробности за този процес ще бъдат разгледани по-долу в следващите два раздела (5.4 и 5.5).

Дори по-елегантен метод за следене на промените в репозитория е директното изпращане на съобщения от сървъра, на който той е разположен, до BuildMaster-то за промяната на изходния код на проекта. В този случай, щом разработчикът направи commit, сървърът с репозитория на проекта ще изпрати съобщение BuildMaster-то. А той, от своя страна, ще го прихване, създавайки обект PBChangeSource. След това този обект ще бъде предаден на Планирател, който ще активира стъпките за компилиране на проекта и тестването му. Важна част от този метод е работата с hook-скриптовете на сървъра в репозитория. В скрипта hook-то, отговорно за обработка на действията при commit-то, е необходимо да се извика утилитата sendchange и да се посочи мрежовия адрес BuildMaster-то. Необходимо е да се посочи и мрежовият порт, който ще слуша PBChangeSource. PBChangeSource, между другото, е част от BuildMaster-то. Този метод ще изисква права админ-a на сървъра, където е разположен репозитория на проекта. Предварително ще е необходимо да се направи резервно копие на репозитория.

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 – е елемент, който служи като тригер, стартиращ цялата верига за компилация и тестване на проекта.
Пример за изпълнение на Continuous Integration с помощта на BuildBot

Тези промени, които са били записани change_source, се промениха в процеса на работа с BuildBot-a в обект Change и сега всеки Sheduler изгражда заявки на базата на тях за стартиране на процеса на компилация на проекта. Но той определя и кога да предаде тези заявки по-нататък в опашката. Обектът Builder съхранява опашката от заявки и наблюдава състоянието на текущата компилация на отделен Worker-е. Builder съществува и на BuildMaster-е и на Worker-е. Той също така изпраща от BuildMaster-а на Worker-а вече конкретен build — серия от стъпки, които трябва да се изпълнят.
Виждаме, че в текущия пример се създават 2 броя. Освен това, всеки има свой тип. schedulers SingleBranchScheduler

SingleBranchScheduler – един от най-популярните класове за разписание. Той наблюдава една клонка и се задейства при фиксирана промяна в нея. Когато види промени, може да отложи изпращането на заявка за построяване (да отложи за периода, указан в специален параметър treeStableTimer). В name записва името на разписанието, което ще се показва в BuildBot-уеб-интерфейса. В ChangeFilter записва филтър, минавайки през който промените в клона предизвикват разписание да изпрати заявка за построяване. В builderNames указва името builder-а, което ще зададем малко по-късно. Името в нашия случай ще бъде същото като името на проекта: yourProject.

ForceScheduler е доста проста работа. Този вид разписание се задейства чрез клик с мишката в BuildBot-уеб-интерфейс. Параметрите имат същата същност, както в SingleBranchScheduler.

P.S. №3. Поне може да бъде полезно
Periodic — това е разписание, което се задейства с определена фиксирана времева периодичност. Извикването му изглежда приблизително така


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 указва времето на тази периодичност в секунди.

BuildFactory създава конкретен build, който след това builder изпраща на Worker. В BuildFactory указват се стъпките, които трябва да се изпълнят Worker-а. Стъпките се добавят с извикването на метода addStep

Първата добавена стъпка в този пример — git clean -d -f -f –x, след това git checkout. Тези действия са заложени в параметъра метод, който визуално не е указан, но подразбира стойност по подразбиране fresh. Параметърът mode='incremental' означава, че файловете от директорията, където става checkout, при това липсващите в репозитория остават непокътнати.

Втората добавена стъпка — това е извикването на скрипта trial с параметъра hello на страната Worker-а от директорията /home/habr/worker/yourProject/build c променливата за среда PATHONPATH=… По този начин можете да пишете вашите скриптове и да ги изпълнявате на страната Worker-а чрез стъпка util.ShellCommand. Тези скриптове могат да бъдат поставени директно в репозитория. Тогава при checkout-а те ще попадат в /home/habr/worker/yourProject/build. Въпреки това има две "но":

  1. Worker трябва да бъде създаден с ключа —umask за да не блокира правата за изпълнение след checkout-a.
  2. При git push-а тези скриптове е необходимо да се зададе свойството executable, за да не губи после при checkout-а правата за изпълнение на скрипт Git.

5.6 builders


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

За това, какво е Builder беше разказано тук.. Сега ще разкажа по-подробно как да го създадете. BuilderConfig е конструктор builder. Такива конструктори могат да бъдат зададени в c[‘builders’] , тъй като това е списък от обекти builder . Сега ще пренапишем примера, приближавайки го до нашата задача. BuildBotc['builders'] = [] c['builders'].append(util.BuilderConfig(name="yourProject", workernames=["yourWorkerName"], factory=factory))


Сега ще говоря за параметрите

заддава името BuilderConfig.

name -a. Тук го нарекохме builder. Това означава, че на yourProject-е ще бъде създаден този маршрут Workerоткрива /home/habr/worker/yourProject/build. Sheduler точно по това име. builder workernames

съдържа списък -ове. Всеки от които трябва да бъде добавен в Workerc[‘workers’] factory.

— конкретен , с който е асоцииран build. Той ще изпрати обект builderза изпълнение на всички стъпки, включени в това build на Worker Ето архитектурата на примерния проект, която предлагам да реализираме чрез build-a.

6. Пример за конфигурация

Като система за контрол на версиите ще използваме BuildBot
.

svn . Самият репозитори ще бъде в някакво облако. Ето адреса на това облакоsvn.host/svn/yourProject/trunk . В облака подима акаунт username: . Самият репозитори ще бъде в някакво облако. Ето адреса на това облако , passwd: user. Скриптовете, които представляват стъпки password-a ще са също така в клон build, в отделна папка . Самият репозитори ще бъде в някакво облако. Ето адреса на това облакоbuildbot/worker_linux . Тези скриптове са в репозитория с запазено свойствоexecutable работят на един хост.

BuildMaster и Worker project.host съхранява своите файлове в папка .BuildMaster също така съхранява по следния път /home/habr/master. Worker . Връзката между процесите /home/habr/worker-а и BuildMaster-а се осъществява през порт 4000 по протокол Worker-a, т.е. BuildBot‘pb’ протокол. Целевият проект е напълно написан на python. Задачата е да се проследят промените му, да се създаде изпълним файл, да се генерира документация, да се проведе тестване. В случай на неуспех, всички разработчици трябва да получат имейл със съобщение, че има неуспешно изпълнено действие.

Уеб визуализацията

ще свържем на порт 80 за BuildBot . Apache не е задължително да се инсталира. В библиотеката съхранява своите файлове в папкаtwisted вече присъства уеб сървър, който иска. BuildBot За съхранение на информация с вътрешно предназначение за

За имейл разпространение е необходим хост BuildBot ще използваме sqlite.

smtp.your.domain — на него е разрешена изпращането на имейли от адреса projectHost@your.domain без удостоверяване. Също така на хост ‘ smtp‘ протоколът се слуша на порт 1025. Участниците в процеса са двама:

. admin администрира админ и user. user е лицето, което извършва BuildBot-ите. commitИзпълнимият файл се генерира чрез

Файл Exacutable се генерира чрез pyinstaller. Документацията се генерира чрез doxygen.

За тази архитектура написах следното 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 можете да се свържете със сървъра с ip:xxx.xx.xxx.xx. Влезте с habr/password, за да изтеглите построения изпълним файл от директорията ~/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'] = "Процес на построение"
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"
}

На първо място е необходимо създаде BuildMaster-а се осъществява през порт 4000 по протокол Worker-a. След това да се постави този файл master.cfg в /home/habr/master.

Следващата стъпка е да се стартира услугата BuildMaster-а


sudo buildbot start /home/habr/master

След това стартирайте услугата Worker-a


buildbot-worker start /home/habr/worker

Готово! Сега Buildbot ще следи промените и ще реагира на commit-у в . Самият репозитори ще бъде в някакво облако. Ето адреса на това облако, изпълнявайки стъпките за компилиране и тестване на проекта с указаната архитектура.

По-долу ще опиша някои особености на посоченото master.cfg.

6.1 Пътят към master.cfg


Докато пиша своето master.cfg ще се направят немалко грешки, затова ще е необходимо четене на log файла. Той се съхранява както на BuildMaster-e c с абсолютен път /home/habr/master/twistd.log, така и на страната Worker-a с абсолютен път /home/habr/worker/twistd.log. При четене на грешки и тяхното коригиране ще е необходимо рестартиране на услугата BuildMaster-a. Ето как става:


sudo buildbot stop /home/habr/master
sudo buildbot upgrade-master /home/habr/master
sudo buildbot start /home/habr/master

6.2 Работа с 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)

На първо място, нека да разгледаме svn_poller. Това е същият интерфейс, който регулярно опитва да получи информация от репозитория на всеки минута. В този случай svn_poller обраща само към клона trunk. Загадъчният параметър split_file=util.svn.split_file_alwaystrunk определя правилата: как да се разделя структурата на папките . Самият репозитори ще бъде в някакво облако. Ето адреса на това облако на клони. Той предлага относителни пътища. От своя страна split_file_alwaystrunk улеснява процеса, като посочва, че в репозитория съществува само trunk.

В Schedulers се посочва ChangeFilter, който вижда None и асоциира с него клон trunk чрез зададената асоциация split_file_alwaystrunk. Реагирайки на изменения в trunk, стартира builder c с име yourProject.

properties тук е нужен, за да получава известия за резултатите от компилацията и тестването, като собственик на процеса.

Стъпка build-a checkout може да направи пълно изтриване на всякакви файлове, съхранявани в локалната версия на репозитория Worker-а. След това да направи пълно svn update. Режимът е настроен чрез параметъра mode=full, method=fresh. Параметърът haltOnTailure означава, че ако svn update ще трябва да бъде спряно, тъй като следващите действия нямат смисъл.

6.3 Получавате писмо: reporters е упълномощен да заяви


репортери е услуга за разпространение на уведомления по имейл.


template_html=u'''
<h4>Статус на построеното издание: {{ summary }}</h4>
<p>Използван сервиз за построение: {{ workername }}</p>
<p>Проект: {{ projects }}</p>
<p>За да видите интерфейса за управление, посетете следния линк: {{ buildbot_url }}</p>
<p>За да видите резултата от построяването, кликнете на линка: {{ build_url }}</p>
<p>С използване на WinSCP можете да се свържете със сървъра с ip:xxx.xx.xxx.xx. Влезте с habr/password, за да изтеглите построения изпълним файл от директорията ~/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]

Той може да изпраща съобщения по различни начини.

MailNotifier използва имейл за разпространение на уведомления.

template_html определя шаблона на текста за разпространение. За създаване на разметка се използва html. Той е модифициран от движещия механизъм jinja2 (може да се сравни с django). BuildBot има набор от променливи, стойностите на които се влагат в шаблона по време на формиране на текста на съобщението. Тези променливи са вписани в {{ двойни фигурни скобки }}. Например, summary показва статуса на завършените операции, тоест success или failure. А проектите ще изведат yourProject. Така, с помощта на управляващи команди в jinja2, променливите BuildBot-а и средствата за форматиране на низове python, може да се създаде доста информативно съобщение.

MailNotifier съдържа следните аргументи.

fromaddr – адресът, от който ще се изпращат уведомленията.

sendToInterestedUsers=True изпраща съобщението на собственика и на потребителя, който е направил commit.

lookup е суфикс, който трябва да се добави към имената на потребителите, получаващи уведомления. Така админ потребителят ще получи уведомление на адрес admin@your.domain.

relayhost определя името на хоста, на който е отворен сървърът ‘ протоколът се слуша на порт 1025., a smptPort определя номера на порта, който слуша ‘ протоколът се слуша на порт 1025. сървър.

mode=«warning» казва, че разпространението трябва да се прави само в случай, че има поне една стъпка build-а, която е завършила със статус failure или warning. При success разпространението не е необходимо.

extraRecipients съдържа списък на лицата, на които трябва да се направи разпространение освен собственика и лицето, извършило commit.

messageFormatter е обект, задаващ формата на съобщението, неговия шаблон и набор от променливи, достъпни от jinja2. Такъв параметър, като wantProperties=True и wantSteps=True задат този набор от достъпни променливи.

s[‘services’]=[sendMessageToAll] предоставя списък на услугите, сред които ще бъде и нашият репортер.

Справихме се! Моите поздравления

Създадохме собствена конфигурация и видяхме функционалността, на която е способен. BuildBotМисля, че това е достатъчно, за да разберете дали този инструмент е необходим за създаването на вашия проект. Интересува ли ви? Ще ви ползва ли? Удобно ли е да работите с него? Тогава не съм написал тази статия напразно.

И още. Бих искал професионалната общност, използваща BuildBot, да стане по-широка, ръководствата да се превеждат и примерите да стават още повече.

Благодаря на всички за вниманието. Успех.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster