Buildbot Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ

Π’Ρ€ΡΠ±Π²Π°ΡˆΠ΅ Π΄Π° настроя процСса Π½Π° Π±ΠΈΠ»Π΄ ΠΈ доставка Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈΡ‚Π΅ софтуСр ΠΎΡ‚ Git Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π½Π° сайта. И слСд ΠΊΠ°Ρ‚ΠΎ видях ΠΏΡ€Π΅Π΄ΠΈ Π²Ρ€Π΅ΠΌΠ΅ статия Π² Π₯Π°Π±ΡŠΡ€ Π·Π° buildbot (Π»ΠΈΠ½ΠΊ Π² края), Ρ€Π΅ΡˆΠΈΡ… Π΄Π° Π³ΠΎ ΠΏΡ€ΠΎΠ±Π²Π°ΠΌ Π·Π° Ρ‚ΠΎΠ²Π°.

Въй ΠΊΠ°Ρ‚ΠΎ buildbot Π΅ Ρ€Π°Π·ΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° систСма, Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ Π΅ Π΄Π° сС създадС ΠΎΡ‚Π΄Π΅Π»Π΅Π½ хост Π·Π° всяка Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π° систСма. Π’ случая Ρ‰Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ LXC ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΈ (Π·Π° linux) ΠΈ qemu (Π·Π° windows):

  • vm-srv-build1 β€” centos 7, Ρ‚ΡƒΠΊ Ρ‰Π΅ бъдС buildbot мастСр (master) ΠΈ Π΅Π΄ΠΈΠ½ ΠΎΡ‚ Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΡ†ΠΈΡ‚Π΅ (worker)
  • vm-srv-build2 β€” debian 10, Π·Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Π½Π΅ Π½Π° DEB ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ
  • vm-srv-build3 β€” windows 10, Π·Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Π½Π΅, сами Ρ€Π°Π·Π±ΠΈΡ€Π°Ρ‚Π΅, ΠΏΠΎΠ΄ ΠΊΠ°ΠΊΠ²ΠΎ

Π©Π΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°ΠΌΠ΅ Rac GUI β€” Π³Ρ€Π°Ρ„ΠΈΡ‡Π΅Π½ интСрфСйс Π·Π° 1Π‘ rac Π·Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π° ΠΎΡ‚ ΡΡŠΡ€Π²ΡŠΡ€ΠΈ. Для Linux Ρ‰Π΅ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Π²Π³Ρ€Π°Π΄Π΅Π½ΠΈ инструмСнти Π·Π° всяка ОБ, Π·Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Π½Π΅ Π½Π° exe Ρ„Π°ΠΉΠ» ΠΏΠΎΠ΄ Windows ΠΎΡ‚ tcl скрипт сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° freewrap.

Π˜Π½ΡΡ‚Π°Π»ΠΈΡ€Π°Π½Π΅ Π½Π°

GNU/Linux

По инсталацията, докумСнтацията Π² ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° Π΅ Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½Π° 1,2. И Π½Π΅ ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΠ²Π° особСни ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ:
Π—Π° мастСра:

pip3 install buildbot
pip3 install twisted
pip3 install autobahn
pip3 install pysqlite3
pip3 install sqlalchemy sqlalchemy-migrate
pip3 install buildbot-www buildbot-grid-view buildbot-console-view buildbot-waterfall-view
pip3 install python-dateutil

Π—Π° "Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΡ†ΠΈΡ‚Π΅" Ρ‚ΠΎΠ²Π° Π΅ Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ:

pip3 install buildbot-worker

Π Π°Π·Π±ΠΈΡ€Π° сС, ΠΏΠΎ-ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ Π΅ Π΄Π° сС ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Ρ‚ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π·Π° всяка ОБ, Π½ΠΎ Ρ‚ΠΎΠ²Π° Π½Π΅ Π΅ Π² ΠΎΠ±Ρ…Π²Π°Ρ‚Π° Π½Π° статията. ОсвСн Ρ‚ΠΎΠ²Π° Ρ‰Π΅ пропуснСм описаниСто Π½Π° настройкитС Π½Π° ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΈΡ‚Π΅ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π°, просто Ρ‰Π΅ ΠΎΡ‚Π±Π΅Π»Π΅ΠΆΠ°, Ρ‡Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ ProxMox VE. И ΡΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° Ρ‰Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° сС инсталират ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π·Π° всяка ОБ, Π½ΡƒΠΆΠ½ΠΈ Π·Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Π½Π΅ (centos: rpmdevtools ΠΈ Ρ‚.Π½.; debian: build-essential, dh-make, pbuilder ΠΈ Ρ‚.Π½.)

ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ‚Π΅ Π·Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Π½Π΅ ΠΈ услугитС Π½Π° buildbot Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ стартирани ΠΎΡ‚ Π½Π΅ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π», Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° ΡΡŠΠ·Π΄Π°Π΄Π΅Ρ‚Π΅ Ρ‚Π°ΠΊΡŠΠ² Π½Π° всичкитС хостовС, участващи Π² процСса:


adduser buildbot

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° Ρ‰Π΅ настроим Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎΡ‚ΠΎ стартиранС Π½Π° услугитС Π½Π° всСки ΠΎΡ‚ хостовСтС (ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΈΡ‚Π΅):

Systemd ΡŽΠ½ΠΈΡ‚ Π·Π° стартиранС Π½Π° мастСра:

touch /etc/systemd/buildbot-master.service 

[Unit]
Description=BuildBot master service
After=network.target

[Service]
User=buildbot
Group=buildbot
WorkingDirectory=/home/buildbot/master
ExecStart=/usr/local/bin/buildbot start --nodaemon
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

ΠΈ "Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΠΊΠ°"

touch /etc/systemd/buildbot-worker.service 

[Unit]
Description=BuildBot worker service
After=network.target

[Service]
User=buildbot
Group=buildbot
WorkingDirectory=/home/buildbot/worker
ExecStart=/usr/local/bin/buildbot-worker start --nodaemon

[Install]
WantedBy=buildbot-master.service

Въй ΠΊΠ°Ρ‚ΠΎ всички скриптовС (Π² нашия случай) са Ρ€Π°Π·ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈ Π² /usr/local/, трябва Π΄Π° Π·Π°Π΄Π°Π΄Π΅Ρ‚Π΅ ΠΏΡŠΡ‚Ρ към тях Π² ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈΡ‚Π΅ Π½Π° срСдата:

nano /root/.bash_profile

PATH=$PATH:$HOME/.local/bin:$HOME/bin:/usr/local/bin

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΡΡŠΠ·Π΄Π°Π΄Π΅Ρ‚Π΅ инфраструктура Π·Π° ΠΊΠ°Ρ‚Π°Π»ΠΎΠ·ΠΈ Π·Π° "Ρ€Π°Π±ΠΎΡ‚Π½ΠΈ" (Π½Π° всички хостовС), Π·Π° ΠΊΠΎΠ΅Ρ‚ΠΎ сС рСгистрира ΠΏΠΎΠ΄ потрСбитСля buildbot ΠΈ ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚Π΅ слСднитС ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ:

На ΠΏΡŠΡ€Π²ΠΈΡ хост vm-srv-build1:

su - buildbot
mkdir /home/buildbot/worker
cd ~
buildbot-worker create-worker --umask=0o22 --keepalive=60 worker vm-srv-build1:4000 CentOS 123456

На втория хост vm-srv-build2:

su - buildbot
mkdir /home/buildbot/worker
cd ~
buildbot-worker create-worker --umask=0o22 --keepalive=60 worker vm-srv-build1:4000 Debian-10 123456

На Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΡ‚Π΅ хостовС услугата buildbot-worker ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС стартирана

systemctl start buildbot-worker

MS Windows

ΠšΠ°Ρ‚ΠΎ "Ρ€Π°Π±ΠΎΡ‚Π΅Π½" Π·Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅ ΠΏΠΎΠ΄ Windows Ρ‰Π΅ бъдС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π° машина с послСдната вСрсия Π½Π° Win10.
Π—Π° Ρ€Π°Π±ΠΎΡ‚Π° Ρ‰Π΅ са Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈ:

  • Python
  • PyWIN
  • Git
  • Π—Π° инсталиранСто Π½Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΈ Π½Π° Python Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° сС ΠΈΠ·Ρ‚Π΅Π³Π»ΠΈ Build Tools for Visual Studio 2019
  • 7Zip

Π‘Π»Π΅Π΄ ΠΊΠ°Ρ‚ΠΎ сС инсталират всички ΠΈΠ·Π±Ρ€ΠΎΠ΅Π½ΠΈ ΠΏΠΎ-Π³ΠΎΡ€Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΈ, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° инсталиратС ΠΈ самия buildbot:

pip install buildbot-worker

Π”Π° създадСм Ρ€Π°Π±ΠΎΡ‚Π΅Π½ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³

md c:worker

И Π΄Π° стартирамС

buildbot-worker start c:worker

Ако всичко Ρ€Π°Π±ΠΎΡ‚ΠΈ (Π²ΠΈΠΆΡ‚Π΅ Π»ΠΎΠ³ c:workertwistd.log), ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° рСгистриратС нашия "Ρ€Π°Π±ΠΎΡ‚Π΅Π½", ΠΊΠ°Ρ‚ΠΎ услуга, добавяйки Π² Ρ€Π΅Π³ΠΈΡΡ‚ΡŠΡ€Π° Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ с работния ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ (ΠΊΠΎΠΌΠ°Π½Π΄ΠΈΡ‚Π΅ сС ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚ Π² powershell, стартиран ΠΎΡ‚ ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° администратора):

buildbot_worker_windows_service.exe --user VM-SRV-BUILD3buildbot --password 123456 --startup auto install
New-ItemProperty -path Registry::HKEY_LOCAL_MACHINESYSTEMCurrentControlSetservicesBuildBotParameters -Name directories -PropertyType String -Value c:worker

И ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° стартиратС услугата

Start-Service buildbot

Π‘ "Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΡ‚Π΅" Π½Π° Ρ‚ΠΎΠ²Π° Π΅ всичко, ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π΅ Π³ΠΈ засягатС, всичкото ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ става ΠΎΡ‚ мастСра.

Настройка Π½Π° мастСра

ΠŸΡŠΡ€Π²ΠΎ, Π΄Π° създадСм инфраструктура Π·Π° мастСра (Π½Π° главния хост), Π·Π° ΠΊΠΎΠ΅Ρ‚ΠΎ сС рСгистрира ΠΏΠΎΠ΄ потрСбитСля buildbot ΠΈ ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚Π΅ слСднитС ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ:

su - buildbot
mkdir /home/buildbot/master
cd ~
buildbot create-master master

Π—Π° Π³ΠΎΡ‚ΠΎΠ²ΠΈΡ‚Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π΄Π° създадСм ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ builds

mkdir /home/buildbot/builds

Π’ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° /home/buildbot/master/ бСшС създадСн Ρ„Π°ΠΉΠ» master.cfg. Π’ΠΎΠ·ΠΈ Ρ„Π°ΠΉΠ» прСдставлява ΠΊΠΎΠ΄ Π½Π° Python ΠΈ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° описаниС Π½Π° всички ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΈ Π½Π° Ρ€Π°Π±ΠΎΡ‚Π° Π½Π° систСмата, с Π½Π΅Π³ΠΎ Ρ‰Π΅ Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌ Π² Π±ΡŠΠ΄Π΅Ρ‰Π΅.

nano /home/buildbot/master/master.cfg

import os, re
from buildbot.plugins import steps, util, schedulers, worker, changes, reporters

c = BuildmasterConfig = {}

# ОписаниС Π½Π°ΡˆΠΈΡ… Ρ€Π°Π±ΠΎΡ‡ΠΈΡ….
c['workers'] = [ worker.Worker('CentOS', '123456'), worker.Worker('Debian-10', '123456'), worker.Worker('Windows-10', '123456')]
c['protocols'] = {'pb': {'port': 4000}} 

# Π£ΠΊΠ°Π·Π°Π½ΠΈΠ΅ мастСру ΠΊΠ°ΠΊΠΎΠΉ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ
c['change_source'] = []
c['change_source'].append(changes.GitPoller(
       repourl = 'https://bitbucket.org/svk28/rac-gui.git',
       project = 'Rac-GUI',
       branches = True,
       pollInterval = 60
      )
)

# слуТба запуска сборки
c['schedulers'] = []
c['schedulers'].append(schedulers.SingleBranchScheduler(
       name="Rac-GUI-schedulers",
       change_filter=util.ChangeFilter(branch='master'),
       builderNames=["Rac-GUI-RPM-builder", "Rac-GUI-DEB-builder", "Rac-GUI-WIN-builder"],
       properties = {'owner': 'admin'}
       )
)
@util.renderer

######################################3
# Π‘Π±ΠΎΡ€ΠΊΠ° RPM-ΠΏΠ°ΠΊΠ΅Ρ‚Π°
 rac_gui_build_RPM = util.BuildFactory()

rac_gui_build_RPM.addStep(steps.Git(
       repourl = 'https://bitbucket.org/svk28/rac-gui.git',
       workdir = 'rac-gui',
       haltOnFailure = True,
       submodules = True,
       mode='full',
       progress = True)
)

Π—Π° Π΄Π° Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€Π°ΠΌΠ΅ ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ с Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ вСрсии, Π±Π΅Π· Π΄Π° сС Π½Π°Π»Π°Π³Π° Π΄Π° сС Ρ€ΠΎΠ²ΠΈΠΌ Π² ΠΊΠΎΠ΄Π° Π½Π° Ρ„Π°ΠΉΠ»Π° master.cfg, Π² основния скрипт Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° rac_gui.tcl Π² Π·Π°Π³Π»Π°Π²ΠΈΠ΅Ρ‚ΠΎ, бяха Π΄ΠΎΠ±Π°Π²Π΅Π½ΠΈ Ρ€Π΅Π΄ΠΎΠ²Π΅ с Ρ‚Π΅ΠΊΡƒΡ‰Π°Ρ‚Π° вСрсия ΠΈ Ρ€Π΅Π»ΠΈΠ·:

######################################################
#        Rac GUI
...
# version: 1.0.3
# release: 1

И Π½Π° Π±Π°Π·Π°Ρ‚Π° Π½Π° Ρ‚Π΅Π·ΠΈ Ρ€Π΅Π΄ΠΎΠ²Π΅ buildbot Ρ‰Π΅ Π½ΠΎΠΌΠ΅Ρ€ΠΈΡ€Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈΡ‚Π΅. Π—Π° ΠΈΠ·Π²Π»ΠΈΡ‡Π°Π½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈΡ‚Π΅ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° конзолния grep. Π’ buildbot Π½Π΅ Π΅ възмоТно просто Ρ‚Π°ΠΊΠ° Π΄Π° сС опрСдСлят ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π·Π° β€žΡ€Π°Π±ΠΎΡ‚Π½ΠΈΡ†ΠΈΡ‚Π΅β€œ (ΠΏΠΎΠ½Π΅ Π°Π· Π½Π΅ Π½Π°ΠΌΠ΅Ρ€ΠΈΡ… Π½Π°Ρ‡ΠΈΠ½). Π—Π°Ρ‚ΠΎΠ²Π° слуТат свойствата (property). ВоСст, Π² процСса Π½Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅, добавямС ΡΡ‚ΡŠΠΏΠΊΠΈ Π·Π° опрСдСлянС Π½Π° вСрсията ΠΈ Ρ€Π΅Π»ΠΈΠ·Π° ΠΈ ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΎ, Π·Π°Π΄Π°Π²Π°ΠΌΠ΅ свойствата version ΠΈ release. Бвойствата ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС Π·Π°Π΄Π°Π²Π°Ρ‚ ΠΏΠΎ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ Π½Π°Ρ‡ΠΈΠ½ΠΈ, Π² Ρ‚ΠΎΠ·ΠΈ случай Ρ‚ΠΎΠ²Π° Π΅ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°:

# Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ вСрсии ΠΈΠ· основного Ρ„Π°ΠΉΠ»Π°
rac_gui_build_RPM.addStep(
       steps.SetPropertyFromCommand(
       command="grep version ../rac-gui/rac_gui.tcl | grep -oE 'b[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}b'", property="version"
       )
)
# Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ€Π΅Π»ΠΈΠ·Π° ΠΈΠ· основного Ρ„Π°ΠΉΠ»Π°
rac_gui_build_RPM.addStep(
       steps.SetPropertyFromCommand(
       command="grep release ../rac-gui/rac_gui.tcl | grep -oE 'b[0-9]{1,3}b'", property="release"
       )
)

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΡ‚Π΅ стойности ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС подставят посрСдством ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° util.Interpolate().

# Π—Π°ΠΏΠ°ΠΊΡƒΠ΅ΠΌ исходники
rac_gui_build_RPM.addStep(
       steps.ShellCommand(
          command=["tar", "czf", util.Interpolate("/home/buildbot/rpmbuild/SOURCES/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz"), "../rac-gui"]
       )
)

Π’ΡƒΠΊ слСдва Π΄Π° сС ΠΎΡ‚Π±Π΅Π»Π΅ΠΆΠΈ, Ρ‡Π΅ Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Ρ…ΠΎΡΡ‚ΡŠΡ‚ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΈ Π·Π° Ρ€ΡŠΡ‡Π½ΠΎ ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ Ρ‰Π΅ ΠΏΡ€Π΅ΠΌΠΈΠ½Π°Π²Π° ΠΏΠΎ стандартни ΠΏΡŠΡ‚ΠΈΡ‰Π°.

# ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ spec
rac_gui_build_RPM.addStep(steps.ShellCommand(
       command=["cp", "../rac-gui/rac_gui.spec", "/home/buildbot/rpmbuild/SPECS/rac_gui.spec"]))

Π—Π° установяванС Π½Π° ΠΊΠΎΡ€Π΅ΠΊΡ‚Π½ΠΈ Π½ΠΎΠΌΠ΅Ρ€Π° Π½Π° Ρ€Π΅Π»ΠΈΠ·Π° ΠΈ вСрсията сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° стандартния sed, Ρ‚.Π΅. ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° замСня стойноститС Π² spec-Ρ„Π°ΠΉΠ»Π° Π½Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈΡ‚Π΅.

# мСняСм Π²Π΅Ρ€ΡΠΈΡŽ
rac_gui_build_RPM.addStep(steps.ShellCommand(
       command=["sed", "-i", util.Interpolate("s/.*Version:.*/Version:t%(prop:version)s/"), "/home/buildbot/rpmbuild/SPECS/rac_gui.spec"]))
# мСняСм Ρ€Π΅Π»ΠΈΠ·
rac_gui_build_RPM.addStep(steps.ShellCommand(
       command=["sed", "-i", util.Interpolate("s/.*Release:.*/Release:t%(prop:release)s/"), "/home/buildbot/rpmbuild/SPECS/rac_gui.spec"]))

# запускаСм процСсс сборки
rac_gui_build_RPM.addStep(steps.RpmBuild(
       specfile="/home/buildbot/rpmbuild/SPECS/rac_gui.spec",
       dist='.el5',
       topdir='/home/buildbot/rpmbuild',
       builddir='/home/buildbot/rpmbuild/build',
       rpmdir='/home/buildbot/rpmbuild/RPMS',
       sourcedir='/home/buildbot/rpmbuild/SOURCES'
      )
)

Готовият ΠΏΠ°ΠΊΠ΅Ρ‚ ΠΈ Π°Ρ€Ρ…ΠΈΠ²Π° с изходния ΠΊΠΎΠ΄ сС ΠΊΠΎΠΏΠΈΡ€Π°Ρ‚ Π½Π° майстора. Но ΠΌΠΎΠΆΠ΅ ΠΈ Π²Π΅Π΄Π½Π°Π³Π° ΠΎΡ‚ работния Ρ„Π°ΠΉΠ» Π΄Π° сС ΠΊΠΎΠΏΠΈΡ€Π° Π² собствСния Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈ ΠΈΠ»ΠΈ Π½Π° сайта.

# Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Ρ„Π°ΠΉΠ» Π½Π° мастСр
rac_gui_build_RPM.addStep(
       steps.FileUpload(
          workersrc=util.Interpolate("/home/buildbot/rpmbuild/RPMS/noarch/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm"),
          masterdest=util.Interpolate("/home/buildbot/builds/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm")
      )
)

rac_gui_build_RPM.addStep(
       steps.FileUpload(
       workersrc=util.Interpolate("/home/buildbot/rpmbuild/SOURCES/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz"),
          masterdest=util.Interpolate("/home/buildbot/builds/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz")
       )
)

Π©Π΅ стартирамС Π½Π° майстора процСса ΠΏΠΎ ΠΊΠΎΠΏΠΈΡ€Π°Π½Π΅ Π½Π° ΡΡŠΠ±Ρ€Π°Π½ΠΈΡ‚Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π½Π° хостинг ΠΏΠΎ FTP. Π—Π° Ρ‚ΠΎΠ²Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° скрипт Π½Π° tcl.

rac_gui_build_RPM.addStep(
        steps.MasterShellCommand(
            command=["/usr/local/bin/deploy-ftp.tcl",
                util.Interpolate("--local-file=/home/buildbot/builds/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm"),
                util.Interpolate("--remote-file=uploads/rac-gui/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm")]
        )
)

rac_gui_build_RPM.addStep(
        steps.MasterShellCommand(
            command=["/usr/local/bin/deploy-ftp.tcl",
                util.Interpolate("--local-file=/home/buildbot/builds/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz"),
                util.Interpolate("--remote-file=uploads/rac-gui/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz")]
        )
)

Π‘ RPM ΠΌΡ‹ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ»ΠΈ. Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ ΠΊ описанию Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° сборки DEB-ΠΏΠ°ΠΊΠ΅Ρ‚Π°. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ процСссы сборки ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² для Ρ€Π°Π·Π½Ρ‹Ρ… систСм нСзависимы Π΄Ρ€ΡƒΠ³ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³Π°, ΠΌΠ½ΠΎΠ³ΠΈΠ΅ шаги Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡ‚ΡŒΡΡ.


rac_gui_build_DEB = util.BuildFactory()

rac_gui_build_DEB.addStep(steps.Git(
       repourl = 'https://bitbucket.org/svk28/rac-gui.git',
       haltOnFailure = True,
       submodules = True,
       mode='full',
       workdir='build',
       progress = True)
)

# Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ вСрсии ΠΈΠ· основного Ρ„Π°ΠΉΠ»Π°
rac_gui_build_DEB.addStep(
       steps.SetPropertyFromCommand(
       command="grep version rac_gui.tcl | grep -oE 'b[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}b'", property="version"
       )
)

# Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ€Π΅Π»ΠΈΠ·Π° ΠΈΠ· основного Ρ„Π°ΠΉΠ»Π°
rac_gui_build_DEB.addStep(
       steps.SetPropertyFromCommand(
       command="grep release rac_gui.tcl | grep -oE 'b[0-9]{1,3}b'", property="release"
       )
)

# ΠŸΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΡƒΠ΅ΠΌ запускаСмый Ρ„Π°ΠΉΠ»
    rac_gui_build_DEB.addStep(steps.ShellCommand(
       command=["mv", "rac_gui.tcl", "racgui"]))

Для RPM-ΠΏΠ°ΠΊΠ΅Ρ‚Π° Ρ‡Π°ΡΡ‚ΡŒ Π½ΠΈΠΆΠ΅ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ выполняСтся самим rpm ΠΏΡ€ΠΈ сборкС ΠΈ описана Π²Π½ΡƒΡ‚Ρ€ΠΈ спСцификации, Π° для Debian Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ это Π΄Π΅Π»Π°Ρ‚ΡŒ здСсь:

# ПомСняСм ΠΏΡƒΡ‚ΠΈ ΠΊ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°ΠΌ
rac_gui_build_DEB.addStep(steps.ShellCommand(
       command=["sed", "-i", "s+^set dir(lib)+set dir(lib) /usr/share/rac-gui/lib ;#+g", "racgui"]))

# ПомСняСм ΠΏΡƒΡ‚ΠΈ ΠΊ Ρ„Π°ΠΉΠ»Π°ΠΌ
rac_gui_build_DEB.addStep(steps.ShellCommand(
       command=["sed", "-i", "s+[pwd]+/usr/share/rac-gui+g", "racgui"]))

# Π·Π°Π°Ρ€Ρ…ΠΈΠ²ΠΈΡ€ΡƒΠ΅ΠΌ исходники
rac_gui_build_DEB.addStep(steps.ShellCommand(
       command=["tar", "czf", util.Interpolate("../rac-gui_%(prop:version)s.orig.tar.gz"), "."]))

# Π‘ΠΎΠ±Π΅Ρ€Ρ‘ΠΌ ΠΏΠ°ΠΊΠ΅Ρ‚
rac_gui_build_DEB.addStep(steps.ShellCommand(
       command=["dpkg-buildpackage"]))

# Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Ρ„Π°ΠΉΠ» Π½Π° мастСр
rac_gui_build_DEB.addStep(
       steps.FileUpload(
       workersrc=util.Interpolate("../rac-gui_%(prop:version)s-%(prop:release)s_amd64.deb"),
           masterdest=util.Interpolate("/home/buildbot/builds/rac-gui_%(prop:version)s-%(prop:release)s_amd64.deb")
       )
)
rac_gui_build_DEB.addStep(
        steps.MasterShellCommand(
            command=["/usr/local/bin/deploy-ftp.tcl",
             util.Interpolate("--local-file=/home/buildbot/builds/rac-gui_%(prop:version)s-%(prop:release)s_amd64.deb"),
             util.Interpolate("--remote-file=uploads/rac-gui/rac-gui_%(prop:version)s-%(prop:release)s_amd64.deb")]
        )
)

ΠœΡ‹ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ»ΠΈ с DEB, Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ ΠΊ Windows!

rac_gui_build_WIN = util.BuildFactory()

rac_gui_build_WIN.addStep(steps.Git(
       repourl = 'https://bitbucket.org/svk28/rac-gui.git',
       haltOnFailure = True,
       submodules = True,
       mode='full',
       workdir='build',
       progress = True)
)

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π² Windows ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π½Π΅Ρ‚ grep ΠΈ sed (ΠΈΠ»ΠΈ ΠΎΠ½ΠΈ Π΅ΡΡ‚ΡŒ?), Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ PowerShell.

# Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ вСрсии ΠΈΠ· основного Ρ„Π°ΠΉΠ»Π°
rac_gui_build_WIN.addStep(
       steps.SetPropertyFromCommand(
       command="powershell -command "((Get-Content .rac_gui.tcl | Select-String -Pattern 'version:') -split 's')[2]",
       property="version"
       )
    )

# Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ€Π΅Π»ΠΈΠ·Π° ΠΈΠ· основного Ρ„Π°ΠΉΠ»Π°
rac_gui_build_WIN.addStep(
       steps.SetPropertyFromCommand(
       command="powershell -command "((Get-Content .rac_gui.tcl | Select-String -Pattern 'release:') -split 's')[2]",
       property="release"
       )
)

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ запускаСмый Ρ„Π°ΠΉΠ»
rac_gui_build_WIN.addStep(steps.ShellCommand(
       command=["c:binfreewrap.exe", "rac_gui.tcl"]))

# Π·Π°ΠΏΠ°ΠΊΡƒΠ΅ΠΌ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ
rac_gui_build_WIN.addStep(steps.ShellCommand(
       command=["c:Program Files7-zip7z.exe", "a", "-r", util.Interpolate("..rac-gui_%(prop:version)s-%(prop:release)s.win.zip"), "..build"]))

# скопируСм Π½Π° мастСр
rac_gui_build_WIN.addStep(
       steps.FileUpload(
       workersrc=util.Interpolate("..rac-gui_%(prop:version)s-%(prop:release)s.win.zip"),
           masterdest=util.Interpolate("/home/buildbot/builds/rac-gui_%(prop:version)s-%(prop:release)s.win.zip")
       )
)
# Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Ρ„Π°ΠΉΠ» Π½Π° хостинг
rac_gui_build_WIN.addStep(
        steps.MasterShellCommand(
            command=["/usr/local/bin/deploy-ftp.tcl",
            util.Interpolate("--local-file=/home/buildbot/builds/rac-gui_%(prop:version)s-%(prop:release)s.win.zip"),
            util.Interpolate("--remote-file=uploads/rac-gui/rac-gui_%(prop:version)s-%(prop:release)s.win.zip")]
       )
)

# Π’ΡƒΡ‚ опрСдСляСм ΠΊΠ°ΠΊΠΈΠ΅ сборщики Ρƒ нас Π΅ΡΡ‚ΡŒ
c['builders'] = [
        util.BuilderConfig(name="Rac-GUI-RPM-builder", workername='CentOS', factory=rac_gui_build_RPM),
        util.BuilderConfig(name="Rac-GUI-DEB-builder", workername='Debian-10', factory=rac_gui_build_DEB),
        util.BuilderConfig(name="Rac-GUI-WIN-builder", workername='Windows-10', factory=rac_gui_build_WIN),
]

Для увСдомлСния ΠΎ состоянии процСсса сборки ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΡΠ»Π΅ΠΊΡ‚Ρ€ΠΎΠ½Π½ΡƒΡŽ ΠΏΠΎΡ‡Ρ‚Ρƒ.


c['services'] = []

template=u'''
    <h4>Бтатус Π½Π° строСТа: {{ summary }}</h4>
    <p> Използван Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΠΊ: {{ workername }}</p>
    {% for step in build['steps'] %}
    <p> {{ step['name'] }}: {{ step['result'] }}</p>
    {% endfor %}
    <p><b> -- The Buildbot</b></p>
    '''

mailNotifier = reporters.MailNotifier(fromaddr="builder@domain.bg",
             sendToInterestedUsers=False,
             mode=('all'),
             extraRecipients=["admin@domain.bg"],
             relayhost="mail.domain.bg",
             smtpPort=587,
             smtpUser="builder@domain.bg",
             smtpPassword="******",
             messageFormatter=reporters.MessageFormatter(
                                 template=template, template_type='html',
                                 wantProperties=True, wantSteps=True))

c['services'].append(mailNotifier)

# Основни настройки Π½Π° майстора
c['title'] = "ΠŸΡ€ΠΎΡ†Π΅Ρ Π½Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅"
c['titleURL'] = "http://vm-srv-build1:80/"
c['buildbotURL'] = "http://vm-srv-build1/"
c['www'] = dict(port=80,
                plugins=dict(waterfall_view={}, console_view={}, grid_view={}))
c['db'] = {
       'db_url' : "sqlite://state.sqlite"
}

БохраняСм Ρ„Π°ΠΉΠ» ΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ слуТбу мастСра:

systemctl restart buildbot-master

Π’ Π»ΠΎΠ³Π΅ провСряСм, Ρ‡Ρ‚ΠΎ с ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠ΅ΠΉ всС Π² порядкС ΠΈ всё Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² ΡˆΡ‚Π°Ρ‚Π½ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅. ВсС наши Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΠΊΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ, ΠΈ ΠΎΠ± этом Π² Π»ΠΎΠ³Π΅ »»'/home/buildbot/master/twistd.log'»» Π±ΡƒΠ΄Π΅Ρ‚ с Ρ€Π°Π΄ΠΎΡΡ‚ΡŒΡŽ сообщСно:

 2019-07-24 16:50:35+0300 [-] Π—Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° buildbot.tac...
 2019-07-24 16:50:35+0300 [-] Π—Π°Ρ€Π΅Π΄Π΅Π½ΠΎ.
 2019-07-24 16:50:35+0300 [-] twistd 19.2.1 (\/usr\/bin\/python3.6 3.6.8) стартиранС.
 2019-07-24 16:50:35+0300 [-] клас Π½Π° Ρ€Π΅Π°ΠΊΡ‚ΠΎΡ€Π°: twisted.internet.epollreactor.EPollReactor.
 2019-07-24 16:50:35+0300 [-] Π‘Ρ‚Π°Ρ€Ρ‚ΠΈΡ€Π°Π½Π΅ Π½Π° BuildMaster -- buildbot.version: 2.3.1
 2019-07-24 16:50:35+0300 [-] Π—Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° конфигурация ΠΎΡ‚ '\/home\/buildbot\/master\/master.cfg'
 2019-07-24 16:50:36+0300 [-] \/usr\/local\/lib\/python3.6\/site-packages\/buildbot\/config.py:90: buildbot.config.ConfigWarning: [0.9.0 and later] `buildbotNetUsageData` Π½Π΅ Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½ΠΎ ΠΈ ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ Π΅ основно.
        Π’ΠΎΠ·ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€ ΠΏΠΎΠΌΠ°Π³Π° Π½Π° Π΅ΠΊΠΈΠΏΠ° Π·Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° buildbot Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅ основата Π½Π° инсталацията.
        НС сС ΡΡŠΠ±ΠΈΡ€Π° Π»ΠΈΡ‡Π½Π° информация.
        Π‘Π°ΠΌΠΎ информация Π·Π° вСрсията Π½Π° инсталационния софтуСр ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° плъгини сС ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°.
        ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° `ΠΎΡ‚ΠΊΠ°ΠΆΠ΅Ρ‚Π΅` ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅, Π·Π°Π΄Π°Π²Π°ΠΉΠΊΠΈ Ρ‚Π°Π·ΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° Π½Π° None.
        Или Π΄Π° `сС Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅` Π·Π° ΠΏΠΎΠ²Π΅Ρ‡Π΅ информация, Π·Π°Π΄Π°Π²Π°ΠΉΠΊΠΈ я Π½Π° "full".

 2019-07-24 16:50:36+0300 [-] Настройка Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ с URL 'sqlite:\/state.sqlite'
 2019-07-24 16:50:36+0300 [-] настройка Π½Π° Ρ€Π΅ΠΆΠΈΠΌΠ° Π½Π° ΠΆΡƒΡ€Π½Π°Π» Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π½Π° 'wal'
 2019-07-24 16:50:36+0300 [-] добавянС Π½Π° 1 Π½ΠΎΠ²Π° услуга, ΠΏΡ€Π΅ΠΌΠ°Ρ…Π²Π°Π½Π΅ Π½Π° 0
 2019-07-24 16:50:36+0300 [-] добавянС Π½Π° 1 Π½ΠΎΠ² ΠΈΠ·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ Π½Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅, ΠΏΡ€Π΅ΠΌΠ°Ρ…Π²Π°Π½Π΅ Π½Π° 0
 2019-07-24 16:50:36+0300 [-] gitpoller: ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Ρ€Π°Π±ΠΎΡ‚Π½Π° дирСктория '\/home\/buildbot\/master\/gitpoller-work'
 2019-07-24 16:50:36+0300 [-] добавянС Π½Π° 3 Π½ΠΎΠ²ΠΈ строитСли, ΠΏΡ€Π΅ΠΌΠ°Ρ…Π²Π°Π½Π΅ Π½Π° 0
 2019-07-24 16:50:36+0300 [-] добавянС Π½Π° 1 Π½ΠΎΠ² Π³Ρ€Π°Ρ„ΠΈΠΊ, ΠΏΡ€Π΅ΠΌΠ°Ρ…Π²Π°Π½Π΅ Π½Π° 0
 2019-07-24 16:50:36+0300 [-] ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° www плъгин 'waterfall_view'
 2019-07-24 16:50:36+0300 [-] ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° www плъгин 'console_view'
 2019-07-24 16:50:36+0300 [-] ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° www плъгин 'grid_view'
 2019-07-24 16:50:36+0300 [-] Π—ΠΠ‘Π•Π›Π•Π–ΠšΠ: www плъгин 'sitenav' Π΅ инсталиран, Π½ΠΎ Π½Π΅ Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½
 2019-07-24 16:50:36+0300 [-] ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° www плъгин 'waterfall_view'
 2019-07-24 16:50:36+0300 [-] ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° www плъгин 'console_view'
 2019-07-24 16:50:36+0300 [-] ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° www плъгин 'grid_view'
 2019-07-24 16:50:36+0300 [-] Π—ΠΠ‘Π•Π›Π•Π–ΠšΠ: www плъгин 'sitenav' Π΅ инсталиран, Π½ΠΎ Π½Π΅ Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½
 2019-07-24 16:50:36+0300 [-] BuildbotSite стартиранС Π½Π° 80
 2019-07-24 16:50:36+0300 [-] Π‘Ρ‚Π°Ρ€Ρ‚ΠΈΡ€Π°Π½Π΅ Π½Π° Ρ„Π°Π±Ρ€ΠΈΠΊΠ° <buildbot.www.service.BuildbotSite ΠΎΠ±Π΅ΠΊΡ‚ Π½Π° 0x7fe31c2657b8>
 2019-07-24 16:50:36+0300 [-] добавянС Π½Π° 3 Π½ΠΎΠ²ΠΈ Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΡ†ΠΈ, ΠΏΡ€Π΅ΠΌΠ°Ρ…Π²Π°Π½Π΅ Π½Π° 0
 2019-07-24 16:50:36+0300 [-] PBServerFactory стартиранС Π½Π° 4000
 2019-07-24 16:50:36+0300 [-] Π‘Ρ‚Π°Ρ€Ρ‚ΠΈΡ€Π°Π½Π΅ Π½Π° Ρ„Π°Π±Ρ€ΠΈΠΊΠ° <twisted.spread.pb.PBServerFactory ΠΎΠ±Π΅ΠΊΡ‚ Π½Π° 0x7fe31c147470>
 2019-07-24 16:50:37+0300 [-] BuildMaster Ρ€Π°Π±ΠΎΡ‚ΠΈ
 2019-07-24 16:50:37+0300 [-] buildbotNetUsageData: ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅ {'installid': 'b6193b126b96689351d2fe95787c5a03fc0879f9', 'versions': {'Python': '3.6.8', 'Buildbot': '2.3.1', 'Twisted': '19.2.1'}, 'platform': {'platform': 'Linux-4.15.18-10- pve-x86_64-with-centos-7.6.1810-Core', 'system': 'Linux', 'machine': 'x86_64', 'processor': 'x86_64', 'python_implementation': 'CPython', 'version': '#1 SMP PVE 4.15.18-32', 'distro': 'centos:7'}, 'plugins': {'buildbot\/worker\/base\/Worker': 3, 'buildbot\/config\/BuilderConfig': 3, 'buildbot\/schedulers\/basic\/SingleBranchScheduler': 1, 'buildbot\/reporters\/mail\/MailNotifier': 1, 'buildbot\/changes\/gitpoller\/GitPoller': 1, 'buildbot\/steps\/worker\/MakeDirectory': 1, 'buildbot\/steps\/source\/git\/Git': 3, 'buildbot\/steps\/shell\/ShellCommand': 9, 'buildbot\/steps\/package\/rpm\/rpmbuild\/RpmBuild': 1}, 'db': 'sqlite', 'mq': 'simple', 'www_plugins': ['waterfall_view', 'console_view', 'grid_view']}
 2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΠΊ 'CentOS' сС ΠΏΡ€ΠΈΡΡŠΠ΅Π΄ΠΈΠ½ΡΠ²Π° ΠΎΡ‚ IPv4Address(type='TCP', host='127.0.0.1', port=37332)
 2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ workerinfo ΠΎΡ‚ 'CentOS'
 2019-07-24 16:50:37+0300 [-] Π±ΠΎΡ‚ ΠΏΡ€ΠΈΡΡŠΠ΅Π΄ΠΈΠ½Π΅Π½
 2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] Π Π°Π±ΠΎΡ‚Π½ΠΈΠΊ CentOS ΡΠ²ΡŠΡ€Π·Π°Π½ с Rac-GUI-RPM-builder
 2019-07-24 16:50:37+0300 [-] buildbotNetUsageData: buildbot.net ΠΊΠ°Π·Π°: ok
 2019-07-24 16:50:39+0300 [Broker,1,192.168.55.15] Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΠΊ 'Windows-10' сС ΠΏΡ€ΠΈΡΡŠΠ΅Π΄ΠΈΠ½ΡΠ²Π° ΠΎΡ‚ IPv4Address(type='TCP', host='192.168.5.145', port=49831)
 2019-07-24 16:50:39+0300 [Broker,1,192.168.55.15] ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ workerinfo ΠΎΡ‚ 'Windows-10'
 2019-07-24 16:50:40+0300 [-] Π±ΠΎΡ‚ ΠΏΡ€ΠΈΡΡŠΠ΅Π΄ΠΈΠ½Π΅Π½
 2019-07-24 16:50:40+0300 [Broker,1,192.168.55.15] Π Π°Π±ΠΎΡ‚Π½ΠΈΠΊ Windows-10 ΡΠ²ΡŠΡ€Π·Π°Π½ с Rac-GUI-WIN-builder
 2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΠΊ 'Debian-10' сС ΠΏΡ€ΠΈΡΡŠΠ΅Π΄ΠΈΠ½ΡΠ²Π° ΠΎΡ‚ IPv4Address(type='TCP', host='192.168.5.9', port=44430)
 2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ workerinfo ΠΎΡ‚ 'Debian-10'
 2019-07-24 16:50:41+0300 [-] Π±ΠΎΡ‚ ΠΏΡ€ΠΈΡΡŠΠ΅Π΄ΠΈΠ½Π΅Π½
 2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] Π Π°Π±ΠΎΡ‚Π½ΠΈΠΊ Debian-10 ΡΠ²ΡŠΡ€Π·Π°Π½ с Rac-GUI-DEB-builder

Настройката Π΅ Π·Π°Π²ΡŠΡ€ΡˆΠ΅Π½Π°. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ Ρ‚Π΅ΠΊΡƒΡ‰ΠΎΡ‚ΠΎ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅ Ρ‡Ρ€Π΅Π· ΡƒΠ΅Π± интСрфСйса. Π’Π°ΠΌ ΡΡŠΡ‰ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚Π΅ Π³Ρ€Π΅ΡˆΠΊΠΈΡ‚Π΅ Π² Π±ΠΈΠ»Π΄ΠΎΠ²Π΅Ρ‚Π΅, Π΄Π° рСстартиратС зависналия процСс, Π°ΠΊΠΎ Π½Π΅Ρ‰ΠΎ Π½Π΅ Π΅ Π½Π°Ρ€Π΅Π΄ ΠΈ Ρ‚.Π½.

Π’Π΅Π΄Π½Π°Π³Π° слСд стартиранСто Π½Π° Π½Π°ΡˆΠΈΡ‚Π΅ Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΡ†ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π³ΠΈ Π²ΠΈΠ΄ΠΈΡ‚Π΅ ΠΏΡ€Π΅Π· ΠΌΠ΅Π½ΡŽΡ‚ΠΎ β€žBuildsβ€œ -> β€žWorkersβ€œ

Buildbot Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ

Π‘Π»Π΅Π΄ ΠΊΠ°Ρ‚ΠΎ бъдС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ΅Π½ ΠΏΡŠΡ€Π²ΠΈΡΡ‚ процСс Π½Π° Π±ΠΈΠ»Π΄ (Ρ‚.Π΅. ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² Git рСпозитория), Π½Π° ΠΏΡŠΡ€Π²Π°Ρ‚Π° страница Ρ‰Π΅ сС появи ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅Ρ‚ΠΎ Π½Π° процСситС.

Buildbot Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ

Ако ΠΊΠ»ΠΈΠΊΠ½Π΅Ρ‚Π΅ с ΠΌΠΈΡˆΠΊΠ°Ρ‚Π° Π²ΡŠΡ€Ρ…Ρƒ нСобходимия Ρ€Π΅Π΄, Ρ‰Π΅ сС ΠΎΡ‚Π²ΠΎΡ€ΠΈ страница с Ρ‚Π΅ΠΊΡƒΡ‰ΠΎΡ‚ΠΎ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅ Π½Π° Ρ‚ΠΎΠ·ΠΈ процСс, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π²ΠΈΠ΄ΠΈ ΠΊΠ°ΠΊΠ²ΠΎ сС случва, ΠΊΠ°ΠΊΠ²ΠΈ Π³Ρ€Π΅ΡˆΠΊΠΈ ΠΈ Ρ‚.Π½.

Buildbot Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ

Цялата конфигурация Π½Π° мастСр-Π° ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС Π½Π°ΠΌΠ΅Ρ€Π΅Π½Π° Ρ‚ΡƒΠΊ

import os, re
from buildbot.plugins import steps, util, schedulers, worker, changes, reporters

c= BuildmasterConfig ={}

c['workers'] = [ worker.Worker('CentOS', '123456'), worker.Worker('Debian-10', '123456'), worker.Worker('Windows-10', '123456')]
c['protocols'] = {'pb': {'port': 4000}} 

c['change_source'] = []
c['change_source'].append(changes.GitPoller(
    repourl = 'https://bitbucket.org/svk28/rac-gui.git',
    project = 'Rac-GUI',
    branches = True,
    pollInterval = 600
    ))

# слуТба запуска сборки
c['schedulers'] = []
c['schedulers'].append(schedulers.SingleBranchScheduler(
    name="Rac-GUI-schedulers",
    change_filter=util.ChangeFilter(branch='master'),
    builderNames=["Rac-GUI-RPM-builder", "Rac-GUI-DEB-builder", "Rac-GUI-WIN-builder"],
    properties = {'owner': 'admin'}
    ))
@util.renderer
def get_name_version_release(props):
    prog_name = "rac-gui"
    prog_version = "1.0.3"
    prog_release = "3"

    return {
    "prog_name": prog_name
    #"prog_version": prog_version,
    #"prog_release": prog_release
}

rac_gui_build_RPM = util.BuildFactory()

rac_gui_build_RPM.addStep(steps.Git(
    repourl = 'https://bitbucket.org/svk28/rac-gui.git',
    workdir = 'rac-gui',
    haltOnFailure = True,
    submodules = True,
    mode='full',
    progress = True)
    )

# Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ вСрсии ΠΈΠ· основного Ρ„Π°ΠΉΠ»Π°
rac_gui_build_RPM.addStep(
    steps.SetPropertyFromCommand(
    command="grep version ..\/rac-gui\/rac_gui.tcl | grep -oE 'b[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}b'", property="version"
    )
)

# Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ€Π΅Π»ΠΈΠ·Π° ΠΈΠ· основного Ρ„Π°ΠΉΠ»Π°
rac_gui_build_RPM.addStep(
    steps.SetPropertyFromCommand(
    command="grep release ..\/rac-gui\/rac_gui.tcl | grep -oE 'b[0-9]{1,3}b'", property="release"
    )
)

rac_gui_build_RPM.addStep(steps.ShellCommand(
    command=["tar", "czf", util.Interpolate("\/home\/buildbot\/rpmbuild\/SOURCES\/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz"), "..\/rac-gui"]))

rac_gui_build_RPM.addStep(steps.ShellCommand(
    command=["cp", "..\/rac-gui\/rac_gui.spec", "\/home\/buildbot\/rpmbuild\/SPECS\/rac_gui.spec"]))

rac_gui_build_RPM.addStep(steps.ShellCommand(
    command=["sed", "-i", util.Interpolate("s\/.*Version:.*\/Version:t%(prop:version)s\/"), "\/home\/buildbot\/rpmbuild\/SPECS\/rac_gui.spec"]))

rac_gui_build_RPM.addStep(steps.ShellCommand(
    command=["sed", "-i", util.Interpolate("s\/.*Release:.*\/Release:t%(prop:release)s\/"), "\/home\/buildbot\/rpmbuild\/SPECS\/rac_gui.spec"]))

rac_gui_build_RPM.addStep(steps.RpmBuild(
    specfile="\/home\/buildbot\/rpmbuild\/SPECS\/rac_gui.spec",
    dist='.el5',
    topdir='\/home\/buildbot\/rpmbuild',
    builddir='\/home\/buildbot\/rpmbuild\/build',
    rpmdir='\/home\/buildbot\/rpmbuild\/RPMS',
    sourcedir='\/home\/buildbot\/rpmbuild\/SOURCES'
    ))

# Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Ρ„Π°ΠΉΠ» Π½Π° мастСр
rac_gui_build_RPM.addStep(
    steps.FileUpload(
    workersrc=util.Interpolate("\/home\/buildbot\/rpmbuild\/RPMS\/noarch\/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm"),
        masterdest=util.Interpolate("\/home\/buildbot\/builds\/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm")
    )
)

rac_gui_build_RPM.addStep(
    steps.FileUpload(
    workersrc=util.Interpolate("\/home\/buildbot\/rpmbuild\/SOURCES\/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz"),
        masterdest=util.Interpolate("\/home\/buildbot\/builds\/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz")
    )
)

rac_gui_build_RPM.addStep(
    steps.MasterShellCommand(
    command=["\/usr\/local\/bin\/deploy-ftp.tcl",
     util.Interpolate("--local-file=\/home\/buildbot\/builds\/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm"),
     util.Interpolate("--remote-file=uploads\/rac-gui\/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm")]
    )
)

rac_gui_build_RPM.addStep(
    steps.MasterShellCommand(
    command=["\/usr\/local\/bin\/deploy-ftp.tcl",
     util.Interpolate("--local-file=\/home\/buildbot\/builds\/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz"),
     util.Interpolate("--remote-file=uploads\/rac-gui\/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz")]
    )
)
####################################
##      DEB 
####################################

rac_gui_build_DEB = util.BuildFactory()

rac_gui_build_DEB.addStep(steps.Git(
    repourl = 'https://bitbucket.org/svk28/rac-gui.git',
    haltOnFailure = True,
    submodules = True,
    mode='full',
    workdir='build',
    progress = True)
    )

# Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ вСрсии ΠΈΠ· основного Ρ„Π°ΠΉΠ»Π°
rac_gui_build_DEB.addStep(
    steps.SetPropertyFromCommand(
    command="grep version rac_gui.tcl | grep -oE 'b[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}b'", property="version"
    )
)

# Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ€Π΅Π»ΠΈΠ·Π° ΠΈΠ· основного Ρ„Π°ΠΉΠ»Π°
rac_gui_build_DEB.addStep(
    steps.SetPropertyFromCommand(
    command="grep release rac_gui.tcl | grep -oE 'b[0-9]{1,3}b'", property="release"
    )
)

# ΠŸΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΡƒΠ΅ΠΌ запускаСмый Ρ„Π°ΠΉΠ»
rac_gui_build_DEB.addStep(steps.ShellCommand(
    command=["mv", "rac_gui.tcl", "racgui"]))

# ПомСняСм ΠΏΡƒΡ‚ΠΈ ΠΊ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°ΠΌ
rac_gui_build_DEB.addStep(steps.ShellCommand(
    command=["sed", "-i", "s+^set dir(lib)+set dir(lib) \/usr\/share\/rac-gui\/lib ;#+g", "racgui"]))

# ПомСняСм ΠΏΡƒΡ‚ΠΈ ΠΊ Ρ„Π°ΠΉΠ»Π°ΠΌ
rac_gui_build_DEB.addStep(steps.ShellCommand(
    command=["sed", "-i", "s+[pwd]+\/usr\/share\/rac-gui+g", "racgui"]))

# Π·Π°Π°Ρ€Ρ…ΠΈΠ²ΠΈΡ€ΡƒΠ΅ΠΌ исходники
rac_gui_build_DEB.addStep(steps.ShellCommand(
    command=["tar", "czf", util.Interpolate("..\/rac-gui_%(prop:version)s.orig.tar.gz"), "."]))

# Π‘ΠΎΠ±Π΅Ρ€Ρ‘ΠΌ ΠΏΠ°ΠΊΠ΅Ρ‚
rac_gui_build_DEB.addStep(steps.ShellCommand(
    command=["dpkg-buildpackage"]))

# Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Ρ„Π°ΠΉΠ» Π½Π° мастСр
rac_gui_build_DEB.addStep(
    steps.FileUpload(
    workersrc=util.Interpolate("..\/rac-gui_%(prop:version)s-%(prop:release)s_amd64.deb"),
        masterdest=util.Interpolate("\/home\/buildbot\/builds\/rac-gui_%(prop:version)s-%(prop:release)s_amd64.deb")
    )
)

rac_gui_build_DEB.addStep(
    steps.MasterShellCommand(
    command=["\/usr\/local\/bin\/deploy-ftp.tcl",
     util.Interpolate("--local-file=\/home\/buildbot\/builds\/rac-gui_%(prop:version)s-%(prop:release)s_amd64.deb"),
     util.Interpolate("--remote-file=uploads\/rac-gui\/rac-gui_%(prop:version)s-%(prop:release)s_amd64.deb")]
    )
)
############################################
#       WIN
############################################

rac_gui_build_WIN = util.BuildFactory()

rac_gui_build_WIN.addStep(steps.Git(
    repourl = 'https://bitbucket.org/svk28/rac-gui.git',
    haltOnFailure = True,
    submodules = True,
    mode='full',
    workdir='build',
    progress = True)
    )

# Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ вСрсии ΠΈΠ· основного Ρ„Π°ΠΉΠ»Π°
rac_gui_build_WIN.addStep(
    steps.SetPropertyFromCommand(
    command="powershell -command "((Get-Content .rac_gui.tcl | Select-String -Pattern 'version:') -split 's')[2]",
    property="version"
    )
)

# Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ€Π΅Π»ΠΈΠ·Π° ΠΈΠ· основного Ρ„Π°ΠΉΠ»Π°
rac_gui_build_WIN.addStep(
    steps.SetPropertyFromCommand(
    command="powershell -command "((Get-Content .rac_gui.tcl | Select-String -Pattern 'release:') -split 's')[2]",
    property="release"
    )
)

# Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ запускаСмый Ρ„Π°ΠΉΠ»
rac_gui_build_WIN.addStep(steps.ShellCommand(
    command=["c:binfreewrap.exe", "rac_gui.tcl"]))

# Π·Π°ΠΏΠ°ΠΊΡƒΠ΅ΠΌ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ
rac_gui_build_WIN.addStep(steps.ShellCommand(
    command=["c:Program Files7-zip7z.exe", "a", "-r", util.Interpolate("..rac-gui_%(prop:version)s-%(prop:release)s.win.zip"), "..build"]))

# скопируСм Π½Π° мастСр
rac_gui_build_WIN.addStep(
    steps.FileUpload(
    workersrc=util.Interpolate("..rac-gui_%(prop:version)s-%(prop:release)s.win.zip"),
        masterdest=util.Interpolate("\/home\/buildbot\/builds\/rac-gui_%(prop:version)s-%(prop:release)s.win.zip")
    )
)

# Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Ρ„Π°ΠΉΠ» Π½Π° хостинг
rac_gui_build_WIN.addStep(
    steps.MasterShellCommand(
    command=["\/usr\/local\/bin\/deploy-ftp.tcl",
     util.Interpolate("--local-file=\/home\/buildbot\/builds\/rac-gui_%(prop:version)s-%(prop:release)s.win.zip"),
     util.Interpolate("--remote-file=uploads\/rac-gui\/rac-gui_%(prop:version)s-%(prop:release)s.win.zip")]
    )
)

c['builders'] = [
        util.BuilderConfig(name="Rac-GUI-RPM-builder", workername='CentOS', factory=rac_gui_build_RPM),
        util.BuilderConfig(name="Rac-GUI-DEB-builder", workername='Debian-10', factory=rac_gui_build_DEB),
        util.BuilderConfig(name="Rac-GUI-WIN-builder", workername='Windows-10', factory=rac_gui_build_WIN),
]

c['services'] = []

template=u'''
<h4>Бтатус Π½Π° строСТа: {{ summary }}</h4>
<p> Използван Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΠΊ: {{ workername }}</p>
{% for step in build['steps'] %}
<p> {{ step['name'] }}: {{ step['result'] }}</p>
{% endfor %}
<p><b> -- The Buildbot</b></p>
'''

mailNotifier = reporters.MailNotifier(fromaddr="112@icvibor.bg",
          sendToInterestedUsers=False,
          mode=('all'),
          extraRecipients=["my@domain.local"],
          relayhost="mail.domain.local",
          smtpPort=587,
          smtpUser="buildbot@domain.local",
          smtpPassword="**********",
          messageFormatter=reporters.MessageFormatter(
                                 template=template, template_type='html',
                                 wantProperties=True, wantSteps=True))

c['services'].append(mailNotifier)

c['title'] = "ΠŸΡ€ΠΎΡ†Π΅Ρ Π½Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅"
c['titleURL'] = "http://vm-srv-build1:80/"

c['buildbotURL'] = "http://vm-srv-build1/"

c['www'] = dict(port=80,
                plugins=dict(waterfall_view={}, console_view={}, grid_view={}))
c['db'] = {
    'db_url' : "sqlite:///state.sqlite"
}

ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈ

ΠŸΡ€ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ°Ρ‚Π° Π½Π° статията бяха ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ΠΈ слСднитС ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈ:

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster