(áá¯á¶
áá±áá¹áá¬ááŸáá·áºááŒá¬ážááá¯ááºáá«á!
áá»áœááºáá±á¬áºá·á¡áááºááŸá¬ Evgeniy Cherkináá»áœááºá¯ááºááẠááá¹áá¯áá°ážáá±á¬áºáá±ážáá¯áá¹ááá®áá áºáá¯ááŸá ááœá¶á·ááŒáá¯ážááá¯ážáááºáá±ážá¡ááœá²á·ááœáẠáááá¯ááááºáá¬áá áºáŠážááŒá áºáááºá Polymetal ááŒá áºáááº.
ááá±á¬áá»ááºááŒá®ážáá áºáá¯ááᯠá áááºáá±á¬á¡áá«ááœááºá "áááºážááᯠááááºážááááºážááẠáááºááá·áºáá±á¬á·ááºáá²ááºááᯠá¡áá¯á¶ážááŒá¯ááẠá¡áá±á¬ááºážáá¯á¶ážááŒá áºááááºáž" áᯠá áááºááœá±ážáá±á¬áá¬áá«áááºá á¡áá¯ááºáá®ááá±á¬áá»ááºáá áºáá¯ááẠáá±á¬ááºáá¬ážááŸááºážááá¯ááºáá® á¡ááá·áºáá»á¬ážá áœá¬ááᯠááŒááºáááºážáááºá á€á¡ááá·áºáá»á¬ážáááœááºážáááºáá»á¬ážááᯠá¡ááá¯á¡áá»á±á¬ááºáá¯ááºáá±á¬ááºááá·áºá¡áá« áá±á¬ááºážááœááºáá«áááºá IT ááá±á¬áá»ááºáá áºáá¯á áá¬ážááŸááºážá¡áá áºááᯠáá¯ááºáá±ážááá·áº á¡ááá¯á¡áá»á±á¬áẠáá¯ááºáááºážá ááºááᯠáááºážááá¯ááºááá¯áẠáá±á«áºáááºá á ááºáááºáááŒááºáá±á«ááºážá ááºážáá±áž. BuildBot á€áá¯ááºáááºážá ááºááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºáá¬ááœáẠáá»áœááºá¯ááºááá¯á·á¡ááœáẠáá±á¬ááºážááœááºáá±á¬ áááºáá±á¬ááºáá áºáŠážááŒá áºáá¬áá²á·áááºá
á€áá±á¬ááºážáá«ážááœáẠááŒá
áºááá¯ááºáá»á±áá»á¬ážááᯠááŒá¯á¶áá¯á¶áá¯á¶ážáááºáááºááŒááẠáá¯á¶ážááŒááºáá²á·áááºá BuildBot. áá®áá±á¬á·ááºáá²á áá¬á
áœááºážáá±á¬ááºááá¯ááºááá²á áá°á·ááᯠáááºááá¯áá»ááºážáááºááŒá®áž áá°áá²á· áá¯á¶ááŸááºáááá±á¬ááºáá²á· á¡áá¯ááºáááºáá¶áá±ážááᯠáááºááá¯áááºáá±á¬ááºááá²á ááá·áºá
ááºáá±á«áºááŸá ááá·áºááá±á¬áá»ááºááᯠáááºáá±á¬ááºááŒááºážááŸáá·áº á
ááºážáááºááŒááºážá¡ááœáẠá¡áá¯ááºáááºáá±á¬ááºááŸá¯áá
áºáᯠáááºáá®ážááŒááºážááŒáá·áº áá»áœááºá¯ááºááá¯á·áá¡ááœá±á·á¡ááŒá¯á¶ááᯠáááºááá¯ááºááá¯áẠá¡áá¯á¶ážáá»ááá¯ááºáá«áááºá
á¡ááŒá±á¬ááºážá¡áá¬
á¡ááŒá±á¬ááºážá¡áá¬
1. á¡áááºááŒá±á¬áá·áº BuildBot?
á¡áááºá habr-e ááŸá¬ á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯áá²á· áááºáááºáá²á· áá±á¬ááºážáá«ážááœá±ááᯠááœá±á·áá²á·ááááºá á
ááºáááºáááŒááºáá±á«ááºážá
ááºážáá±áž á¡áá¯á¶ážááŒá¯ááŒááºáž BuildBot. á¥ááá¬-
áááº! áá°ááá¯á·áá²á· ááá±á¬áá»ááºááœá±ááŸá¬ ááááºáá¯á¶ážáá°ážáá¬ážá ááœááºáá¬áá¬ááá±á¬á· áá¯ááºáá«áááºá
áá«ááᯠáá°ááœá±áá¯á¶ážáá±áá²á· áá¯áá¹ááááá¬áá² Buildbot? áá±á¬ááºáá¯á¶ážááœááºá á¡ááŒá¬ážáááááá¬áá»á¬ážááŸááááºá Cruise Control О Jenkins. áá«áá®ááá¯ááŒá±áááºá á¡áá¯ááºá¡áá»á¬ážá á¯á¡ááœáẠJenkins á¡ááŸááºááá¬ážááẠáá¯á¶áá±á¬ááºáááá·áºáááºá á¡ááŸáá·áºáá»á BuildBot - ááŒá¿áá¬áá»á¬ážááᯠááá¯ážááá¯ážááŸááºážááŸááºáž ááŒá±ááŸááºážáá±áá»áááºááœáẠááá¯ááá¯ááá¹áá¬ááºááŸá¯ááŸááááºá Jenkins. ááœá±ážáá»ááºááŸá¯ááẠááá·áºá¡ááœááºááŒá áºáááºá ááá¯á·áá±á¬áº áá»áœááºá¯ááºááá¯á·ááẠááœá¶á·ááŒáá¯ážáá²áá áºááŸááºááá±á¬áá»ááºá¡ááœáẠáááááá¬áá áºáá¯ááᯠááŸá¬ááœá±áá±áá±á¬ááŒá±á¬áá·áºá ááá¯ážááŸááºážáá±á¬á¡ááá·áºáá»á¬ážááŸá áááºáᬠá¡ááŒááºá¡ááŸááºá¡áá»áá¯ážáááºáá±á¬ááºááŸá¯ááŸáá·áº áá°ážááŒá¬ážáá±á¬á¡ááºáá¬áá±á·á áºáááºáá±á¬ááºááŸá¯á áá áºáá áºáá¯áááŸáááẠááœáá·áºááŒá¯ááá·áºáá áºáá¯á¡á¬áž á¡áááºááŒá±á¬áá·áºááœá±ážáá»ááºááááºážá
áá áºááŸááºááá±á¬áá»ááºááᯠpython ááŒáá·áºáá±ážáá¬ážáá±á¬áá°áá»á¬ážá¡ááœááºá áá±ážááœááºážáá±á«áºáá¬áááº- "ááá±á¬áá»ááºááœááºá¡áá¯á¶ážááŒá¯ááá·áºáá¬áá¬á áá¬ážááŸáá·áºáááºáááºááŒá®áž ááŸááºážáááºážáá±á¬ interface ááŸááá±á¬ áá±á«ááºážá ááºážááŸá¯á áá áºááᯠá¡áááºááŒá±á¬áá·áºáááœá±ážáá»ááºáááááºážá ááá¯á¡áá»áááºááẠá¡áá»áá¯ážáá»á±ážáá°ážáá»á¬ážááᯠáááºáááºáááºá¡áá»áááºááŒá áºáááºá BuildBot.
áá®áá±á¬á· áá«ááá¯á·áá²á· "áá°áááᬠáá±ážááœá²"á áá»áœááºáá±á¬áºááá¯ááºááá¯ááºá¡ááœáẠá¡ááºá¹áá«áááºáá±ážáá¯ááᯠáá±á¬áºáá¯ááºáá¬ážáá«áááºá BuildBot:
- áááºážááẠGPL ááá¯ááºá ááºá¡á±á¬ááºááœáẠopen source áá°áá±á¬ááºáá áºáá¯ááŒá áºáááºá
- á€áááºááŸá¬ python ááᯠconfiguration tool áá áºáá¯á¡áá±ááŸáá·áº ááá¯á¡ááºáá±á¬ áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážá áá±á¬áºááŒáá»ááºááŒá áºáááºá
- áááºážááẠá ááºážáá±ážááœá²áá»ááºážáááá·áº á ááºá០áá¯á¶á·ááŒááºááŸá¯ááᯠáááºáá¶áááŸáááẠá¡ááœáá·áºá¡áá±ážááŒá áºáááºá
- á€á¡áá¬áá»á¬ážááẠHost áá áºáá¯á¡ááœáẠá¡áááºážáá¯á¶ážááá¯á¡ááºáá»ááºáá»á¬ážááŒá áºáááºá ááŒáá·áºáá»ááºááŒááºážááẠpython ááŸáá·áº twisted ááá¯á¡ááºááŒá®áž virtual machine ááŸáá·áº java machine áááá¯á¡ááºáá«á
2. BuildMaster áŠážáá±á¬ááºáá±á¬ á¡áá°á¡á
áá¬áááºááœá²áá±ááŸá¯áááá¯áá¬ááááá¯ááŒá
áºáááºá BuildMaster. áááºážááẠáááºáá±á¬ááºááŸá¯áá
áºáá¯ááŒá
áºáááº-
- ááŒá±áá¬áá¶áááºá ááá±á¬áá»ááºáááºážááŒá áºáá áºáááºááœáẠá¡ááŒá±á¬ááºážá¡áá²áá»á¬áž
- ááá¯á·áá±ážáá«áááºá ááá±á¬áá»ááºááá¯áááºáá±á¬ááºááŒá®áž áááºážááá¯á ááºážáááºáááºá¡ááœáẠWorker service ááŸáá¯ááºáá±á¬ááºááá·áºááá·áº command áá»á¬áž
- á¡ááŒá±á¬ááºážááŒá¬ážáááºá áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážáááááºáá»á¬ážááŸáá·áº áááºáááºá á¡áá¯á¶ážááŒá¯áá°áá»á¬áž
BuildMaster ááá¯ááºááŸáááá·áºááŒááºáááºáá¬ážáááºá master.cfg. á€ááá¯ááºááẠroot ááœááºááŒá áºáááºá BuildMaster. áá±á¬ááºááá¯ááºážááŸá¬ áá® root ááᯠáááºááá¯áááºáá®ážáá¬ážáá²ááá¯áá¬ááᯠááŒá±á¬ááŒáá«áááºá ááá¯ááºááá¯ááºááá¯ááºá master.cfg áá±á«áºááá¯ááŸá¯áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááá·áº python script áá«ááŸááááºá BuildBot.
áá±á¬ááºáá áºáᯠá¡áá±ážááŒá®ážáá¯á¶áž á¡áá¬ááá¹áᯠBuildBot áá¬áááºáá áºáá¯ááŸááááºá á¡áá¯ááºááá¬áž. á€áááºáá±á¬ááºááŸá¯ááᯠááá°áá®áá±á¬ OS áá áºáá¯ááŒáá·áº á¡ááŒá¬ážáá±á¬ host ááœáẠá áááºá¡áá¯á¶ážááŒá¯ááá¯ááºáááºá ááá¯á·ááá¯áẠááá¯áá±áá¬ááœáẠááŒá áºááá¯ááºáááºá BuildMaster. áááºážááẠáááºážáááá¯ááºááá¯áẠáááºáá±á·áá»áºáá»á¬ážááŸáá·áº ááááºážááŸááºáá»á¬ážáá«ááŸááá±á¬ á¡áá°ážááŒááºáááºáá¬ážáá±á¬ virtual áááºáááºážáá»ááºááœááºáááºáž áááºááŸáááá¯ááºáááºá á€áá²á·ááá¯á·áá±á¬ virtual áááºáááºážáá»ááºáá»á¬ážááᯠpython utilities áá»á¬ážá¡áá¯á¶ážááŒá¯á ááŒááºáááºááá¯ááºáááºá virtualenvá venv.
BuildMaster á¡áááá·áºáá»á¬ážááᯠáá°ááá¯ááºážááᯠáá¯ááºááœáŸáá·áºáááºá á¡áá¯ááºááá¬áž-y, áá°, áá áºáááº, ááŒáá·áºáááºážáá±ážáá±á¬áºáá°áá ááá¯ááá¯áááºááŸá¬á ááá±á¬áá»ááºáá áºáá¯áááºáá±á¬ááºááŒááºážááŸáá·áºá ááºážáááºááŒááºážáá¯ááºáááºážá ááºáááºáááºáá¯ááºáá±á¬ááºááá¯ááºáááºááá¯ááœá±á·ááááºá á¡áá¯ááºááá¬áž-e á Windows áá²á· Linux ááá¯áá¯á¶ážáá²á· áááŒá¬áž Worker áá±á«áºááŸá¬á
ááœááºááœá¬ááẠááá±á¬áá»ááºá¡áááºážá¡ááŒá áºáá¯ááºáá áºáá¯á á®ááœáẠááŒá áºáá±á«áºáááºá á¡áá¯ááºááá¬áž-e
3. áááºáááºááŒááºážá
áá«ááᯠááœá¬ážááŒáá¡á±á¬ááºá áá»áœááºá¯ááºááẠUbuntu 18.04 ááᯠhost á¡ááŒá áºá¡áá¯á¶ážááŒá¯áá«áááºá á¡á²áá«áá±á«áºááŸá¬ áá áºáá¯áááºáááºá BuildMaster-a ááŸáá·áº áá áºáᯠá¡áá¯ááºááá¬áž-a áá«áá±ááá·áº á¡áááºáá¯á¶áž python3.7 ááᯠinstall áá¯ááºááá¯á· ááá¯áá«áááºá
sudo apt-get update
sudo apt-get install python3.7
3.7.2 á¡á á¬áž python3.7.1 ááá¯á¡ááºáá°áá»á¬ážá¡ááœááºá á¡á±á¬ááºáá«ááá¯á·ááᯠááŒá¯áá¯ááºááá¯ááºáá«áááºá
sudo apt-get update
sudo apt-get software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get install python3.7
sudo ln -fs /usr/bin/python3.7 /usr/bin/python3
pip3 install --upgrade pip
áá±á¬ááºáá áºááá·áºááá±á¬á· install áá¯ááºáá«á ááœá áºáᬠá О 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 # СПбÑÑвеММП ÑЎеÑÑ Ðž ÑПзЎаеЌ
mkdir worker
buildbot-worker create-worker --umask=0o22 --keepalive=60 worker localhost:4000 yourWorkerName password
ááŒá±ážáá²á·á¡áá« á¡áá¯ááºááá¬ážááá¯á·áá±á¬áẠdefault á¡áá±ááŒáá·áº áááºážááẠáááºáá®ážáááºááŒá áºáááºá /home/habr/worker ááœááºáá±á¬áºááŒáá¬ážáá±á¬ ááá±á¬áá»ááºá¡áááºááŒáá·áº ááá¯ááºááœá² master.cfg. ááá±á¬áá»ááºá¡áááºááŒáá·áº ááá¯ááºááœá²áá²ááœáẠáááºážááẠáááºážááœáŸááºáá áºáᯠáááºáá®ážáááºááŒá áºáááºá áááºáá±á¬ááºááŒá®ážáá±á¬á· áááºááŒá®ážáá¯ááºáááºá ááœááºááœá¬áááº. á¡áá¯ááºáááºážááœáŸáẠá¡áá¯ááºááá¬áž- áá«ááá¯ááºáá¬áá áºáá¯ááŒá áºáá¬áááá·áºáááºá /home/habr/yourProject/build.
"ááœáŸá±áá±á¬á·
ááᯠáá»áœááºá¯ááºááẠááááºá
á¬ááá¯ááºá¡ááœáẠáá±ážáá¬ážáááº- áá¬ááºááœáŸááºážáá
áºáᯠáá¬á
áᬠáá¶á០áá±á¬ááºážááá¯áááºá á¡áá¯ááºááá¬ážscript ááœáẠrun áááºááœáá·áºááŒá¯áá»ááºáá»á¬ážáááŸááá±á¬ááŒá±á¬áá·áºá€áááºážááœáŸááºááœááºá¡áá±ážááŸáá¯ááºáá±á¬ááºááŒá®ážáá¯ááºáá±á¬ááºáááºááá¯ááºáá«á á¡ááŒá±á¡áá±ááᯠááŒá¯ááŒááºááẠáá±á¬á·áá
áºáᯠááá¯á¡ááºáá«áááºá
BuildMaster О á¡áá¯ááºááá¬áž á¡áá»ááºážáá»ááºáž áááºááœááºááŸá¯ áá°áá±á¬ááºáá«á ááŒááºááœá¬ážá ááŒá áºáá»ááºá á¡áá¯ááºááá¬áž áá®á áá¯á¶á·ááŒááºááŸá¯áááá¯á· á¡áá»áááºáá áºáᯠá á±á¬áá·áºááááºá BuildMaster-A áá¯á¶á·ááŒááºááŸá¯áááŸááá«á áá»áááºáááºááŸá¯ááᯠááŒááºáááºá áááºáááºá áá±á¬á· --keepalive=60 ááŒá®ážááẠá¡áá»áááºááᯠááœáŸááºááŒááá¯á·áá²ááá¯áááºá ááẠááŒááºáááºá áááºáááºá
5. ááœá²á·á ááºážááŸá¯á áááºážáá»ááºáááºážá¡ááá·áºááá·áº
configuration áá»á¬áž BuildMaster áá»áœááºá¯ááºááá¯á·ááẠcommand ááá¯áá¯ááºáá±á¬ááºááá·áºá ááºááááºááŒááºážááœááºáá¯ááºáá±á¬ááºáááºá áááºáá®áž-áá¬á áá¬. áá»áœááºá¯ááºááá¯á·áá¡ááŒá±á¡áá±ááœááºá á€áááºááŸá¬áááºážááœáŸááºáá áºáá¯ááŒá áºáááºá /home/habr/master. ááœá²á·á ááºážááŸá¯ááá¯áẠmaster.cfg áááŸááá±ážáá«á ááá¯á·áá±á¬áº command ááá¯ááºááá¯ááºá ááá¯ááºááᯠáááºáá®ážááŒá®ážááŒá áºáááºá master.cmg.ááá°áá¬. áááºážááᯠá¡áááºááŒá±á¬ááºážááẠááá¯á¡ááºáááºá master.cfg.ááá°áᬠв master.cfg
mv master.cfg.sample master.cfg
áá«ááá¯ááœáá·áºááŒáá·áºáá¡á±á¬áẠmaster.cfg. áááºážááœáẠá¡áááºá¡áá¬áá«áááºáááºááᯠáá±á·áá¬ááŒáá·áºááŒáá«á áá¯á·á ááá¯á·áá±á¬áẠáá»áœááºá¯ááºááá¯á·áááá¯ááºááá¯áẠconfiguration file ááá¯ááŒá¯áá¯ááºáááºááŒáá¯ážá á¬ážááŒáá«á áá¯á·á
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 - ááœá²á·á
ááºážááŸá¯ááá¯ááºá á¡ááŒá±áá¶á¡áááá¬ááºá áááºážááᯠconfiguration file ááœáẠááá·áºááœááºážááá«áááºá á¡áá¯á¶ážááŒá¯áááœááºáá°á
á±áááºá ááœá²á·á
ááºážááŸá¯áá¯ááºááœáẠalias ááᯠááááºáááºáá¬ážáááºá "á". ááœá²á·áá¶ááááºáá»á¬áž
5.2 áá¯ááºáá¬ážáá»á¬áž
c['workers'] = [worker.Worker("example-worker", "pass")]
áá®áá
áºáá«áá±á¬á· áá»áœááºáá±á¬áº ááœáŸááºááŒáá«áááºá BuildMaster-y á
á¬áááºáž á¡áá¯ááºááá¬áž-sá ááá¯ááºááá¯áẠá¡áá¯ááºááá¬áž áá«ááá¯á·áááºáá®ážáá²á·áááºá
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 repository ááᯠá¡áá¯á¶ážááŒá¯áááºá
áááá¡ááŒááºážá¡áá¯á¶ááẠáááºáááá¯ááŸá±á¬ááºáá¬ááá¯á· áááºážááŒá±á¬ááºážááŒá áºáááºá
áá¯ááºáá«ááẠáá±ážáááºááŸá folder ááá¯á·áááºážááŒá±á¬ááºážááá¯ááá¯ááºá á¬ážááŒá¯áááºá á¡áá¯ááºááá¬áž- áááºááŸáá·áº ááŸááºáá /home/habr/worker/yourProject/build git ááẠrepository á local version ááᯠááááºážáááºážáááºááŒá áºáááºá
áá¬áááŸá²á ááá¯ááºáá¬ááá·áºáá±á¬ repository ááœáẠáá®ážááŒá¬ážáá¬áááœá²áá áºáá¯áá«ááŸááááºá
á á áºáááºážáá¬á á¡á²áá®áá±á¬áẠá áá¹ááá·áºá¡áá±á¡ááœáẠáá«ááŸááá«áááºá BuildMaster á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážá¡ááœáẠrepository ááᯠá á áºáááºážáá±á¬ááºáá°áá«áááºá
ááá±á¬áá»ááºáá áºáá¯á ááá¯ááŸá±á¬ááºáá¬ááá¯á· ááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážááᯠááŒá±áá¬áá¶ááẠáááºážáááºážáá»á¬ážá áœá¬ ááŸááá«áááºá
á¡ááá¯ážááŸááºážáá¯á¶ážáááºážáááºážááá±á¬á· áá²áá¯á¶ááá¯ááá¯áááºááŸá¬á BuildMaster áá¬áá¬ááᯠááá¯ááŸá±á¬ááºááŸá¯ááŒáá·áº á¡áá«á¡á¬ážáá»á±á¬áºá
áœá¬ á
á
áºáááºážáá±á¬ááºáá°áááºá á¡áááºááá¯á· áá»á°ážááœáẠááá¯á·áá±á¬áẠrepository ááœáẠááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážááᯠáááºáááºá
á±áááºá BuildMaster á¡áááºážáááºááŸá±á¬áá·áºááŸá±ážááŸá¯ááŸáá·áºá¡áá° á¡ááœááºážááá¯ááºážá¡áá¬ááá¹áá¯áá
áºáá¯ááᯠáááºáá®ážáááá·áºáááºá ááœá±á¬áá»ážáá² áááºážááᯠááŒá
áºáááºááá¯ááºááœááºáá°áᶠáá±ážááá¯á·áá«á Scheduler ááá¯ááá±á¬áá»ááºáááºáá±á¬ááºááŒááºážááŸáá·áº á
ááºážáááºááŒááºážá
ááá·áº á¡ááá·áºáá»á¬ážááᯠá
áááºáá±á¬ááºááœááºáá«áááºá á¡áá¯ááºááá¬áž-e á€á¡ááá·áºáá»á¬ážá¡áááºá០ááœáŸááºááŒáá«áááºá update ááᯠááá¯ááŸá±á¬ááºááŸá¯á á¡ááá¡áá»áá±á«áºáááºá á¡áá¯ááºááá¬ážáááºážááẠrepository á áá±áááœááºáž áááá¹áá°ááᯠáááºáá®ážáá±ážáááá·áºáááºá á€áá¯ááºáááºážá
ááºáá¡áá±ážá
áááºá¡áá»ááºá¡áááºáá»á¬ážááᯠáá±á¬ááºá¡ááá¯ááºážááŸá
áºáá¯ááœáẠá¡á±á¬ááºááœááºáá±á¬áºááŒáá¬ážáááºááŒá
áºáá«áááºá (
repository áá áºáá¯ááá¯á· á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠááŒá±áá¬áá¶ááẠááá¯á á¡á¶áááºááœááºáá»áá±á¬ áááºážáááºážááŸá¬ áááºážááᯠáááºáá¶áá±á¬ááºááœááºáá±ážáá±áá±á¬ áá¬áá¬á០áááºáá±á·áá»áºáá»á¬ážááᯠááá¯ááºááá¯ááºáá±ážááá¯á·ááŒááºážááŒá áºáááºá BuildMaster- ááá±á¬áá»ááºá¡áááºážá¡ááŒá áºáá¯ááºáá»á¬ážááá¯ááŒá±á¬ááºážáá²ááŒááºážá¡ááŒá±á¬ááºážá á€ááá á¹á ááœááºáá¯ááŸá áº, developer á¡ááŒá áºáááŒá¬áá®ááŒá¯áá¯ááºáááºá áá»á°ážááœááºááá±á¬áá»áẠrepository áá«áá±á¬ áá¬áá¬ááẠáááºáá±á·ááºá»áá áºá á±á¬áẠáá±ážááá¯á·áá«áááá·áºáááºá BuildMaster-y áá áºáááºá áá°ááẠá¡áá¬ááá¹áá¯áá áºáá¯ááᯠáááºáá®ážááŒááºážááŒáá·áº áááºážááᯠááŒá¬ážááŒááºáááá·áºáááºá PBCchangeSource. ááá¯á·áá±á¬áẠá€á¡áá¬á¡á¬áž ááœáŸá²ááŒá±á¬ááºážáá±ážáá«áááºá Scheduler ááá¯ááá±á¬áá»ááºááá¯áááºáá±á¬ááºáááºááŸáá·áº á ááºážáááºááẠá¡ááá·áºáá»á¬ážááᯠá¡áááºááœááºážáá±ážáááºá á€áááºážáááºážá á¡áá±ážááŒá®ážáá±á¬ á¡á áááºá¡ááá¯ááºážáá áºáá¯ááẠáááºážááŸáá·áº á¡áá¯ááºáá¯ááºáá«áááºá áá»áááº- ááá¯ááŸá±á¬ááºáá¬ááŸá server scripts áá»á¬ážá áá¬ááºááœáŸááºážáá²ááŸá¬ áá»áááº-a áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááᯠá á®áá¶áá±á¬ááºááœááºááá·áºá¡áá«ááœáẠáá¬áááºááŸááááºá áá»á°ážááœááº-eá áááºááẠutility ááá¯áá±á«áºááá¯áááºááá¯á¡ááºáááºá áá±ážááá¯á·ááŸá¯ ááœááºáááºááááºá á¬ááᯠáááºááŸááºáá«á BuildMaster-A áá¬ážáá±á¬ááºááá·áº ááœááºáááºáá±á«ááºááᯠáááºáááºáž áááºááŸááºááẠááá¯á¡ááºáááºá PBCchangeSource. PBCchangeSourceá áá¬ážáá ááºá á¡á áááºá¡ááá¯ááºážáá áºáá¯ááŒá áºáááºá BuildMaster-A á€áááºážáááºážáááºááœáá·áºááŒá¯áá»ááºááá¯á¡ááºáááá·áºáááºá admin áá²á·-a ááá±á¬áá»áẠrepository áááºááŸááá¬áá¬áá¬áá±á«áºááœááºá áááºááẠááááá¯á¶áž repository ááᯠá¡áááºáá°ážááẠááá¯á¡ááºáá«áááºá
5.4 á¡áá»áááºááá¬ážáá»á¬áž
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"]))
á¡á
á®á¡á
ááºááœá²áá°áá»á¬áž - á€á¡áá¬ááẠááá±á¬áá»ááºá áááºáááºááŒááºážááŸáá·áº á
ááºážáááºááŒááºážááœááºážáááºáá
áºáá¯áá¯á¶ážááᯠá¡á
áá»áá¯ážááá·áºá¡áá»ááºáá
áºáá¯á¡ááŒá
Ạáá¯ááºáá±á¬ááºááá·áº á¡áá¬áá
áºáá¯ááŒá
áºáááºá
á¡á²áá®á¡ááŒá±á¬ááºážá¡áá²ááœá±ááᯠááŸááºáááºážáááºáá¬ážáááºá change_source, á¡áá¯ááºááá¯ááºáááºážá
ááºáá»á¬ážááœááºá¡ááœááºááŒá±á¬ááºáž BuildBot-a ááá·áºááœááºááẠááœá±á¬áá»ážáá² ááá¯ááá¯ááºážá Sheduler áááºážááá¯á·ááᯠá¡ááŒá±áá¶á ááá±á¬áá»ááºáááºáá±á¬ááºááŒááºážáá¯ááºáááºážá
ááºááᯠá
áááºááẠáá±á¬ááºážááá¯ááŸá¯áá»á¬ážááᯠáááºáá±á¬ááºáá«áááºá ááá¯á·áá±á¬áºá á€áá±á¬ááºážááá¯ááŸá¯áá»á¬ážááᯠáááºážá
á®ááá¯á· áá±á¬ááºáááºááœáŸá²ááŒá±á¬ááºážááá·áºá¡áá«ááœááºáááºáž áá¯á¶ážááŒááºáááºá á¡áá¬ááá¹áá¯áá
áºáá¯
á¡áá¯áááºááŸá á¥ááá¬ááŸá¬ á¡á²áá®ááᯠááŒááºáááºá á¡á
á®á¡á
ááºááœá²áá°áá»á¬áž 2 á¡ááá¯ááºážáááºáá®ážáá¬ážáááºá ááá¯á·á¡ááŒááºá áá
áºáá¯áá»ááºážá
á®ááœááºáááºážáááá¯ááºááá¯ááºá¡áá»áá¯ážá¡á
á¬ážááŸááááºá
SingleBranchScheduler - á¡áá»áááºááá¬ážáá±á«áºááŸááá°ááŒáá¯ááºá¡áá»á¬ážáá¯á¶ážá¡áááºážáá»á¬ážáá²ááŸáá áºáá¯á áááºážááẠá¡ááá¯ááºážá¡áááºáá áºáá¯ááᯠá á±á¬áá·áºááŒáá·áºáá±ááŒá®áž áááºážááœáẠááŸááºáááºážáááºáá¬ážáá±á¬ ááŒá±á¬ááºážáá²ááŸá¯áá áºáá¯ááŒáá·áº á¡á áá»áá¯ážáááºá á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠáá°ááŒááºáá±á¬á¡áá«á áááºáá±á¬ááºááẠáá±á¬ááºážááá¯áá»ááºáá±ážááá¯á·ááŒááºážááᯠááŸá±á¬áá·áºááŸá±ážááá¯ááºááẠ(á¡áá°ážááá·áºáááºáá±á¬ááºá¡ááœááºáž áááºááŸááºáá¬ážááá·áº áá¬áááᯠááœáŸá±á·ááá¯ááºážááá¯ááºáááºá treeStableTimer) á·á á¡áẠáá¬ááá»á±á¬ááᯠááœááºááŒáááá·áºá¡áá»áááºááá¬ážáá¡áááºááá¯áááºááŸááºáááºá BuildBot-web interface á IN ChangeFilter áá¬áááœá²ááœáẠá¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠáá»á±á¬áºááŒááºááŒá®ážáá±á¬áẠáá±á¬ááºáá¯ááºáá±ážá¡ááœáẠáá±á¬ááºážááá¯áá»ááºáá áºáá¯áá±ážááá¯á·ááẠá¡áá»áááºááá¬ážááᯠááœáŸááºááŒáá±á¬ filter áá áºáá¯ááᯠáááºááŸááºáááºá IN áááºáá±á¬ááºáá°á¡áááºáá»á¬áž á¡áááºááá¯áá±á¬áºááŒáááºá áááºáá±á¬ááºáá°-a ááᯠáá±á¬ááºáááºážáááºážááŒá¬á០áááºááŸááºáá«áááºá áá»áœááºá¯ááºááá¯á·áááá á¹á ááœáẠá¡áááºááẠááá±á¬áá»ááºá¡áááºááŸáá·áº áá°áá®áá«áááº- áááºáááá±á¬áá»ááº.
ForceScheduler á¡ááœááºááá¯ážááŸááºážáá±á¬á¡áá¬á á€á¡áá»áááºááá¬ážá¡áá»áá¯ážá¡á á¬ážááᯠáá±á¬ááºá áºááá áºááŒáá·áº á¡á áá»áá¯ážáááºá BuildBot-web interface á ááá·áºáááºáá»ááºáá»á¬ážááẠá¡ááœááºážááŸáá·áºáá°áá±á¬ á¡ááŸá áºáá¬áááŸááááºá SingleBranchScheduler.
PS áá¶áá«áẠáá ááŒá
áºááá¯ááºááẠá¡áááºááŒá±ááŸá¬áá«á
á¡áá»áááºáá¬á á¡áá»áááºáááºááŸááºáá¬ážáá±á¬ ááŒáááºááŸá¯ááºážáá
áºáá¯ááœáẠáá¯ááºáá±á¬ááºááá·áº á¡áá»áááºááá¬ážáá
áºáá¯ááŒá
áºáááºá áá±á«áºááá¯ááŸá¯ááŸá¬ á€áá²á·ááá¯á· ááŒá
áºáá¯á¶ááááºá
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": "."}))
á¡áá»áááºá¡ááá¯ááºBuildTimer á€áá¬áá¡ááá¯ááºážá¡ááŒá¬ážááᯠá áá¹ááá·áºááá¯ááºážá¡ááœááºáž áááºááŸááºáááºá
áá±á¬ááºá
ááºáá¯á¶ áá®ážááŒá¬ážáá
áºáá¯áááºáá®ážáááºá áááºáá±á¬ááºááŒá®ážáá±á¬ áááºáá±á¬ááºáá° ááá¯á· ááá¯á·áá±ážáááºá á¡áá¯ááºááá¬ážá á¡ááá¯áá« áá±á¬ááºá
ááºáá¯á¶ ááá¯ááºáá¬áááá·áº á¡ááá·áºáá»á¬ážááᯠáá±á¬áºááŒáááºá á¡áá¯ááºááá¬áž-y áááºážáááºážááá¯áá±á«áºááá¯ááŒááºážááŒáá·áº á¡ááá·áºáá»á¬ážááᯠáááºáá±á¬ááºážáá±ážáá«áááºá addStep
á€á¥ááá¬ááœáẠááááá¯á¶ážáááºááá·áºáá±á¬á¡ááá·áºááŸá¬ git clean -d -f -f âxááá¯á¡áá« git áá¯ááºáá á¹á ááºáž. á€áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááᯠááá·áºáááºáá»ááºááœáẠááá·áºááœááºážáá¬ážáááºá áááºážáááºážááŸááºážááŸááºážáááºážáááºážáá±á¬áºááŒáá¬ážááŒááºážáááŸááá±á¬áºáááºáž áá¯á¶áá±áááºááá¯ážááᯠááá¯ááá¯áááºá áááºáááºáá±á¬. ááá·áºáááºáá»áẠáá¯áẠ= 'ááá¯ážááŒáŸáá·áº' ááá¯ááºáá»á¬ážááẠááá¯ááºáá»á¬ážááŸááᬠáááºážááœáŸááºááŸááŒá áºááŒá±á¬ááºáž ááœáŸááºááŒáááºá áá»á±áá»áááºárepository ááŸáá»á±á¬ááºáá¯á¶ážáá±áá»áááºááœááºá ááááááá¯ááºáá¬ážáá«á
áá¯ááááááºááá·áºááá·áºá¡ááá·áºááŸá¬ script ááá¯áá±á«áºááŒááºážááŒá áºáááºá á ááºážáááºááŒááºáž ááá·áºáááºáá»ááºáá»á¬ážááŸáá·áºá¡áá° áááᯠáá±ážááœáẠá¡áá¯ááºááá¬áž-a áááºážááœáŸááºá០/home/habr/worker/yourProject/build PATHONPATH= áááºáááºážáá»ááºááŒá±á¬ááºážáá²ááŸá¯ááŸáá·áº... ááá¯á·ááŒá±á¬áá·áºá áááºááẠáááºáááá¯ááºááá¯áẠscript áá»á¬ážááá¯áá±ážááá¯ááºááŒá®áž áá±ážááœáẠáááºážááá¯á·ááᯠexecute áá¯ááºááá¯ááºáááºá á¡áá¯ááºááá¬áž- ááŒá±ááŸááºážááá¯ááºáž util.ShellCommand. ဠscript áá»á¬ážááᯠrepository ááœááºááá¯ááºááá¯ááºááá·áºááá¯ááºáááºá ááŒá®ážáá±á¬ áá»á±áá»áááºá-e áá°ááá¯á·áá²áá»áááá·áºáááºá /home/habr/worker/yourProject/build. ááá¯á·áá±á¬áºá ááá¯á·áá±á¬áẠ"buts" ááŸá áºáá¯ááŸááááºá
- á¡áá¯ááºááá¬áž áá±á¬á·ááŒáá·áºáááºáá®ážááá«áááºá
--umask áá«á០áá±á¬ááºááá¯ááºážááŸá¬ ááœááºáá»ááºááœáá·áº á¡ááœáá·áºá¡áá±ážááœá±ááᯠáááááºáááºáá¬ážáá°ážá ááœááºááœá¬áááº-a - ááœáẠgit ááœááºáž-e ဠscript áá»á¬áž á ááá¯ááºááá¯ááºááŸá¯ ááᯠááẠáááºááŸááºááẠááá¯á¡áẠááẠá¡áá±á¬ááºáááºáá±á¬áºááá¯ááºáá±á¬áá«ááŒá±á¬áá·áº áá±á¬ááºááá¯ááºážááŸá¬ áá»á±áá»áááºá-e ááẠGit script ááá¯áá¯ááºáá±á¬ááºáááºá¡ááœáá·áºá¡áá±ážááá¯á¶ážááŸá¯á¶ážáá«á
áá±á¬ááºáá¯ááºáá±ážááá¬áž áá
c['builders'] = []
c['builders'].append(util.BuilderConfig(name="runtests",
workernames=["example-worker"],
factory=factory))
áá¬á¡ááŒá±á¬ááºážáá²á áááºáá±á¬ááºáá° ááŒá±á¬ááŒáá²á·áá«áááºá
c['builders'] = []
c['builders'].append(util.BuilderConfig(name="yourProject",
workernames=["yourWorkerName"],
factory=factory))
ááá¯áá«áááºážááᯠparameters ááœá±á¡ááŒá±á¬ááºážááŒá±á¬ááŒáááºá BuilderConfig.
áá¬ááá»á±á¬ááᯠá¡áááºááá¯áááºááŸááºáááºá áááºáá±á¬ááºáá°-a á€ááœááºáá»áœááºá¯ááºááá¯á·á¡áááºáá±ážáá¬ážáááºá áááºáááá±á¬áá»ááº... ááá¯ááá¯áááºááŸá¬ áá±á«áºáááºá á¡áá¯ááºááá¬áž- á€áááºážááá¯áááºáá®ážáááá·áºáááºá /home/habr/worker/yourProject/build. Sheduler ááá¯ááá¯ááºááŸá¬ááẠáááºáá±á¬ááºáá° á€á¡áááºááŒáá·áºáá¬á
á¡áá¯ááºááá¬ážá¡áááºáá»á¬áž á á¬ááœááºáá«ááŸááááºá á¡áá¯ááºááá¬áž-sá áá áºáá¯áá»ááºážá á®ááᯠááá·áºááá«áááºá c['á¡áá¯ááºááá¬ážáá»á¬áž'].
á¡áá¯ááºáá¯á¶ - áá®ážááŒá¬áž áááºáá±á¬ááºáááºážááŸáá·áºáááºá ááºáá±áááºá áááºáá±á¬ááºáá°. á¡áá¬ááá¹áá¯ááᯠáá±ážááá¯á·áá±á¬áºáá°áááºá áááºáá±á¬áẠá¡áá±á«áº á¡áá¯ááºááá¬áž á€ááœááºáá«áááºáá±á¬ á¡ááá·áºáá»á¬ážá¡á¬ážáá¯á¶áž ááŒá®ážááŒá±á¬ááºááẠáááºáá±á¬ááº-a
6. ááá·áºááá¯ááºááá¯ááºááœá²á·á ááºážáá¯á¶á¥ááá¬
á€áááºááŸá¬ áá»áœááºá¯áẠá¡ááá¯ááŒá¯áá¬ážáá±á¬ á¥ááá¬á¡á¬ážááŒáá·áº ááá±á¬áá»ááºáááá¯áá¬áááºáá¬ááŒá
áºáááºá BuildBot
.
áá¬ážááŸááºážááááºážáá»á¯ááºááŸá¯á
áá
áºá¡ááŒá
Ạá¡áá¯á¶ážááŒá¯áá«áááºá svn. repository ááá¯ááºááá¯ááºá cloud áá
áºáá»áá¯ážáá»áá¯ážááŸá¬ áááºááŸááá«áááá·áºáááºá á€áááºááŸá¬ á€ááááºááá¯ááºáááááºá
á¬ááŒá
áºáááºá
BuildMaster О á¡áá¯ááºááá¬áž áá°áá®áá±á¬ host áá±á«áºááœáẠrun project.host .BuildMaster áááºážáááá¯ááºáá»á¬ážááᯠfolder áá áºáá¯ááœááºááááºážáááºážáá«á /home/habr/master. á¡áá¯ááºááá¬áž áááºážááᯠá¡á±á¬ááºáá«áááºážááŒá±á¬ááºážááœáẠááááºážáááºážáá¬ážáááºá /home/habr/worker. áááºááœááºáá±ážáá¯ááºáááºážá áẠBuildMaster-a ááŸáá·áº á¡áá¯ááºááá¬áž-a ááᯠprotocol á¡á port 4000 ááŸáááá·áºáá¯ááºáá±á¬ááºáááºá BuildBot-aá á¡á²áá« 'pb' áááá¯ááá¯áá±á¬á
áá áºááŸááºááá±á¬áá»ááºááᯠPython ááœáẠáá¯á¶ážáá¯á¶ážáá±ážáá¬ážáááºá áá¬áááºááŸá¬ áááºážáááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážááᯠááŒá±áá¬áá¶áááºá á á®áá¶áá¯ááºáá±á¬ááºááá¯ááºáá±á¬ ááá¯ááºáá áºáá¯áááºáá®ážáááºá á á¬ááœááºá á¬áááºážáá»á¬ážááᯠáááºáá®ážáááºááŸáá·áº á ááºážáááºáá¯ááºáá±á¬ááºááẠááŒá áºáááºá áá¡á±á¬ááºááŒááºáá«áá áá±á¬á·ááºáá²áá±ážáá¬ážáá°á¡á¬ážáá¯á¶áž áá¡á±á¬ááºááŒááºááá·áºáá¯ááºáá±á¬ááºáá»ááºáá áºáá¯ááŸáááŒá±á¬ááºáž á¡á®ážáá±ážááºááŒáá·áº áááºáá±á·áá»áºáá±ážááá¯á·ááẠááá¯á¡ááºáá«áááºá
áááºááŒáááŸá¯ BuildBot port 80 ááᯠáá»áááºáááºáá«áááºá project.host. Apatch ááá¯ááá·áºááœááºážáááºáááá¯á¡ááºáá«á á á¬ááŒáá·áºááá¯ááºá áá áºá áááºáá áºááá¯ááºážá¡áá±ááŒáá·áº áááẠáááºáá¬áá¬ááŸááá±ááŒá®á BuildBot áááºážááá¯á¡áá¯á¶ážááŒá¯áááºá
á¡ááœááºážá¡áá»ááºá¡áááºáá»á¬ážááᯠááááºážáááºážááẠBuildBot бÑЎеЌОÑпПлÑзПваÑÑ áá»á¬áž.
á á¬ááá¯á·áááºá¡ááœáẠá¡áááºááŸááºáá áºáŠáž ááá¯á¡ááºáááºá smtp.your.domain - áááºážááẠmail ááŸá á¬áá»á¬ážáá±ážááá¯á·ááœáá·áºááŒá¯áááºá [á¡á®ážáá±ážááºááá¯áá¬ááœááºáá¬ážáááº] á á áºááŸááºááŒá±á¬ááºážá¡áá±á¬ááºá¡áá¬ážáááŸááá²á 'á¡áááºááŸááºá¡áá±á«áºááœááºáááºážásmtp ââáááá Ạáááá ááŸá¬ ááŒá¬ážáááºá
ááŒá áºá ááºááœáẠáá«áááºáá° ááŸá áºáŠážááŸááááºá admin áá²á· О á¡áá¯á¶ážááŒá¯áá°ááá¯. á á®áá¶á¡á¯ááºáá»á¯ááºáááºá BuildBot. á¡áá¯á¶ážááŒá¯áá°ááẠáá»á°ážááœááºáá°ááŒá áºáááºá áá»á°ážááœááº-sá
Exacutable file ááŸáááá·áºáá¯ááºáá±ážáá«áááºá pyinstaller. Documentation ááŸáááá·áºáá¯ááºáá±ážáá«áááºá 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 ЌПжМП пПЎклÑÑОÑÑÑÑ Ðº ÑеÑвеÑÑ c ip:xxx.xx.xxx.xx. ÐÐŸÐ¹ÐŽÑ Ð¿ÐŸÐŽ habr/password, забÑаÑÑ ÑПбÑаММÑй executable Ñайл Ñ ÐŽÐžÑекÑПÑОО ~/worker/yourProject/build/dist.</p>
<p><b>ÐПÑÑÑПеМОе бÑлП пÑПОзвеЎеМП ÑеÑез Buildbot</b></p>
'''
sendMessageToAll = reporters.MailNotifier(fromaddr="[email protected]",
sendToInterestedUsers=True,
lookup="your.domain",
relayhost="smtp.your.domain",
smtpPort=1025,
mode="warnings",
extraRecipients=['[email protected]'],
messageFormatter=reporters.MessageFormatter(
template=template_html,
template_type='html',
wantProperties=True,
wantSteps=True)
)
c['services'] = [sendMessageToAll]
c['title'] = "The process of bulding"
c['titleURL'] = "http://project.host:80/"
c['buildbotURL'] = "http://project.host"
c['www'] = dict(port=80,
plugins=dict(waterfall_view={}, console_view={}, grid_view={}))
c['db'] = {
'db_url' : "sqlite:///state.sqlite"
}
ááááá¯á¶ážáááºááá¯á¡ááºáááº
áá±á¬ááºáá áºááá·áºááŸá¬ áááºáá±á¬ááºááŸá¯ááᯠá áááºáááºááŒá áºáááºá BuildMasters ááá¯
sudo buildbot start /home/habr/master
ááá¯á·áá±á¬ááºáááºáá±á¬ááºááŸá¯ááá¯á áááºáá«á á¡áá¯ááºááá¬áž-a
buildbot-worker start /home/habr/worker
á¡áááºááá·áºá áá² Buildbot á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠááŒá±áá¬áá¶ááŒá®áž á¡á áá»áá¯ážáá«áááºá áá»á°ážááœááº-y ááẠsvná¡áááºáá±á¬áºááŒáá« áááá¯áá¬ááá¬ááŒáá·áº ááá±á¬áá»ááºáá áºáá¯ááᯠáááºáá±á¬ááºááŒááºážááŸáá·áº á ááºážáááºááŒááºáž á¡ááá·áºáá»á¬ážááᯠáá¯ááºáá±á¬ááºááŒááºážá
á¡á±á¬ááºááŸá¬ áá»áœááºáá±á¬áº á¡áááºáá±á¬áºááŒáá« á¡ááºá¹áá«áááºá¡áá»áá¯á·ááᯠáá±á¬áºááŒáá«áááºá master.cfgá
6.1 áááºá master.cfg ááá¯á·ááœá¬ážáá¬áááºážááœááº
áá«á·á
á¬áá±ážáá±áá»ááẠmaster.cfg á¡ááŸá¬ážá¡ááœááºážáá»á¬ážá
áœá¬ááŸááááºááŒá
áºáá±á¬ááŒá±á¬áá·áº ááŸááºáááºážááá¯ááºááá¯áááºááŸá¯ááẠááá¯á¡ááºáááºááŒá
áºáá«áááºá á¡ááŒá
Ạááááºážáááºážáá¬ážáááºá BuildMaster-ec áááááááºážááŒá±á¬ááºáž /home/habr/master/twistd.log, ááŸáá·áºáá±ážááœáẠá¡áá¯ááºááá¬ážáááááááºážá
áẠ/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 áá¬áááœá²ááá¯áá¬áááºáá±á¬ááºáááºá áááºá ááº. áá»áŸáá¯á·ááŸááºáááºážááŒááºáá±á¬áá±á¬áẠsplit_file=util.svn.split_file_alwaystrunk á ááºážáá»á¥áºážá ááºážáááºážáá»á¬áž áááºááŸááºáááº- ááá¯ááºááœá²ááœá²á·á ááºážáá¯á¶ááᯠáááºáá²á·ááá¯á· ááŒáá¯ááœá²áááºáááºážá svn áá áºááá¯ááºážáá»á¬ážáá±á«áºááœááºá áá°ááá¯á·ááá¯áááºáž ááœá±áá»áá¯ážáááºážááŒá±á¬ááºážáá±ážáááºá áááºážáá¡ááŸáá·áº split_file_alwaystrunk repository ááœááºáᬠáá«áááºáááºáᯠááá¯ááŒááºážááŒáá·áº áá¯ááºáááºážá ááºááᯠááá¯ážááŸááºážá á±áááºá áááºá ááº.
Ð á¡áá»áááºááá¬ážáá»á¬áž ááœáŸááºááŒááẠChangeFilteráááºáá°ááŒááºáá²á á¡áááºáá°áá»áŸá á¡ááá¯ááºážá¡áááºáá áºáá¯ááŸáá·áº áá±á«ááºážáááºá áááºá áẠáá±ážáá¬ážááá·áº á¡áááºážá¡ááœá²á·á¡ááá¯ááºá split_file_alwaystrunk. á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠáá¯á¶á·ááŒááºááŒááºážá áááºá ááºááœáŸááºáááºáááºá áááºáá±á¬ááºáá° áá¬áááºáá²á· áááºáááá±á¬áá»ááº.
áá¯ááºááá¹áááá»á¬áž áá¯ááºáááºážá ááºáááá¯ááºááŸááºá¡ááŒá Ạáááºáá±á¬ááºááŸá¯ááŸáá·áº á ááºážáááºááŸá¯ááááºáá»á¬ážááᯠá¡ááºááºáááºá áááºáá¶áááŸáááẠá€áá±áá¬ááœáẠááá¯á¡ááºáá«áááºá
á¡ááá·áº áááºáá±á¬ááº-a ááœááºááœá¬ááẠrepository á local version ááœááºááŸááá±á¬ áááºááá·áºááá¯ááºáááᯠá¡ááŒá®ážá¡ááá¯áẠáá»ááºááá¯ááºá áœááºážááŸááááºá á¡áá¯ááºááá¬áž-A ááŒá®ážá០á¡ááŒáá·áºáá¯ááºáá«á svn á¡ááºááááº. áá¯ááºááᯠááá·áºáááºáá»ááºááŒáá·áº ááŒááºáááºáááºááŸááºáá¬ážáááºá mode=á¡ááŒáá·áº, method=fresh. ááá·áºáááºáá»áẠhaltOnTailure á¡á²á·ááá¯ááŒá±á¬ááẠsvn á¡ááºáááẠá¡ááŸá¬ážá¡ááœááºážáá áºáá¯ááŒáá·áº áá¯ááºáá±á¬ááºáááºááŒá áºááŒá®ážá ááá¯á·áá±á¬áẠáá±á¬ááºáááºáá¯ááºáá±á¬ááºááŸá¯áá»á¬ážááẠá¡áááá¹áá¬ááºáááŸááá±á¬ááŒá±á¬áá·áº áááºáá±á¬ááºááŒááºážááŸáá·áº á ááºážáááºááŒááºážáá¯ááºáááºážá ááºáá áºáá¯áá¯á¶ážááᯠááá¯ááºážáá¶á·áá¬ážááá·áºáááºá
6.3 ááá·áºáá¶áá±ážá á¬- ááááºážáá±á¬ááºáá»á¬ážááᯠááŒá±áá¬ááá¯ááºááœáá·áºááŸááááºá
ááááºážáá±á¬ááºááœá±ááᯠá¡á®ážáá±ážááºááŒáá·áº á¡ááŒá±á¬ááºážááŒá¬ážáá»ááºáá»á¬ážááᯠáá±ážááá¯á·ááẠáááºáá±á¬ááºááŸá¯áá
áºáá¯ááŒá
áºáááºá
template_html=u'''
<h4>СÑаÑÑÑ Ð¿ÐŸÑÑÑПеММПгП ÑелОза: {{ summary }}</h4>
<p>ÐÑпПлÑзÑеЌÑй ÑеÑÐ²ÐžÑ ÐŽÐ»Ñ Ð¿ÐŸÑÑÑаеМОÑ: {{ workername }}</p>
<p>ÐÑПекÑ: {{ projects }}</p>
<p>ÐÐ»Ñ ÑПгП ÑÑП Ð±Ñ Ð¿ÐŸÑЌПÑÑеÑÑ ÐžÐœÑеÑÑÐµÐ¹Ñ ÑпÑÐ°Ð²Ð»ÐµÐœÐžÑ Ð¿ÑПйЎОÑе пП ÑÑÑлке: {{ buildbot_url }}</p>
<p>ÐÐ»Ñ ÑПгП ÑÑП Ð±Ñ Ð¿ÐŸÑЌПÑÑеÑÑ ÑезÑлÑÑÐ°Ñ ÑбПÑкО пÑПйЎОÑе пП ÑÑÑлке: {{ build_url }}</p>
<p>ÐÑпПлÑзÑÑ WinSCP ЌПжМП пПЎклÑÑОÑÑÑÑ Ðº ÑеÑвеÑÑ c ip:xxx.xx.xxx.xx. ÐÐŸÐ¹ÐŽÑ Ð¿ÐŸÐŽ habr/password, забÑаÑÑ ÑПбÑаММÑй executable Ñайл Ñ ÐŽÐžÑекÑПÑОО ~/worker/yourProject/build/dist.</p>
<p><b>ÐПÑÑÑПеМОе бÑлП пÑПОзвеЎеМП ÑеÑез Buildbot</b></p>
'''
sendMessageToAll = reporters.MailNotifier(fromaddr="[email protected]",
sendToInterestedUsers=True,
lookup="your.domain",
relayhost="smtp.your.domain",
smtpPort=1025,
mode="warnings",
extraRecipients=['[email protected]'],
messageFormatter=reporters.MessageFormatter(
template=template_html,
template_type='html',
wantProperties=True,
wantSteps=True)
)
c['services'] = [sendMessageToAll]
áááºáá±á·ááºá»ááá¯á·ááá¯ááºáááºá
MailNotifier á¡ááŒá±á¬ááºážááŒá¬ážáá»ááºáá»á¬ážáá±ážááá¯á·ááẠá¡á®ážáá±ážááºááᯠá¡áá¯á¶ážááŒá¯áááºá
áá¯á¶á
á¶ááœááº_html ááááºážááœáŸá¬á¡ááœáẠá
á¬áá¬ážáá¯á¶á
á¶ááᯠáááºááŸááºáá±ážáááºá HTML ááᯠmarkup áááºáá®ážáááºá¡áá¯á¶ážááŒá¯áááºá áááºážááá¯á¡ááºáá»ááºááŒáá·áºááŒá¯ááŒááºáááºá
MailNotifier á¡á±á¬ááºáá« á¡ááŒá±á¬ááºážááŒáá»ááºáá»á¬áž áá«áááºáááºá
fromaddr - áá°ááá¯ááºážááááºážááœáŸá¬áááºáá¶áááŸáááá·áºááááºá á¬á
á áááºáááºá á¬ážáá±á¬á¡áá¯á¶ážááŒá¯áá°áá»á¬ážáá¶áá±ážááá¯á·áá«á=True ááẠáááºáá®ážáá¬ážááá·áº ááá¯ááºááŸááºááŸáá·áº á¡áá¯á¶ážááŒá¯áá°áá¶ááá¯á· áááºáá±á·áá»áº áá±ážááá¯á·áááºá áá»á°ážááœááº.
á¥á®ážáá±á¬á·áá¬ááẠâ ááááºážááœáŸá¬ááᯠáááºáá¶áááŸáááá·áº á¡áá¯á¶ážááŒá¯áá°áá»á¬ážá á¡áááºáá»á¬ážááœáẠááá·áºááœááºážáááá·áº áá±á¬ááºáááºááœá²á áá«ááŒá±á¬áá·áº admin áá²á· áá¯á¶ážá áœá²áá°á ááááºá á¬ááŸá¬ ááááºážááœáŸá¬ááᯠáááºááá¯áááºáá¶ááá²á [á¡á®ážáá±ážááºááá¯áá¬ááœááºáá¬ážáááº].
relayhost áá¬áá¬ááœáá·áºáá¬ážááá·áº hostname ááᯠáááºááŸááºáá±ážáááºá smtpáá áºá¥á®áž smptPort áá¬ážáá±á¬ááºáá±á¬ ááá¯á·ááºáá¶áá«ááºááᯠáááºááŸááºáááºá smtp áá¬áá¬á
mode="ááááá±ážáá»ááº" á¡áááºážáá¯á¶áž á¡ááá·áºáá áºááá·áºááŸáááŸáᬠá á¬ááá¯á·ááŒááºážááᯠáá¯ááºáá±á¬ááºááá·áºáááºáᯠááá¯áááºá áááºáá±á¬ááº-aá á¡ááŒá±á¡áá±áá»ááºááœááºááŸá¯ ááá¯á·ááá¯áẠááááá±ážáá»ááºááŒáá·áº á¡áá¯á¶ážáááºáááºá á¡á±á¬ááºááŒááºááŸá¯ááá á¹á ááœááºá ááááºážááœáŸá¬áá±ážááá¯á·áááºáááá¯á¡ááºáá«á
á¡ááá¯áááºáá¶áá°áá»á¬áž ááá¯ááºááŸááºááŸáá·áº áá±ážááá¯á·áááá·áº áá¯áá¹ááá¯ááºáá»á¬ážá¡ááŒáẠáá±ážááá¯á·áááá·áº áá¯áá¹ááá¯ááºáá»á¬ážá á¬áááºážáá«ááŸááááºá áá»á°ážááœááº.
áááºáá±á·áá»áºáá¯á¶á ᶠáááºáá±á·áá»áºáá±á¬áºáááºá áááºážá ááá°áá¬áá¯á¶á á¶ááŸáá·áº ááá¯á·á០áááŸáááá¯ááºáá±á¬ ááááºážááŸááºá¡á á¯áá áºá á¯ááᯠáááºááŸááºááá·áº á¡áá¬ááá¹áá¯áá áºáá¯ááŒá áºáááºá jinja2. á¡á ááŸááá²á· ááœá±ážáá»ááºááŸá¯áá»á¬áž wantProperties=á¡ááŸáẠО wantSteps=á¡ááŸáẠáááŸáááá¯ááºáá±á¬ ááááºážááŸááºáá»á¬ážá¡á á¯ááᯠáááºááŸááºáá«á
with['services']=[sendMessageToAll] áá»áœááºá¯ááºááá¯á·á áááºáá±á¬ááºááŸá¯áá»á¬ážá á¬áááºážááᯠáá±ážáá±á¬ááºáá«áááºá á¡á á®áááºáá¶á á¬áááºááœááºážáá°.
áá«ááá¯á·áá¯ááºáá²á·áááº! áá¯ááºáá°áá«áááºá
áá»áœááºá¯ááºááá¯á·ááẠáá»áœááºá¯ááºááá¯á·áááá¯ááºááá¯áẠconfiguration ááá¯áááºáá®ážáá²á·ááŒá®áž áááºážááẠáá¯ááºáá±á¬ááºááá¯ááºá áœááºážááŸááááºááᯠááŒááºááœá±á·áá²á·áááºá BuildBot. ááá·áºááá±á¬áá»ááºááá¯áááºáá®ážááẠá€áááááá¬ááẠááá¯á¡ááºáááºááŸááááŸá áá¬ážáááºááẠáá¯á¶áá±á¬ááºáááºáᯠáá»áœááºá¯ááºáááºáááºá áááºážáá°á·ááá¯á áááºáááºá á¬ážáá¬áž ááá·áºá¡ááœáẠá¡áá¯á¶ážáááºááŸá¬áá¬ážá áá°áá²á· á¡áá¯ááºáá¯ááºááᬠá¡áááºááŒá±áá¬áž? á¡á²áá®á¡áá«áá»ááẠáá®áá±á¬ááºážáá«ážááᯠá¡áá»ááºážááŸá®ážááá±ážáá«áá°ážá
ááŒá®ážáá±á¬á· áá±á¬ááºáááºá ááá±á¬áºáááºááŸááºáááºá¡ááá¯ááºážá¡áááºážááᯠá¡áá¯á¶ážááŒá¯áá»ááºáá«áááºá BuildBotááá¯áá»ááºáá¬áááºá áááºá áœá²á á¬á¡á¯ááºááœá±ááᯠáá¬áá¬ááŒááºááŒá®áž áá±á¬ááºááẠá¥ááá¬ááœá±áá±á¬áẠááŸááá«áá±ážáááºá
ááá·áºá¡á¬áá¯á¶á
áá¯ááºááŸá¯á¡ááœáẠá¡á¬ážáá¯á¶ážááᯠáá»á±ážáá°ážáááºáá«áááºá áá¶áá±á¬ááºážáá«á
á±á
source: www.habr.com