(์ด๋ฏธ์ง by
ะัะธะฒะตั!
๋ด ์ด๋ฆ ์๋ธ๊ฒ๋ ์ฒด๋ฅดํจ, ์ ๋ ๊ด์ฐํ์ฌ ๊ฐ๋ฐํ์ ํ๋ก๊ทธ๋๋จธ์ ๋๋ค. ํด๋ฆฌ ๋ฉํ.
๋๊ท๋ชจ ํ๋ก์ ํธ๋ฅผ ์์ํ ๋ "์๋น์ค๋ฅผ ์ ๊ณตํ๋ ๋ฐ ์ด๋ค ์ํํธ์จ์ด๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์๊ฐ?"๋ผ๊ณ ์๊ฐํ๊ธฐ ์์ํฉ๋๋ค. IT ํ๋ก์ ํธ๋ ๋ค์ ๋ฒ์ ์ ์ถ์ํ๊ธฐ ์ ์ ์ฌ๋ฌ ๋จ๊ณ๋ฅผ ๊ฑฐ์นฉ๋๋ค. ์ด๋ฌํ ๋จ๊ณ์ ์ฒด์ธ์ด ์๋ํ๋๋ฉด ์ข์ต๋๋ค. IT ํ๋ก์ ํธ ์์ฒด์ ์ ๋ฒ์ ์ ์ถ์ํ๋ ์๋ํ๋ ํ๋ก์ธ์ค๋ฅผ ์ง์์ ์ธ ํตํฉ. ๋น๋๋ด ์ด ํ๋ก์ธ์ค๋ฅผ ๊ตฌํํ๋ ๋ฐ ์ข์ ์กฐ๋ ฅ์๊ฐ ๋์์ต๋๋ค.
์ด ๊ธฐ์ฌ์์ ๋๋ ๊ฐ๋ฅ์ฑ์ ๋ํ ๊ฐ์๋ฅผ ์ ๊ณตํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ๋น๋๋ด. ์ด ์ํํธ์จ์ด๋ ๋ฌด์์ ํ ์ ์๋์? ๊ทธ์๊ฒ ์ ๊ทผํ๋ ๋ฐฉ๋ฒ๊ณผ ๊ทธ์ ์ ์์ ์ธ ํจ๊ณผ์ ์ธ ์
๋ฌด ๊ด๊ณ๋ฅผ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ฌด์์
๋๊น? ๊ทํ์ ์ปดํจํฐ์์ ํ๋ก์ ํธ๋ฅผ ๊ตฌ์ถํ๊ณ ํ
์คํธํ๊ธฐ ์ํ ์์
์๋น์ค๋ฅผ ์์ฑํ์ฌ ์ฐ๋ฆฌ์ ๊ฒฝํ์ ์ง์ ์ ์ฉํ ์ ์์ต๋๋ค.
๋ด์ฉ
๋ด์ฉ
1. ์ BuildBot์ธ๊ฐ?
์ด์ ์ habr-e์์ ๊ตฌํ์ ๊ดํ ๊ธฐ์ฌ๋ฅผ ์ ํ์ต๋๋ค. ์ง์์ ์ธ ํตํฉ ์ฌ์ฉ ๋น๋๋ด. ์:
๋ฉ์ถ๋ค! ์ค์ ๋ก ํ๋ก์ ํธ์ ์ฌ์ฉํ ์ฌ๋์ด ์๋์? ๊ทธ๋ ์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ฌ๋๋ค์ด ์ฌ์ฉํ๋ ๋ ผ๋ฆฌ๋ ๋ฌด์์ ๋๊น? ๋น๋ ๋ด? ๊ฒฐ๊ตญ, ๋ค๋ฅธ ๋๊ตฌ๋ ์์ต๋๋ค: ํฌ๋ฃจ์ฆ ์ปจํธ๋กค ะธ ์ ํจ์ค. ๋๋ ์ด๋ ๊ฒ ๋๋ตํ ๊ฒ์ด๋ค. ๋๋ถ๋ถ์ ์์ ์ ๋ํด ์ ํจ์ค ์ง์ค์ ์ถฉ๋ถํ ๊ฒ์ ๋๋ค. ์ฐจ๋ก๋ก, ๋น๋๋ด - ๋ ์ ์๋ ฅ์ด ๋ฐ์ด๋๊ณ ๋ฌธ์ ๋ ๋ค์๊ณผ ๊ฐ์ด ๊ฐ๋จํ๊ฒ ํด๊ฒฐ๋ฉ๋๋ค. ์ ํจ์ค. ์ ํ์ ๋น์ ์ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ๊ฐ๋ฐ ๋์ ํ๋ก์ ํธ๋ฅผ ์ํ ๋๊ตฌ๋ฅผ ์ฐพ๊ณ ์์ผ๋ฏ๋ก ๊ฐ๋จํ ๋จ๊ณ๋ถํฐ ์์ํ์ฌ ์ํธ ์์ฉ์ฑ๊ณผ ๊ณ ์ ํ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ถ ๋น๋ ์์คํ ์ ์ป์ ์ ์๋ ๋๊ตฌ๋ฅผ ์ ํํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
Python์ผ๋ก ๋์ ํ๋ก์ ํธ๋ฅผ ์์ฑํ๋ ์ฌ๋๋ค์๊ฒ๋ "ํ๋ก์ ํธ์์ ์ฌ์ฉ๋๋ ์ธ์ด ์ธก๋ฉด์์ ๋ช ํํ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ถ ํตํฉ ์์คํ ์ ์ ํํ๋ ๊ฒ์ด ์ด๋จ๊น์?"๋ผ๋ ์ง๋ฌธ์ด ์๊น๋๋ค. ์ด์ ์ฅ์ ์ ์๊ฐํ ์ฐจ๋ก์ ๋๋ค ๋น๋๋ด.
๊ทธ๋์ ์ฐ๋ฆฌ์ "์ ๊ธฐ XNUMX ์ค์ฃผ". ๋ ์์ ์ ์ํด ๋ค ๊ฐ์ง ํน์ง์ ํ์ธํ์ต๋๋ค. ๋น๋๋ด:
- GPL ๋ผ์ด์ผ์ค์ ๋ฐ๋ฅธ ์คํ ์์ค ํ๋ ์์ํฌ์ ๋๋ค.
- Python์ ๊ตฌ์ฑ ๋๊ตฌ๋ก ์ฌ์ฉํ๊ณ ํ์ํ ์์ ์ ๋ํ ์ค๋ช ์ ๋๋ค.
- ์ด๋ ์กฐ๋ฆฝ์ด ์ด๋ฃจ์ด์ง๋ ๊ธฐ๊ณ๋ก๋ถํฐ ์๋ต์ ๋ฐ์ ์ ์๋ ๊ธฐํ์ ๋๋ค.
- ๋ง์ง๋ง์ผ๋ก ํธ์คํธ์ ์ต์ ์๊ตฌ ์ฌํญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๋ฐฐํฌ์๋ Python ๋ฐ Twisted๊ฐ ํ์ํ๋ฉฐ ๊ฐ์ ๋จธ์ ๋ฐ Java ๋จธ์ ์ ํ์ํ์ง ์์ต๋๋ค.
2. BuildMaster๊ฐ ์ฃผ๋ํ๋ ์ปจ์
์์
๋ถ๋ฐฐ ์ํคํ
์ฒ์ ํต์ฌ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๋น๋๋ง์คํฐ. ์ด๋ ๋ค์๊ณผ ๊ฐ์ ์๋น์ค์
๋๋ค.
- ์ถ์ ํ๋ค ํ๋ก์ ํธ ์์ค ํธ๋ฆฌ์ ๋ณ๊ฒฝ ์ฌํญ
- ๋ณด๋ ํ๋ก์ ํธ๋ฅผ ๋น๋ํ๊ณ ํ ์คํธํ๊ธฐ ์ํด ์์ ์ ์๋น์ค์์ ์คํํด์ผ ํ๋ ๋ช ๋ น
- ํต์ง ์ทจํด์ง ์กฐ์น์ ๊ฒฐ๊ณผ์ ๋ํ ์ฌ์ฉ์
๋น๋๋ง์คํฐ ํ์ผ์ ํตํด ๊ตฌ์ฑ๋จ master.cfg. ์ด ํ์ผ์ ๋ฃจํธ์ ์์ต๋๋ค ๋น๋๋ง์คํฐ. ๋์ค์ ์ด ๋ฃจํธ๊ฐ ์ด๋ป๊ฒ ์์ฑ๋๋์ง ๋ณด์ฌ ๋๋ฆฌ๊ฒ ์ต๋๋ค. ํ์ผ ์์ฒด master.cfg ํธ์ถ์ ์ฌ์ฉํ๋ Python ์คํฌ๋ฆฝํธ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ๋น๋๋ด.
๋ค์์ผ๋ก ์ค์ํ ๊ฐ์ฒด ๋น๋๋ด ๊ทธ๊ฒ์ ์ด๋ฆ์ด ๋ ธ๋์. ์ด ์๋น์ค๋ ๋ค๋ฅธ OS๋ฅผ ์ฌ์ฉํ๋ ๋ค๋ฅธ ํธ์คํธ์์ ์์๋ ์ ์์ต๋๋ค. ๋น๋๋ง์คํฐ. ์์ฒด ํจํค์ง์ ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ํน๋ณํ ์ค๋น๋ ๊ฐ์ ํ๊ฒฝ์ ์กด์ฌํ ์๋ ์์ต๋๋ค. ์ด๋ฌํ ๊ฐ์ ํ๊ฒฝ์ ๋ค์๊ณผ ๊ฐ์ Python ์ ํธ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋นํ ์ ์์ต๋๋ค. ๊ฐ์ ํ๊ฒฝ, ๊ฐ์ ํ๊ฒฝ.
๋น๋๋ง์คํฐ ๋ชจ๋ ์ฌ๋์๊ฒ ๋ช ๋ น์ ๋ฐฉ์กํฉ๋๋ค. ๋ ธ๋์-y, ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ ์ฐจ๋ก๋ก ๊ทธ๊ฒ๋ค์ ์ดํํฉ๋๋ค. ์ฆ, ํ๋ก์ ํธ๋ฅผ ๊ตฌ์ถํ๊ณ ํ ์คํธํ๋ ๊ณผ์ ์ด ๊ณ์๋ ์ ์๋ค๋ ๊ฒ์ด ๋ฐํ์ก์ต๋๋ค. ๋ ธ๋์-e Windows๋ฅผ ์คํํ๊ณ Linux๋ฅผ ์คํํ๋ ๋ค๋ฅธ ์์ ์์์.
์ ๊ฒ ํ๋ก์ ํธ ์์ค ์ฝ๋๋ ๊ฐ๊ฐ์์ ๋ฐ์ํฉ๋๋ค. ๋ ธ๋์-์ด์ํ.
3. ์ค์น
์, ๊ฐ์. ์ ๋ Ubuntu 18.04๋ฅผ ํธ์คํธ๋ก ์ฌ์ฉํ๊ฒ ์ต๋๋ค. ๊ทธ ์์ ํ๋ ์ฌ๋ ค ๋์๊ฒ ๋น๋๋ง์คํฐ-a์ ํ๋ ๋ ธ๋์-ใ . ํ์ง๋ง ๋จผ์ python3.7์ ์ค์นํด์ผ ํฉ๋๋ค.
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
๋ค์ ๋จ๊ณ๋ ์ค์น์ ๋๋ค. ํธ์๋จ ะธ ๋น๋๋ด, ์ถ๊ฐ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋ ํจํค์ง ๋น๋๋ด-NS.
/*ะัะต ััะพ ะฟะพะด 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. ์ฒซ ๋ฒ์งธ ๋จ๊ณ
์ฐฝ์กฐํ ์๊ฐ ๋น๋๋ง์คํฐ. ์ฐ๋ฆฌ ํด๋์ ์์ ๊ฑฐ์์ /์ง/habr/๋ง์คํฐ.
mkdir master
buildbot create-master master # ะกะพะฑััะฒะตะฝะฝะพ ัะดะตัั ะธ ัะพะทะดะฐะตะผ
mkdir worker
buildbot-worker create-worker --umask=0o22 --keepalive=60 worker localhost:4000 yourWorkerName password
๋น์ ์ด ๋ฌ๋ฆด ๋ ๋ ธ๋์, ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์ ์์น์ ์์ฑ๋ฉ๋๋ค. /์ง/habr/์์ ์ ํ๋ก์ ํธ ์ด๋ฆ์ด ์ง์ ๋ ํด๋ master.cfg. ๊ทธ๋ฆฌ๊ณ ํ๋ก์ ํธ ์ด๋ฆ์ ํด๋์ ๋๋ ํ ๋ฆฌ๊ฐ ์์ฑ๋ฉ๋๋ค. ๋น๋, ๊ทธ๋ฆฌ๊ณ ์์ผ๋ก๋ ๊ทธ๋ด ๊ฒ์ด๋ค ์ ๊ฒ. ์์ ๋๋ ํ ๋ฆฌ ๋ ธ๋์-๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ ๋๋ ํ ๋ฆฌ๊ฐ ๋ ๊ฒ์ ๋๋ค /home/habr/yourProject/๋น๋.
"ํฉ๊ธ์ด์
์ด์ ์ ๊ฐ ์ด์ ๋จ๋ฝ์ ์ด ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๋ง์คํฐ ~์๊ฒ ์๊ตฌํ ๊ฒ์ด๋ค ๋
ธ๋์- ์คํฌ๋ฆฝํธ์ ์คํ ๊ถํ์ด ์๊ธฐ ๋๋ฌธ์ ์ด ๋๋ ํฐ๋ฆฌ์์ ์๊ฒฉ์ผ๋ก ์ํ๋๋ฉด ์คํ๋์ง ์์ต๋๋ค. ์ํฉ์ ํด๊ฒฐํ๋ ค๋ฉด ์ด์ ๊ฐ ํ์ํฉ๋๋ค
๋น๋๋ง์คํฐ ะธ ๋ ธ๋์ ์๋ก ์ฐ๊ฒฐ์ ์ค์ ํฉ๋๋ค. ๊นจ์ง๋ ์ผ์ด ๋ฐ์ํ๊ณ ๋ ธ๋์ ์ ์ ๋์์ ์๋ต์ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๋ค. ๋น๋๋ง์คํฐ-ใ . ์๋ต์ด ์์ผ๋ฉด ์ฐ๊ฒฐ์ด ๋ค์ ์์๋ฉ๋๋ค. ์ด์ --keepalive=60 ๊ทธ ์ดํ์ ์๊ฐ์ ํ์ํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ์๋ค ์ฌ๋ถํ ํฉ๋๋ค.
5. ๊ตฌ์ฑ. ๋จ๊ณ๋ณ ๋ ์ํผ
๊ตฌ์ฑ ๋น๋๋ง์คํฐ ๋ช ๋ น์ ์คํํ ๋จธ์ ์ธก์์ ์ํ๋ฉ๋๋ค. ์์ฑ-๋ง์คํฐ. ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ ์ด๊ฒ์ ๋๋ ํ ๋ฆฌ์ ๋๋ค. /์ง/habr/๋ง์คํฐ. ๊ตฌ์ฑ ํ์ผ master.cfg ์์ง ์กด์ฌํ์ง ์์ง๋ง ๋ช ๋ น ์์ฒด๊ฐ ์ด๋ฏธ ํ์ผ์ ์์ฑํ์ต๋๋ค. master.cmg.์ํ. ์ด๋ฆ์ ๋ค์์ผ๋ก ๋ฐ๊ฟ์ผํฉ๋๋ค. master.cfg.์ํ ะฒ 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 โ ๊ตฌ์ฑ ํ์ผ์ ๊ธฐ๋ณธ ์ฌ์ ์
๋๋ค. ๊ตฌ์ฑ ํ์ผ์ ํฌํจ๋์ด์ผ ํฉ๋๋ค. ์ฌ์ฉ ํธ์์ฑ์ ์ํด ๊ตฌ์ฑ ์ฝ๋์ ๋ณ์นญ์ด ๋์
๋์์ต๋๋ค. "์จ". ์ ๋ชฉ
5.2 ๋ ธ๋์
c['workers'] = [worker.Worker("example-worker", "pass")]
์ด๋ฒ์๋ ํ์ํฉ๋๋ค. ๋น๋๋ง์คํฐ-y ๋ชฉ๋ก ๋
ธ๋์-์์ค. ๋ด ์์ ๋
ธ๋์ ์ฐ๋ฆฌ๊ฐ ๋ง๋ค์์ด์
5.3 ๋ณ๊ฒฝ_์์ค
c['change_source'] = []
c['change_source'].append(changes.GitPoller(
'git://github.com/buildbot/hello-world.git',
workdir='gitpoller-workdir', branch='master',
pollInterval=300))
ํค๋ณ ๋ณ๊ฒฝ_์์ค Dictionary C์์๋ ํ๋ก์ ํธ์ ์์ค ์ฝ๋๋ก ์ ์ฅ์๋ฅผ ํด๋งํ๋ ๊ฐ์ฒด๋ฅผ ๋ฃ์ ๋ชฉ๋ก์ ์ก์ธ์คํ ์ ์์ต๋๋ค. ์ด ์์์๋ ํน์ ๊ฐ๊ฒฉ์ผ๋ก ํด๋ง๋๋ Git ์ ์ฅ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ฒซ ๋ฒ์งธ ์ธ์๋ ์ ์ฅ์์ ๊ฒฝ๋ก์ ๋๋ค.
์์ ๋๋ ํ ๋ฆฌ ์ธก๋ฉด์ ์๋ ํด๋์ ๊ฒฝ๋ก๋ฅผ ๋ํ๋ ๋๋ค. ๋ ธ๋์- ๊ฒฝ๋ก์ ๋ํ ์๋ /home/habr/worker/yourProject/build git์ ์ ์ฅ์์ ๋ก์ปฌ ๋ฒ์ ์ ์ ์ฅํฉ๋๋ค.
์ง์ฌ ๋ฐ๋ผ์ผ ํ ์ ์ฅ์์ ํน์ ๋ถ๊ธฐ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
ํด๋ง ๊ฐ๊ฒฉ ๊ทธ ์ดํ์ ์ด ์๋ฅผ ํฌํจํฉ๋๋ค. ๋น๋๋ง์คํฐ ๋ณ๊ฒฝ ์ฌํญ์ ๋ํด ์ ์ฅ์๋ฅผ ํด๋งํฉ๋๋ค.
ํ๋ก์ ํธ ์ ์ฅ์์ ๋ณ๊ฒฝ ์ฌํญ์ ์ถ์ ํ๋ ๋ฐฉ๋ฒ์๋ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์์ต๋๋ค.
๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ํฌํ, ์ด๋ ๋ค์์ ์๋ฏธํฉ๋๋ค. ๋น๋๋ง์คํฐ ์ ๊ธฐ์ ์ผ๋ก ์ ์ฅ์๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฒ๋ฅผ ํด๋งํฉ๋๋ค. ๋ง์ฝ์ ๋ฒํ๋ค ์ ์ฅ์์ ๋ณ๊ฒฝ ์ฌํญ์ ๋ฐ์ํ ๋ค์ ๋น๋๋ง์คํฐ ์ฝ๊ฐ์ ์ง์ฐ์ผ๋ก ๋ด๋ถ ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. ๋ณํ ๊ทธ๋ฆฌ๊ณ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก ๋ณด๋ด์ฃผ์ธ์ ์ค์ผ์ค๋ฌ, ํ๋ก์ ํธ๋ฅผ ๋น๋ํ๊ณ ํ
์คํธํ๋ ๋จ๊ณ๋ฅผ ์์ํฉ๋๋ค. ๋
ธ๋์-์ด์ํ. ์ด ๋จ๊ณ ์ค ํ์๋ฉ๋๋ค ์ต์ ์ ๋ณด ์ ์ฅ์. ์ ํํ ์ผ์ง ๋
ธ๋์๊ทธ๋ฌ๋ฉด ์ ์ฅ์์ ๋ก์ปฌ ๋ณต์ฌ๋ณธ์ด ์์ฑ๋ฉ๋๋ค. ์ด ํ๋ก์ธ์ค์ ๋ํ ์์ธํ ๋ด์ฉ์ ๋ค์ ๋ ์น์
์์ ์ค๋ช
ํฉ๋๋ค. (
์ ์ฅ์์ ๋ํ ๋ณ๊ฒฝ ์ฌํญ์ ์ถ์ ํ๋ ํจ์ฌ ๋ ์ฐ์ํ ๋ฐฉ๋ฒ์ ์ ์ฅ์๋ฅผ ํธ์คํ ํ๋ ์๋ฒ์์ ์ง์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ ๊ฒ์ ๋๋ค. ๋น๋๋ง์คํฐ- ํ๋ก์ ํธ ์์ค ์ฝ๋ ๋ณ๊ฒฝ์ ๋ํด. ์ด ๊ฒฝ์ฐ ๊ฐ๋ฐ์๊ฐ ๋ง๋๋ ์ฆ์ ๋ฒํ๋ค, ํ๋ก์ ํธ ์ ์ฅ์๊ฐ ์๋ ์๋ฒ๊ฐ ๋ฉ์์ง๋ฅผ ๋ณด๋ ๋๋ค. ๋น๋๋ง์คํฐ-์์ด. ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ ์ฐจ๋ก๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ์ด๋ฅผ ๊ฐ๋ก์ฑ ๊ฒ์ ๋๋ค. PBChangeSource. ๋ค์์ผ๋ก ์ด ๊ฐ์ฒด๋ ๋ค์์ผ๋ก ์ ์ก๋ฉ๋๋ค. ์ค์ผ์ค๋ฌ, ํ๋ก์ ํธ๋ฅผ ๋น๋ํ๊ณ ํ ์คํธํ๋ ๋จ๊ณ๋ฅผ ํ์ฑํํฉ๋๋ค. ์ด ๋ฐฉ๋ฒ์ ์ค์ํ ๋ถ๋ถ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ํ - ์ ์ฅ์์ ์๋ฒ ์คํฌ๋ฆฝํธ. ์คํฌ๋ฆฝํธ์์ ํ -a, ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ ์์ ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํฉ๋๋ค. ๋ฒํ๋ค-e, ์ ํธ๋ฆฌํฐ๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค ์ผ๋์ฒด์ธ์ง ๋คํธ์ํฌ ์ฃผ์๋ฅผ ์ง์ ํ๊ณ ๋น๋๋ง์คํฐ-ใ . ๋ํ ์์ ๋๊ธฐํ ๋คํธ์ํฌ ํฌํธ๋ฅผ ์ง์ ํด์ผ ํฉ๋๋ค. PBChangeSource. PBChangeSource, ๊ทธ๊ฑด ๊ทธ๋ ๊ณ , ์ผ๋ถ์ ๋๋ค ๋น๋๋ง์คํฐ-ใ . ์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ ค๋ฉด ๊ถํ์ด ํ์ํฉ๋๋ค. ๊ด๋ฆฌ์-a ํ๋ก์ ํธ ์ ์ฅ์๊ฐ ์๋ ์๋ฒ์ ์์ต๋๋ค. ๋จผ์ ์ ์ฅ์๋ฅผ ๋ฐฑ์ ํด์ผ ํฉ๋๋ค.
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"]))
์ค์ผ์ค๋ฌ โ ์ด๋ ํ๋ก์ ํธ์ ์ ์ฒด ์กฐ๋ฆฝ ๋ฐ ํ
์คํธ ์ฒด์ธ์ ์์ํ๋ ํธ๋ฆฌ๊ฑฐ ์ญํ ์ ํ๋ ์์์
๋๋ค.
๊ธฐ๋ก๋ ๋ณ๊ฒฝ์ฌํญ ๋ณ๊ฒฝ_์์ค, ์์
๊ณผ์ ์์ ๋ณํ๋จ ๋น๋๋ด-a ์ด์๋ฅผ ์ ๊ธฐํ๋ค ๋ณํ ๊ทธ๋ฆฌ๊ณ ์ง๊ธ์ ๋งค ์
ฐ๋๋ฌ ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ก์ ํธ ๋น๋ ํ๋ก์ธ์ค๋ฅผ ์์ํ๋ผ๋ ์์ฒญ์ ์์ฑํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ฌํ ์์ฒญ์ด ๋๊ธฐ์ด๋ก ์ถ๊ฐ๋ก ์ ์ก๋๋ ์๊ธฐ๋ ๊ฒฐ์ ํฉ๋๋ค. ๊ฐ์ฒด
์ฐ๋ฆฌ๋ ํ์ฌ ์์์ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค ์ค์ผ์ค๋ฌ 2๊ฐ์ ์กฐ๊ฐ์ด ์์ฑ๋ฉ๋๋ค. ๋ํ ๊ฐ๊ฐ ๊ณ ์ ํ ์ ํ์ด ์์ต๋๋ค.
๋จ์ผ ์ง์ ์ค์ผ์ค๋ฌ โ ์ผ์ ์ค ๊ฐ์ฅ ์ธ๊ธฐ ์๋ ์์ ์ค ํ๋์ ๋๋ค. ํ๋์ ๋ถ๊ธฐ๋ฅผ ๊ฐ์ํ๊ณ ๊ธฐ๋ก๋ ๋ณ๊ฒฝ ์ฌํญ์ ์ํด ํธ๋ฆฌ๊ฑฐ๋ฉ๋๋ค. ๋ณ๊ฒฝ ์ฌํญ์ ํ์ธํ๋ฉด ๋น๋ ์์ฒญ ์ ์ก์ ์ง์ฐํ ์ ์์ต๋๋ค(ํน์ ๋งค๊ฐ๋ณ์์ ์ง์ ๋ ๊ธฐ๊ฐ ๋์ ์ฐ๊ธฐ). treeStableTimer) ์์ผ๋ก name ํ์๋ ์ผ์ ์ ์ด๋ฆ์ ์ค์ ํฉ๋๋ค. ๋น๋๋ด-์น ์ธํฐํ์ด์ค. ์์ ํํฐ ๋ณ๊ฒฝ ํํฐ๊ฐ ์ค์ ๋๋ฉด ๋ถ๊ธฐ์ ๋ณ๊ฒฝ ์ฌํญ์ด ๊ตฌ์ฑ ์์ฒญ์ ๋ณด๋ด๋๋ก ์ผ์ ์ ์๋ดํฉ๋๋ค. ์์ ๋น๋ ์ด๋ฆ ์ด๋ฆ์ด ํ์๋์ด ์์ด์ ๊ฑด์ถ์ ์-a, ์ด๋ ๋์ค์ ์ค์ ํ๊ฒ ์ต๋๋ค. ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ ์ด๋ฆ์ ํ๋ก์ ํธ ์ด๋ฆ๊ณผ ๋์ผํฉ๋๋ค. ๋์ ํ๋ก์ ํธ.
๊ฐ์ ์ค์ผ์ค๋ฌ ์์ฃผ ๊ฐ๋จํ ์ผ์ด๋ค. ์ด๋ฌํ ์ ํ์ ์ผ์ ์ ๋ง์ฐ์ค ํด๋ฆญ์ ํตํด ์คํ๋ฉ๋๋ค. ๋น๋๋ด-์น ์ธํฐํ์ด์ค. ๋งค๊ฐ๋ณ์๋ ๋ค์๊ณผ ๊ฐ์ ๋ณธ์ง์ ๊ฐ์ง๋๋ค. ๋จ์ผ ์ง์ ์ค์ผ์ค๋ฌ.
PS ๋ฒํธ 3. ์ด์ฉ๋ฉด ๋์์ด ๋ ๊ฒ์
๋๋ค
๊ฐํ์ ์ธ ํน์ ์๊ฐ์ ๊ณ ์ ๋ ๋น๋๋ก ์คํ๋๋ ์ผ์ ์
๋๋ค. ํตํ ๋ด์ฉ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
from buildbot.plugins import schedulers
nightly = schedulers.Periodic(name="daily",
builderNames=["full-solaris"],
periodicBuildTimer=24*60*60)
c['schedulers'] = [nightly]
5.5 ๋น๋ํฉํ ๋ฆฌ
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": "."}))
์ฃผ๊ธฐ์ ๋น๋ํ์ด๋จธ ์ด ์ฃผ๊ธฐ์ ์๊ฐ์ ์ด ๋จ์๋ก ์ง์ ํฉ๋๋ค.
๋น๋ํฉํ ๋ฆฌ ํน์ ์ ์์ฑํฉ๋๋ค ๋น๋, ๊ทธ๋ฌ๋ฉด ๊ฑด์ถ์
์ ~์๊ฒ ๋ณด๋ธ๋ค ๋
ธ๋์. ์ ๋น๋ํฉํ ๋ฆฌ ๋ฐ๋ผ์ผ ํ ๋จ๊ณ๋ฅผ ๋ํ๋
๋๋ค. ๋
ธ๋์-์์ด. ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ๋จ๊ณ๊ฐ ์ถ๊ฐ๋ฉ๋๋ค. ์ถ๊ฐ๋จ๊ณ
์ด ์์์ ์ฒซ ๋ฒ์งธ๋ก ์ถ๊ฐ๋ ๋จ๊ณ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. git clean -d -f -f โx, ๊ทธ ๋ค์์ ์์ ์ฒดํฌ ์์. ์ด๋ฌํ ์์ ์ ๋งค๊ฐ๋ณ์์ ํฌํจ๋ฉ๋๋ค. ๋ฐฉ๋ฒ, ์ด๋ ๋ช ํํ๊ฒ ๋ช ์๋์ด ์์ง ์์ง๋ง ๊ธฐ๋ณธ๊ฐ์ ์๋ฏธํฉ๋๋ค. ์ ์ ํ. ๋ชจ์ ๋ชจ๋='์ฆ๋ถ' ํ์ผ์ด ๋ค์ ๋๋ ํฐ๋ฆฌ์ ์์์ ๋ํ๋ ๋๋ค. Chechout, ์ ์ฅ์์์ ๋๋ฝ๋ ๋์์๋ ๊ทธ๋๋ก ์ ์ง๋ฉ๋๋ค.
๋ ๋ฒ์งธ๋ก ์ถ๊ฐ๋ ๋จ๊ณ๋ ์คํฌ๋ฆฝํธ๋ฅผ ํธ์ถํ๋ ๊ฒ์ ๋๋ค. ์๋ ๋งค๊ฐ๋ณ์ ํฌํจ ์๋ ํ์ธ์ ์ธก๋ฉด์ ๋ ธ๋์-a ๋๋ ํ ๋ฆฌ์์ /home/habr/worker/yourProject/build ํ๊ฒฝ ๋ณ์ PATHONPATH=...๋ฅผ ์ฌ์ฉํ๋ฉด ์์ฒด ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๊ณ ์ธก๋ฉด์์ ์คํํ ์ ์์ต๋๋ค. ๋ ธ๋์- ๋ชจ๋ ๋จ๊ณ util.ShellCommand. ์ด๋ฌํ ์คํฌ๋ฆฝํธ๋ ์ ์ฅ์์ ์ง์ ๋ฐฐ์นํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ Chechout-e ๊ทธ๋ค์ ๋น ์ง ๊ฒ์ด๋ค /home/habr/worker/yourProject/build. ๊ทธ๋ฌ๋ ๋ ๊ฐ์ง "๊ทธ๋ฌ๋"๊ฐ ์์ต๋๋ค.
- ๋
ธ๋์ ํค๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑํด์ผ ํฉ๋๋ค.
--umask ์ดํ ์คํ ๊ถํ์ ์ฐจ๋จํ์ง ์๋๋ก ์ ๊ฒ-NS. - ์ git push-e ์ด ์คํฌ๋ฆฝํธ ์ค ์์ฑ์ ์ง์ ํด์ผ ํฉ๋๋ค. ์คํ ๊ฐ๋ฅํ๊ทธ๋์ ๋์ค์ Chechout-e๋ Git ์คํฌ๋ฆฝํธ ์คํ ๊ถํ์ ์์ง ์์์ต๋๋ค.
5.6๋ช ์ ๊ฑด์ถ์ ์
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))
์ด์ ๋งค๊ฐ ๋ณ์์ ๋ํด ์ค๋ช ํ๊ฒ ์ต๋๋ค. ๋น๋ ๊ตฌ์ฑ.
name ์ด๋ฆ์ ์ง์ ํฉ๋๋ค ๊ฑด์ถ์ ์-ใ . ์ฌ๊ธฐ์ ์ด๋ฆ์ ๋ถ์์ต๋๋ค. ๋์ ํ๋ก์ ํธ. ์ด๋ ๋ค์์ ์๋ฏธํฉ๋๋ค. ๋ ธ๋์- ๋ฐ๋ก ์ด ๊ธธ์ด ๋ง๋ค์ด์ง ๊ฒ์ด๋ค /home/habr/worker/yourProject/build. ์ ฐ๋๋ฌ ์ฐพ๊ณ ์๋ ๊ฑด์ถ์ ์ ๋ฐ๋ก ์ด ์ด๋ฆ์ผ๋ก.
์์ ์ ์ด๋ฆ ์ํธ ํฌํจ ๋ ธ๋์-์์ค. ๊ฐ๊ฐ ์ถ๊ฐํด์ผ ํ ํญ๋ชฉ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. c['๋ ธ๋์'].
๊ณต์ฅ - ํน์ ํ ๋น๋, ์ด๋ ์ฐ๊ด๋์ด ์์ต๋๋ค. ๊ฑด์ถ์ ์. ๊ทธ๋ ๋ฌผ๊ฑด์ ๋ณด๋ผ ๊ฒ์ด๋ค ๋น๋ ์ ๋ ธ๋์ ์ฌ๊ธฐ์ ํฌํจ๋ ๋ชจ๋ ๋จ๊ณ๋ฅผ ์๋ฃํ๋ ค๋ฉด ๋น๋-NS.
6. ์์ ๋ง์ ๊ตฌ์ฑ ์์
๋ค์์ ์ ๊ฐ ๊ตฌํ์ ์ ์ํ๋ ํ๋ก์ ํธ ์ํคํ
์ฒ์ ์์
๋๋ค. ๋น๋๋ด
.
๋ฒ์ ๊ด๋ฆฌ ์์คํ
์ผ๋ก ์ฌ์ฉํ๊ฒ ์ต๋๋ค. svn. ์ ์ฅ์ ์์ฒด๋ ์ผ์ข
์ ํด๋ผ์ฐ๋์ ์์นํฉ๋๋ค. ์ด ํด๋ผ์ฐ๋์ ์ฃผ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค
๋น๋๋ง์คํฐ ะธ ๋ ธ๋์ ๋์ผํ ํธ์คํธ์์ ์คํ ํ๋ก์ ํธ.ํธ์คํธ .๋น๋๋ง์คํฐ ํ์ผ์ ํด๋์ ์ ์ฅ /์ง/habr/๋ง์คํฐ. ๋ ธ๋์ ๋ค์ ๊ฒฝ๋ก์ ์ ์ฅ๋ฉ๋๋ค /์ง/habr/์์ ์. ํ๋ก์ธ์ค ์ปค๋ฎค๋์ผ์ด์ ๋น๋๋ง์คํฐ-a ๊ทธ๋ฆฌ๊ณ ๋ ธ๋์-a๋ ํ๋กํ ์ฝ์ ๋ฐ๋ผ ํฌํธ 4000์ ํตํด ์ํ๋ฉ๋๋ค. ๋น๋๋ด-์, ๊ทธ๋ ์ฃ 'pb' ๊ท์ฝ.
๋์ ํ๋ก์ ํธ๋ ์์ ํ Python์ผ๋ก ์์ฑ๋์์ต๋๋ค. ์๋ฌด๋ ๋ณ๊ฒฝ ์ฌํญ์ ์ถ์ ํ๊ณ , ์คํ ํ์ผ์ ์์ฑํ๊ณ , ๋ฌธ์๋ฅผ ์์ฑํ๊ณ , ํ ์คํธ๋ฅผ ์ํํ๋ ๊ฒ์ ๋๋ค. ์คํจํ ๊ฒฝ์ฐ ๋ชจ๋ ๊ฐ๋ฐ์๋ ์คํจํ ์์ ์ด ์์์ ์๋ฆฌ๋ ๋ฉ์์ง๋ฅผ ์ด๋ฉ์ผ๋ก ๋ณด๋ด์ผ ํฉ๋๋ค.
์น ๋์คํ๋ ์ด ๋น๋๋ด ํฌํธ 80์ ์ฐ๊ฒฐํ๊ฒ ์ต๋๋ค. ํ๋ก์ ํธ.ํธ์คํธ. Apache๋ฅผ ์ค์นํ ํ์๋ ์์ต๋๋ค. ๋์๊ด์ ์ผ๋ถ๋ก ๊ผฌ์ธ ์ด๋ฏธ ์น ์๋ฒ๊ฐ ์๊ณ , ๋น๋๋ด ๊ทธ๊ฒ์ ์ฌ์ฉํฉ๋๋ค.
๋ด๋ถ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ค๋ฉด ๋น๋๋ด ์ฐ๋ฆฌ๋ ์ฌ์ฉํ ๊ฒ์ ๋๋ค sqlite.
๋ฉ์ผ์ ๋ณด๋ด๋ ค๋ฉด ํธ์คํธ๊ฐ ํ์ํฉ๋๋ค. smtp.your.domain - ์ฐํธ์์ ํธ์ง๋ฅผ ๋ณด๋ผ ์ ์์ต๋๋ค. [์ด๋ฉ์ผ ๋ณดํธ] ์ธ์ฆ ์์ด. ํธ์คํธ์์๋ 'SMTP ' ํ์๋ก์ 1025๋ฒ ํฌ์คํธ์์ ์ฒญ์ทจ๋๊ณ ์์ต๋๋ค.
์ด ๊ณผ์ ์๋ ๋ ์ฌ๋์ด ์ฐธ์ฌํฉ๋๋ค. ๊ด๋ฆฌ์ ะธ ์ฌ์ฉ์. ๊ด๋ฆฌ์๊ฐ ๊ด๋ฆฌํฉ๋๋ค ๋น๋๋ด. ์ฌ์ฉ์๋ ์ปค๋ฐํ๋ ์ฌ๋์ ๋๋ค. ๋ฒํ๋ค-์์ค.
์คํ ๊ฐ๋ฅํ ํ์ผ์ ๋ค์์ ํตํด ์์ฑ๋ฉ๋๋ค. ํ์ด ์ธ์คํจ๋ฌ. ๋ฌธ์๋ ๋ค์์ ํตํด ์์ฑ๋ฉ๋๋ค. ๋ ์.
์ด ์ํคํ ์ฒ๋ฅผ ์ํด ๋๋ ๋ค์๊ณผ ๊ฐ์ด ์ผ์ต๋๋ค. 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"
}
๋จผ์ ํ์ํ
๋ค์ ๋จ๊ณ๋ ์๋น์ค๋ฅผ ์์ํ๋ ๊ฒ์ ๋๋ค ๋น๋๋ง์คํฐ์์
sudo buildbot start /home/habr/master
๊ทธ๋ผ ์๋น์ค ์์ ๋ ธ๋์-a
buildbot-worker start /home/habr/worker
์ค๋น๊ฐ ๋! ์ง๊ธ ๋น๋ ๋ด ๋ณ๊ฒฝ ์ฌํญ์ ์ถ์ ํ๊ณ ํธ๋ฆฌ๊ฑฐํฉ๋๋ค. ๋ฒํ๋ค-y in svn, ์ ์ํคํ ์ฒ๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก์ ํธ๋ฅผ ๋น๋ํ๊ณ ํ ์คํธํ๋ ๋จ๊ณ๋ฅผ ์ํํฉ๋๋ค.
์๋์์๋ ์์ ๋ช ๊ฐ์ง ๊ธฐ๋ฅ์ ๋ํด ์ค๋ช
ํ๊ฒ ์ต๋๋ค. master.cfg.
6.1 master.cfg๋ก ๊ฐ๋ ์ค
๋ด ๊ธ์ ์ฐ๋ ๋์ master.cfg ์ค๋ฅ๊ฐ ๋ง์ด ๋ฐ์ํ๋ฏ๋ก ๋ก๊ทธ ํ์ผ์ ์ฝ์ด์ผ ํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ์ ์ฅ๋ฉ๋๋ค. ๋น๋๋ง์คํฐ-ec ์ ๋ ๊ฒฝ๋ก /home/habr/master/twistd.log, ๊ทธ๋ฆฌ๊ณ ๊ทธ ์์๋ ๋
ธ๋์-a ์ ๋ ๊ฒฝ๋ก ํฌํจ /home/habr/worker/twistd.log. ์ค๋ฅ๋ฅผ ์ฝ๊ณ ์์ ํ ํ์๋ ์๋น์ค๋ฅผ ๋ค์ ์์ํด์ผ ํฉ๋๋ค. ๋น๋๋ง์คํฐ-ใ
. ์ํ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
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. ์ด๋ ์ฌ์ ํ ๋์ผํ ์ธํฐํ์ด์ค๋ก, XNUMX๋ถ์ ํ ๋ฒ์ฉ ์ ์ฅ์๋ฅผ ์ ๊ธฐ์ ์ผ๋ก ํด๋งํฉ๋๋ค. ์ด ๊ฒฝ์ฐ svn_poller ์ง์ ์๋ง ์ก์ธ์ค ํธ๋ ํฌ. ์ ๋นํ ๋งค๊ฐ๋ณ์ Split_file=util.svn.split_file_alwaysstrunk ๊ท์น ์ค์ : ํด๋ ๊ตฌ์กฐ๋ฅผ ๋ถํ ํ๋ ๋ฐฉ๋ฒ svn ๊ฐ์ง์. ๊ทธ๋ ๋ํ ๊ทธ๋ค์๊ฒ ์๋ ๊ฒฝ๋ก๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ฐจ๋ก๋๋ก ๋ถํ _ํ์ผ_alwaystrunk ์ ์ฅ์์๋ ๋ค์ ํญ๋ชฉ๋ง ํฌํจ๋์ด ์์์ ๋งํ์ฌ ํ๋ก์ธ์ค๋ฅผ ๋จ์ํํฉ๋๋ค. ํธ๋ ํฌ.
ะ ์ค์ผ์ค๋ฌ ํ์๋จ ํํฐ ๋ณ๊ฒฝ๋๊ฐ ๋ณด๋๊ฐ ์์ ์ง์ ์ ์ฐ๊ฒฐํฉ๋๋ค. ํธ๋ ํฌ ํน์ ํํ๋ฅผ ํตํด ๋ถํ _ํ์ผ_alwaystrunk. ๋ณํ์ ๋ํ ๋์ ํธ๋ ํฌ, ์ถ์ ๊ฑด์ถ์ ์ ์ด๋ฆ์ด ์๋ ๋์ ํ๋ก์ ํธ.
์์ฑ ์ฌ๊ธฐ์๋ ๊ด๋ฆฌ์๊ฐ ํ๋ก์ธ์ค ์์ ์๋ก์ ๋น๋ ๋ฐ ํ ์คํธ ๊ฒฐ๊ณผ์ ๋ํ ๋ฉ์ผ๋ง ๋ชฉ๋ก์ ์์ ํ๊ธฐ ์ํด ํ์ํฉ๋๋ค.
๋จ๊ณ ๋น๋-a ์ ๊ฒ ์ ์ฅ์์ ๋ก์ปฌ ๋ฒ์ ์ ์๋ ๋ชจ๋ ํ์ผ์ ์์ ํ ์ญ์ ํ ์ ์์ต๋๋ค. ๋ ธ๋์-ใ . ๊ทธ๋ฐ ๋ค์ ์ ์ฒด ์์ ์ ์ํํ์ญ์์ค. svn ์ ๋ฐ์ดํธ. ๋ชจ๋๋ ๋งค๊ฐ๋ณ์๋ฅผ ํตํด ๊ตฌ์ฑ๋ฉ๋๋ค. ๋ชจ๋=์ ์ฒด, ๋ฐฉ๋ฒ=์ ์ . ๋ชจ์ quitOnTailure ๋ง์ฝ์ ๊ทธ๋ ๊ฒ ๋งํ๋ค 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]
๊ทธ๋ ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ์ ์๋ค
๋ฉ์ผ์๋ฆผ๊ธฐ ์ด๋ฉ์ผ์ ์ฌ์ฉํ์ฌ ์๋ฆผ์ ๋ณด๋ ๋๋ค.
template_html ๋ด์ค๋ ํฐ์ ํ
์คํธ ํ
ํ๋ฆฟ์ ์ค์ ํฉ๋๋ค. HTML์ ๋งํฌ์
์ ๋ง๋๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์์ง์ ์ํด ์์ ๋ฉ๋๋ค.
๋ฉ์ผ์๋ฆผ๊ธฐ ๋ค์ ์ธ์๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
fromaddr โ ๋ชจ๋ ์ฌ๋์ด ๋ด์ค๋ ํฐ๋ฅผ ๋ฐ์ ์ฃผ์.
๊ด์ฌ ์๋ ์ฌ์ฉ์์๊ฒ ๋ณด๋ด๊ธฐ=True๋ ๋ง๋ ์์ ์์ ์ฌ์ฉ์์๊ฒ ๋ฉ์์ง๋ฅผ ๋ณด๋ ๋๋ค. ๋ฒํ๋ค.
์กฐํ โ ๋ด์ค๋ ํฐ๋ฅผ ๋ฐ๋ ์ฌ์ฉ์ ์ด๋ฆ์ ์ถ๊ฐํด์ผ ํ๋ ์ ๋ฏธ์ฌ์ ๋๋ค. ๊ทธ๋์ ๊ด๋ฆฌ์ ์ฌ์ฉ์๊ฐ ํด๋น ์ฃผ์์์ ๋ด์ค๋ ํฐ๋ฅผ ๋ฐ๋ ๋ฐฉ๋ฒ [์ด๋ฉ์ผ ๋ณดํธ].
๋ฆด๋ ์ดํธ์คํธ ์๋ฒ๊ฐ ์ด๋ฆฌ๋ ํธ์คํธ ์ด๋ฆ์ ์ง์ ํฉ๋๋ค. SMTP์ smptํฌํธ ์์ ํ๋ ํฌํธ ๋ฒํธ๋ฅผ ์ง์ ํฉ๋๋ค. SMTP ์๋ฒ.
๋ชจ๋="๊ฒฝ๊ณ " ์ ์ด๋ ํ๋์ ๋จ๊ณ๊ฐ ์๋ ๊ฒฝ์ฐ์๋ง ๋ฉ์ผ๋ง์ ์ํํด์ผ ํ๋ค๊ณ ๋งํฉ๋๋ค. ๋น๋-a, ์ํ ์คํจ ๋๋ ๊ฒฝ๊ณ ๋ก ์ข ๋ฃ๋์์ต๋๋ค. ์ฑ๊ณตํ ๊ฒฝ์ฐ ๋ด์ค๋ ํฐ๋ฅผ ๋ณด๋ผ ํ์๊ฐ ์์ต๋๋ค.
์ถ๊ฐ์์ ์ ์์ ์์ ํด๋น ์์ ์ ์ํํ ์ฌ๋ ์ธ์ ์ฐํธ๋ฌผ์ ๋ณด๋ด์ผ ํ๋ ์ฌ๋์ ๋ชฉ๋ก์ด ํฌํจ๋์ด ์์ต๋๋ค. ๋ฒํ๋ค.
๋ฉ์์งํฌ๋งท ๋ฉ์์ง ํ์, ํด๋น ํ ํ๋ฆฟ, ์ฌ์ฉ ๊ฐ๋ฅํ ๋ณ์ ์งํฉ์ ์ง์ ํ๋ ๊ฐ์ฒด์ ๋๋ค. ์ง์ 2. ๋ค์๊ณผ ๊ฐ์ ์ต์ ์ํ๋์์ฑ=์ฐธ ะธ ์ํ๋ ๋จ๊ณ=์ฐธ ์ด ์ฌ์ฉ ๊ฐ๋ฅํ ๋ณ์ ์ธํธ๋ฅผ ์ ์ํ์ญ์์ค.
with['services']=[sendMessageToAll] ์๋น์ค ๋ชฉ๋ก์ ์ ๊ณตํ๋ฉฐ ๊ทธ ์ค ์ฐ๋ฆฌ ์๋น์ค๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์ ๊ณ ์.
์ฐ๋ฆฌ๋ ํด๋๋ค! ์ถํํด์
์ฐ๋ฆฌ๋ ์์ฒด ๊ตฌ์ฑ์ ๋ง๋ค๊ณ ๊ทธ๊ฒ์ด ๊ฐ๋ฅํ ๊ธฐ๋ฅ์ ํ์ธํ์ต๋๋ค. ๋น๋๋ด. ์ ์๊ฐ์๋ ์ด ๋๊ตฌ๊ฐ ํ๋ก์ ํธ๋ฅผ ๋ง๋๋ ๋ฐ ํ์ํ์ง ์ดํดํ๋ ๋ฐ ์ถฉ๋ถํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ ์ฌ๋์๊ฒ ๊ด์ฌ์ด ์๋์? ๋น์ ์๊ฒ ์ ์ฉํ ๊น์? ๊ทธ ์ฌ๋์ ํจ๊ป ์ผํ๊ธฐ ํธํ๊ฐ์? ๊ทธ๋ ๋ค๋ฉด ๋๋ ์ด ๊ธ์ ํ๋์ด ์ฐ๊ณ ์๋ ๊ฒ์ด ์๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋. ์ ๋ฌธ ์ปค๋ฎค๋ํฐ์์ ์ฌ์ฉํ๊ณ ์ถ์ต๋๋ค. ๋น๋๋ด, ๋ ๋์ด์ก๊ณ , ๋งค๋ด์ผ๋ ๋ฒ์ญ๋์์ผ๋ฉฐ, ์์ ๋ ๋ ๋ง์์ก์ต๋๋ค.
๊ด์ฌ์ ๊ฐ์ ธ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค. ํ์ด์ ๋น์ด์.
์ถ์ฒ : habr.com