BuildBot์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง€์†์  ํ†ตํ•ฉ์„ ๊ตฌํ˜„ํ•˜๋Š” ์˜ˆ

BuildBot์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง€์†์  ํ†ตํ•ฉ์„ ๊ตฌํ˜„ํ•˜๋Š” ์˜ˆ
(์ด๋ฏธ์ง€ by ์ปดํ“จํ„ฐํ™”๊ธฐ ์— ํ”ฝ์‚ฌ๋ฒ ์ด)

ะŸั€ะธะฒะตั‚!

๋‚ด ์ด๋ฆ„ ์˜ˆ๋ธŒ๊ฒŒ๋‹ˆ ์ฒด๋ฅดํ‚จ, ์ €๋Š” ๊ด‘์‚ฐํšŒ์‚ฌ ๊ฐœ๋ฐœํŒ€์˜ ํ”„๋กœ๊ทธ๋ž˜๋จธ์ž…๋‹ˆ๋‹ค. ํด๋ฆฌ ๋ฉ”ํƒˆ.

๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ "์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐ ์–ด๋–ค ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์€๊ฐ€?"๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. IT ํ”„๋กœ์ ํŠธ๋Š” ๋‹ค์Œ ๋ฒ„์ „์„ ์ถœ์‹œํ•˜๊ธฐ ์ „์— ์—ฌ๋Ÿฌ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์นฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋‹จ๊ณ„์˜ ์ฒด์ธ์ด ์ž๋™ํ™”๋˜๋ฉด ์ข‹์Šต๋‹ˆ๋‹ค. IT ํ”„๋กœ์ ํŠธ ์ž์ฒด์˜ ์ƒˆ ๋ฒ„์ „์„ ์ถœ์‹œํ•˜๋Š” ์ž๋™ํ™”๋œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ง€์†์ ์ธ ํ†ตํ•ฉ. ๋นŒ๋“œ๋ด‡ ์ด ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์ข‹์€ ์กฐ๋ ฅ์ž๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ธฐ์‚ฌ์—์„œ ๋‚˜๋Š” ๊ฐ€๋Šฅ์„ฑ์— ๋Œ€ํ•œ ๊ฐœ์š”๋ฅผ ์ œ๊ณตํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ๋ด‡. ์ด ์†Œํ”„ํŠธ์›จ์–ด๋Š” ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ๋‚˜์š”? ๊ทธ์—๊ฒŒ ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๊ทธ์™€ ์ •์ƒ์ ์ธ ํšจ๊ณผ์ ์ธ ์—…๋ฌด ๊ด€๊ณ„๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๊ท€ํ•˜์˜ ์ปดํ“จํ„ฐ์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•œ ์ž‘์—… ์„œ๋น„์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์šฐ๋ฆฌ์˜ ๊ฒฝํ—˜์„ ์ง์ ‘ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด์šฉ

๋‚ด์šฉ

1. ์™œ BuildBot์ธ๊ฐ€?
2. BuildMaster๊ฐ€ ์ฃผ๋„ํ•˜๋Š” ์ปจ์…‰
3. ์„ค์น˜
4. ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„

5. ๊ตฌ์„ฑ. ๋‹จ๊ณ„๋ณ„ ๋ ˆ์‹œํ”ผ

5.1 BuildmasterConfig
5.2 ๋…ธ๋™์ž
5.3 ๋ณ€๊ฒฝ_์†Œ์Šค
5.4 ์Šค์ผ€์ค„๋Ÿฌ

5.5 ๋นŒ๋“œํŒฉํ† ๋ฆฌ
5.6๋ช…์˜ ๊ฑด์ถ•์—…์ž

6. ์ž์‹ ๋งŒ์˜ ๊ตฌ์„ฑ ์˜ˆ์‹œ

6.1 master.cfg๋กœ ๊ฐ€๋Š” ์ค‘
6.2 svn์œผ๋กœ ์ž‘์—…ํ•˜๊ธฐ
6.3 ๊ท€ํ•˜์—๊ฒŒ ๋ณด๋‚ด๋Š” ํŽธ์ง€: ๊ธฐ์ž๋Š” ์„ ์–ธํ•  ๊ถŒํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ํ•ด๋ƒˆ๋‹ค! ์ถ•ํ•˜ํ•ด์š”

1. ์™œ BuildBot์ธ๊ฐ€?

์ด์ „์— habr-e์—์„œ ๊ตฌํ˜„์— ๊ด€ํ•œ ๊ธฐ์‚ฌ๋ฅผ ์ ‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€์†์ ์ธ ํ†ตํ•ฉ ์‚ฌ์šฉ ๋นŒ๋“œ๋ด‡. ์˜ˆ: ์ด๊ฑฐ ๊ฐ€์žฅ ์œ ์ตํ•˜๋‹ค๊ณ  ๋Š๊ผˆ์Šต๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ์˜ˆ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค - ๋” ๋‹จ์ˆœํ•œ. ์ด ๊ธฐ์‚ฌ๋Š” ์–‘๋…์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๋งค๋‰ด์–ผ์˜ ์˜ˆ๊ณผ ๊ทธ๊ฒƒ ๊ทธ ์ดํ›„์—๋Š” ์˜์–ด๋กœ. ์ฟ ํŽ˜๋Š” ์ข‹์€ ์ถœ๋ฐœ์ ์ด ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ์‚ฌ๋ฅผ ์ฝ์€ ํ›„์—๋Š” ์•„๋งˆ๋„ ์ฆ‰์‹œ ๋ญ”๊ฐ€๋ฅผ ์›ํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋นŒ๋“œ๋ด‡ ํ• 

๋ฉˆ์ถ”๋‹ค! ์‹ค์ œ๋กœ ํ”„๋กœ์ ํŠธ์— ์‚ฌ์šฉํ•œ ์‚ฌ๋žŒ์ด ์žˆ๋‚˜์š”? ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ๋งŽ์€ ๊ทธ๊ฒƒ์„ ์ž์‹ ์˜ ์—…๋ฌด์— ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฐพ์„์ˆ˜์žˆ๋‹ค ์˜ˆ์ œ๋“ค ์‚ฌ์šฉ ๋นŒ๋“œ๋ด‡ ๊ทธ๋ฆฌ๊ณ  Google ์ฝ”๋“œ ์•„์นด์ด๋ธŒ์— ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์‚ฌ๋žŒ๋“ค์ด ์‚ฌ์šฉํ•˜๋Š” ๋…ผ๋ฆฌ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋นŒ๋“œ ๋ด‡? ๊ฒฐ๊ตญ, ๋‹ค๋ฅธ ๋„๊ตฌ๋„ ์žˆ์Šต๋‹ˆ๋‹ค: ํฌ๋ฃจ์ฆˆ ์ปจํŠธ๋กค ะธ ์  ํ‚จ์Šค. ๋‚˜๋Š” ์ด๋ ‡๊ฒŒ ๋Œ€๋‹ตํ•  ๊ฒƒ์ด๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ž‘์—…์— ๋Œ€ํ•ด ์  ํ‚จ์Šค ์ง„์‹ค์€ ์ถฉ๋ถ„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฐจ๋ก€๋กœ, ๋นŒ๋“œ๋ด‡ - ๋” ์ ์‘๋ ฅ์ด ๋›ฐ์–ด๋‚˜๊ณ  ๋ฌธ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ์  ํ‚จ์Šค. ์„ ํƒ์€ ๋‹น์‹ ์˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•œ ๋„๊ตฌ๋ฅผ ์ฐพ๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๊ฐ„๋‹จํ•œ ๋‹จ๊ณ„๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ์ƒํ˜ธ ์ž‘์šฉ์„ฑ๊ณผ ๊ณ ์œ ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ–์ถ˜ ๋นŒ๋“œ ์‹œ์Šคํ…œ์„ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Python์œผ๋กœ ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋Š” "ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์–ธ์–ด ์ธก๋ฉด์—์„œ ๋ช…ํ™•ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ–์ถ˜ ํ†ตํ•ฉ ์‹œ์Šคํ…œ์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์–ด๋–จ๊นŒ์š”?"๋ผ๋Š” ์งˆ๋ฌธ์ด ์ƒ๊น๋‹ˆ๋‹ค. ์ด์ œ ์žฅ์ ์„ ์†Œ๊ฐœํ•  ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค ๋นŒ๋“œ๋ด‡.

๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ์˜ "์•…๊ธฐ XNUMX ์ค‘์ฃผ". ๋‚˜ ์ž์‹ ์„ ์œ„ํ•ด ๋„ค ๊ฐ€์ง€ ํŠน์ง•์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ๋ด‡:

  1. GPL ๋ผ์ด์„ผ์Šค์— ๋”ฐ๋ฅธ ์˜คํ”ˆ ์†Œ์Šค ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.
  2. Python์„ ๊ตฌ์„ฑ ๋„๊ตฌ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ํ•„์š”ํ•œ ์ž‘์—…์— ๋Œ€ํ•œ ์„ค๋ช…์ž…๋‹ˆ๋‹ค.
  3. ์ด๋Š” ์กฐ๋ฆฝ์ด ์ด๋ฃจ์–ด์ง€๋Š” ๊ธฐ๊ณ„๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ์ž…๋‹ˆ๋‹ค.
  4. ๋งˆ์ง€๋ง‰์œผ๋กœ ํ˜ธ์ŠคํŠธ์˜ ์ตœ์†Œ ์š”๊ตฌ ์‚ฌํ•ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฐฐํฌ์—๋Š” Python ๋ฐ Twisted๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ ๊ฐ€์ƒ ๋จธ์‹  ๋ฐ Java ๋จธ์‹ ์€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

2. BuildMaster๊ฐ€ ์ฃผ๋„ํ•˜๋Š” ์ปจ์…‰

BuildBot์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง€์†์  ํ†ตํ•ฉ์„ ๊ตฌํ˜„ํ•˜๋Š” ์˜ˆ

์ž‘์—… ๋ถ„๋ฐฐ ์•„ํ‚คํ…์ฒ˜์˜ ํ•ต์‹ฌ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ๋งˆ์Šคํ„ฐ. ์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.

  • ์ถ”์ ํ•˜๋‹ค ํ”„๋กœ์ ํŠธ ์†Œ์Šค ํŠธ๋ฆฌ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ
  • ๋ณด๋ƒ„ ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์—…์ž ์„œ๋น„์Šค์—์„œ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ๋ช…๋ น
  • ํ†ต์ง€ ์ทจํ•ด์ง„ ์กฐ์น˜์˜ ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž

๋นŒ๋“œ๋งˆ์Šคํ„ฐ ํŒŒ์ผ์„ ํ†ตํ•ด ๊ตฌ์„ฑ๋จ 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 # ะกะพะฑัั‚ะฒะตะฝะฝะพ ัะดะตััŒ ะธ ัะพะทะดะฐะตะผ

๋‹ค์Œ ๋‹จ๊ณ„. ๋งŒ๋“ค์–ด ๋ณด์ž ๋…ธ๋™์ž. ์šฐ๋ฆฌ ํด๋”์— ์žˆ์„ ๊ฑฐ์˜ˆ์š” /์ง‘/habr/์ž‘์—…์ž.

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

๋‹น์‹ ์ด ๋‹ฌ๋ฆด ๋•Œ ๋…ธ๋™์ž, ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค์Œ ์œ„์น˜์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. /์ง‘/habr/์ž‘์—…์ž ํ”„๋กœ์ ํŠธ ์ด๋ฆ„์ด ์ง€์ •๋œ ํด๋” master.cfg. ๊ทธ๋ฆฌ๊ณ  ํ”„๋กœ์ ํŠธ ์ด๋ฆ„์˜ ํด๋”์— ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๋นŒ๋“œ, ๊ทธ๋ฆฌ๊ณ  ์•ž์œผ๋กœ๋„ ๊ทธ๋Ÿด ๊ฒƒ์ด๋‹ค ์ ๊ฒ€. ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ ๋…ธ๋™์ž-๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์€ ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค /home/habr/yourProject/๋นŒ๋“œ.

"ํ™ฉ๊ธˆ์—ด์‡ 
์ด์ œ ์ œ๊ฐ€ ์ด์ „ ๋‹จ๋ฝ์„ ์“ด ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋งˆ์Šคํ„ฐ ~์—๊ฒŒ ์š”๊ตฌํ•  ๊ฒƒ์ด๋‹ค ๋…ธ๋™์ž- ์Šคํฌ๋ฆฝํŠธ์— ์‹คํ–‰ ๊ถŒํ•œ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ์›๊ฒฉ์œผ๋กœ ์ˆ˜ํ–‰๋˜๋ฉด ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ƒํ™ฉ์„ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ์—ด์‡ ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค --umask=0o22, ์ด ๋””๋ ‰ํ† ๋ฆฌ์— ์“ฐ๊ธฐ๋ฅผ ๊ธˆ์ง€ํ•˜์ง€๋งŒ ์‹คํ–‰ ๊ถŒํ•œ์€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์ด ์šฐ๋ฆฌ์—๊ฒŒ ํ•„์š”ํ•œ ์ „๋ถ€์ž…๋‹ˆ๋‹ค.

๋นŒ๋“œ๋งˆ์Šคํ„ฐ ะธ ๋…ธ๋™์ž ์„œ๋กœ ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๊นจ์ง€๋Š” ์ผ์ด ๋ฐœ์ƒํ•˜๊ณ  ๋…ธ๋™์ž ์ž ์‹œ ๋™์•ˆ์˜ ์‘๋‹ต์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ๋งˆ์Šคํ„ฐ-ใ…. ์‘๋‹ต์ด ์—†์œผ๋ฉด ์—ฐ๊ฒฐ์ด ๋‹ค์‹œ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ์—ด์‡  --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 โ€” ๊ตฌ์„ฑ ํŒŒ์ผ์˜ ๊ธฐ๋ณธ ์‚ฌ์ „์ž…๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ํŒŒ์ผ์— ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ ํŽธ์˜์„ฑ์„ ์œ„ํ•ด ๊ตฌ์„ฑ ์ฝ”๋“œ์— ๋ณ„์นญ์ด ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค. "์”จ". ์ œ๋ชฉ ์—ด์‡  ะฒ c["keyFromDist"] ์ƒํ˜ธ์ž‘์šฉ์„ ์œ„ํ•œ ๊ณ ์ • ์š”์†Œ์ž…๋‹ˆ๋‹ค. ๋นŒ๋“œ๋งˆ์Šคํ„ฐ. ๊ฐ ํ‚ค์— ๋Œ€ํ•ด ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ๊ฐ’์œผ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค.

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์€ ์ €์žฅ์†Œ์˜ ๋กœ์ปฌ ๋ฒ„์ „์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

์ง€์‚ฌ ๋”ฐ๋ผ์•ผ ํ•  ์ €์žฅ์†Œ์˜ ํŠน์ • ๋ถ„๊ธฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํด๋ง ๊ฐ„๊ฒฉ ๊ทธ ์ดํ›„์˜ ์ดˆ ์ˆ˜๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ๋นŒ๋“œ๋งˆ์Šคํ„ฐ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์ €์žฅ์†Œ๋ฅผ ํด๋งํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ์ €์žฅ์†Œ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ถ”์ ํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ ํˆฌํ‘œ, ์ด๋Š” ๋‹ค์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋นŒ๋“œ๋งˆ์Šคํ„ฐ ์ •๊ธฐ์ ์œผ๋กœ ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ ํด๋งํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ์— ๋ฒ”ํ•˜๋‹ค ์ €์žฅ์†Œ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฐ˜์˜ํ•œ ๋‹ค์Œ ๋นŒ๋“œ๋งˆ์Šคํ„ฐ ์•ฝ๊ฐ„์˜ ์ง€์—ฐ์œผ๋กœ ๋‚ด๋ถ€ ๊ฐœ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋ณ€ํ™” ๊ทธ๋ฆฌ๊ณ  ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋กœ ๋ณด๋‚ด์ฃผ์„ธ์š” ์Šค์ผ€์ค„๋Ÿฌ, ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋™์ž-์ด์žํ˜•. ์ด ๋‹จ๊ณ„ ์ค‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค ์ตœ์‹  ์ •๋ณด ์ €์žฅ์†Œ. ์ •ํ™•ํžˆ ์ผœ์ง ๋…ธ๋™์ž๊ทธ๋Ÿฌ๋ฉด ์ €์žฅ์†Œ์˜ ๋กœ์ปฌ ๋ณต์‚ฌ๋ณธ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ ๋‘ ์„น์…˜์—์„œ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. (5.4 ะธ 5.5).

์ €์žฅ์†Œ์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ถ”์ ํ•˜๋Š” ํ›จ์”ฌ ๋” ์šฐ์•„ํ•œ ๋ฐฉ๋ฒ•์€ ์ €์žฅ์†Œ๋ฅผ ํ˜ธ์ŠคํŒ…ํ•˜๋Š” ์„œ๋ฒ„์—์„œ ์ง์ ‘ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋นŒ๋“œ๋งˆ์Šคํ„ฐ- ํ”„๋กœ์ ํŠธ ์†Œ์Šค ์ฝ”๋“œ ๋ณ€๊ฒฝ์— ๋Œ€ํ•ด. ์ด ๊ฒฝ์šฐ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋งŒ๋“œ๋Š” ์ฆ‰์‹œ ๋ฒ”ํ•˜๋‹ค, ํ”„๋กœ์ ํŠธ ์ €์žฅ์†Œ๊ฐ€ ์žˆ๋Š” ์„œ๋ฒ„๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๋นŒ๋“œ๋งˆ์Šคํ„ฐ-์™€์ด. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๋Š” ์ฐจ๋ก€๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ด๋ฅผ ๊ฐ€๋กœ์ฑŒ ๊ฒƒ์ž…๋‹ˆ๋‹ค. 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"]))

์Šค์ผ€์ค„๋Ÿฌ โ€“ ์ด๋Š” ํ”„๋กœ์ ํŠธ์˜ ์ „์ฒด ์กฐ๋ฆฝ ๋ฐ ํ…Œ์ŠคํŠธ ์ฒด์ธ์„ ์‹œ์ž‘ํ•˜๋Š” ํŠธ๋ฆฌ๊ฑฐ ์—ญํ• ์„ ํ•˜๋Š” ์š”์†Œ์ž…๋‹ˆ๋‹ค.
BuildBot์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง€์†์  ํ†ตํ•ฉ์„ ๊ตฌํ˜„ํ•˜๋Š” ์˜ˆ

๊ธฐ๋ก๋œ ๋ณ€๊ฒฝ์‚ฌํ•ญ ๋ณ€๊ฒฝ_์†Œ์Šค, ์ž‘์—… ๊ณผ์ •์—์„œ ๋ณ€ํ˜•๋จ ๋นŒ๋“œ๋ด‡-a ์ด์˜๋ฅผ ์ œ๊ธฐํ•˜๋‹ค ๋ณ€ํ™” ๊ทธ๋ฆฌ๊ณ  ์ง€๊ธˆ์€ ๋งค ์…ฐ๋“ˆ๋Ÿฌ ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹œ์ž‘ํ•˜๋ผ๋Š” ์š”์ฒญ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฌํ•œ ์š”์ฒญ์ด ๋Œ€๊ธฐ์—ด๋กœ ์ถ”๊ฐ€๋กœ ์ „์†ก๋˜๋Š” ์‹œ๊ธฐ๋„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด ๊ฑด์ถ•์—…์ž ์š”์ฒญ ๋Œ€๊ธฐ์—ด์„ ์ €์žฅํ•˜๊ณ  ํ˜„์žฌ ์–ด์…ˆ๋ธ”๋ฆฌ์˜ ์ƒํƒœ๋ฅผ ๋ณ„๋„์˜ ์œ„์น˜์— ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋™์ž-์ด์žํ˜•. ๊ฑด์ถ•์—…์ž ์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค ๋นŒ๋“œ๋งˆ์Šคํ„ฐ-e ์ด์ƒ ๋…ธ๋™์ž-์ด์žํ˜•. ๊ทธ๋Š” ํ•จ๊ป˜ ๋ณด๋‚ธ๋‹ค ๋นŒ๋“œ๋งˆ์Šคํ„ฐ-์— ๋…ธ๋™์ž-๊ทธ๋ฆฌ๊ณ  ์ด๋ฏธ ๊ตฌ์ฒด์ ์ด๋‹ค ๋นŒ๋“œ - ๋ฐ˜๋“œ์‹œ ๋”ฐ๋ผ์•ผ ํ•  ์ผ๋ จ์˜ ๋‹จ๊ณ„.
์šฐ๋ฆฌ๋Š” ํ˜„์žฌ ์˜ˆ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ์Šค์ผ€์ค„๋Ÿฌ 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. ๊ทธ๋Ÿฌ๋‚˜ ๋‘ ๊ฐ€์ง€ "๊ทธ๋Ÿฌ๋‚˜"๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋…ธ๋™์ž ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. --umask ์ดํ›„ ์‹คํ–‰ ๊ถŒํ•œ์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š๋„๋ก ์ ๊ฒ€-NS.
  2. ์— git push-e ์ด ์Šคํฌ๋ฆฝํŠธ ์ค‘ ์†์„ฑ์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ๊ทธ๋ž˜์„œ ๋‚˜์ค‘์— Chechout-e๋Š” Git ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ๊ถŒํ•œ์„ ์žƒ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

5.6๋ช…์˜ ๊ฑด์ถ•์—…์ž


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

๊ทธ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€์— ๋Œ€ํ•ด ๊ฑด์ถ•์—…์ž ๋“ค์—ˆ๋‹ค ์—ฌ๊ธฐ์—. ์ด์ œ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ๋ ค ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ๋นŒ๋” ๊ตฌ์„ฑ ์ƒ์„ฑ์ž์ž…๋‹ˆ๋‹ค ๊ฑด์ถ•์—…์ž. ๊ทธ๋Ÿฐ ๋””์ž์ด๋„ˆ๋“ค c['๋นŒ๋”'] ๊ฐœ์ฒด ์‹œํŠธ์ด๋ฏ€๋กœ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฑด์ถ•์—…์ž ์œ ํ˜•. ์ด์ œ ์˜ˆ์ œ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ๋ด‡, ์šฐ๋ฆฌ์˜ ์ž„๋ฌด์— ๋” ๊ฐ€๊นŒ์›Œ์กŒ์Šต๋‹ˆ๋‹ค.


c['builders'] = []
c['builders'].append(util.BuilderConfig(name="yourProject",
                                            workernames=["yourWorkerName"],
                                            factory=factory))

์ด์ œ ๋งค๊ฐœ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋นŒ๋” ๊ตฌ์„ฑ.

name ์ด๋ฆ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค ๊ฑด์ถ•์—…์ž-ใ…. ์—ฌ๊ธฐ์— ์ด๋ฆ„์„ ๋ถ™์˜€์Šต๋‹ˆ๋‹ค. ๋„ˆ์˜ ํ”„๋กœ์ ํŠธ. ์ด๋Š” ๋‹ค์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋™์ž- ๋ฐ”๋กœ ์ด ๊ธธ์ด ๋งŒ๋“ค์–ด์งˆ ๊ฒƒ์ด๋‹ค /home/habr/worker/yourProject/build. ์…ฐ๋“ˆ๋Ÿฌ ์ฐพ๊ณ ์žˆ๋Š” ๊ฑด์ถ•์—…์ž ๋ฐ”๋กœ ์ด ์ด๋ฆ„์œผ๋กœ.

์ž‘์—…์ž ์ด๋ฆ„ ์‹œํŠธ ํฌํ•จ ๋…ธ๋™์ž-์—์Šค. ๊ฐ๊ฐ ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ํ•ญ๋ชฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. c['๋…ธ๋™์ž'].

๊ณต์žฅ - ํŠน์ •ํ•œ ๋นŒ๋“œ, ์ด๋Š” ์—ฐ๊ด€๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฑด์ถ•์—…์ž. ๊ทธ๋Š” ๋ฌผ๊ฑด์„ ๋ณด๋‚ผ ๊ฒƒ์ด๋‹ค ๋นŒ๋“œ ์— ๋…ธ๋™์ž ์—ฌ๊ธฐ์— ํฌํ•จ๋œ ๋ชจ๋“  ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ•˜๋ ค๋ฉด ๋นŒ๋“œ-NS.

6. ์ž์‹ ๋งŒ์˜ ๊ตฌ์„ฑ ์˜ˆ์‹œ

๋‹ค์Œ์€ ์ œ๊ฐ€ ๊ตฌํ˜„์„ ์ œ์•ˆํ•˜๋Š” ํ”„๋กœ์ ํŠธ ์•„ํ‚คํ…์ฒ˜์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค. ๋นŒ๋“œ๋ด‡
.

๋ฒ„์ „ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. svn. ์ €์žฅ์†Œ ์ž์ฒด๋Š” ์ผ์ข…์˜ ํด๋ผ์šฐ๋“œ์— ์œ„์น˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ํด๋ผ์šฐ๋“œ์˜ ์ฃผ์†Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค svn.host/svn/yourProject/trunk. ๊ตฌ๋ฆ„ ์•„๋ž˜์—๋Š” svn ๊ณ„์ • ์‚ฌ์šฉ์ž ์ด๋ฆ„์ด ์žˆ์Šต๋‹ˆ๋‹ค: ์‚ฌ์šฉ์ž, ๋น„๋ฐ€๋ฒˆํ˜ธ: ์•”ํ˜ธ. ๋‹จ๊ณ„๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์Šคํฌ๋ฆฝํŠธ ๋นŒ๋“œ-a๋„ ์ง€์ ์— ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. svn, ๋ณ„๋„์˜ ํด๋”์— ๋นŒ๋“œ๋ด‡/worker_linux. ์ด๋Ÿฌํ•œ ์Šคํฌ๋ฆฝํŠธ๋Š” ์ €์žฅ๋œ ์†์„ฑ์ด ์žˆ๋Š” ์ €์žฅ์†Œ์— ์žˆ์Šต๋‹ˆ๋‹ค. ์‹คํ–‰ ํŒŒ์ผ.

๋นŒ๋“œ๋งˆ์Šคํ„ฐ ะธ ๋…ธ๋™์ž ๋™์ผํ•œ ํ˜ธ์ŠคํŠธ์—์„œ ์‹คํ–‰ ํ”„๋กœ์ ํŠธ.ํ˜ธ์ŠคํŠธ .๋นŒ๋“œ๋งˆ์Šคํ„ฐ ํŒŒ์ผ์„ ํด๋”์— ์ €์žฅ /์ง‘/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"
}

๋จผ์ € ํ•„์š”ํ•œ ์ฐฝ์กฐํ•˜๋‹ค ๋นŒ๋“œ๋งˆ์Šคํ„ฐ-a ๊ทธ๋ฆฌ๊ณ  ๋…ธ๋™์ž-ใ…. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด ํŒŒ์ผ์„ ๋ถ™์—ฌ๋„ฃ์œผ์„ธ์š”. master.cfg ะฒ /์ง‘/habr/๋งˆ์Šคํ„ฐ.

๋‹ค์Œ ๋‹จ๊ณ„๋Š” ์„œ๋น„์Šค๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค ๋นŒ๋“œ๋งˆ์Šคํ„ฐ์•„์•„


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์€ ๋งˆํฌ์—…์„ ๋งŒ๋“œ๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์—”์ง„์— ์˜ํ•ด ์ˆ˜์ •๋ฉ๋‹ˆ๋‹ค. ์ง„์ž 2 (๋น„๊ต๋  ์ˆ˜ โ€‹โ€‹์žˆ๋‹ค ์žฅ๊ณ ). ๋นŒ๋“œ๋ด‡ ๋ฉ”์‹œ์ง€ ํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์—์„œ ๊ฐ’์ด ํ…œํ”Œ๋ฆฟ์œผ๋กœ ๋Œ€์ฒด๋˜๋Š” ๋ณ€์ˆ˜ ์„ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ณ€์ˆ˜๋Š” {{ ์ด์ค‘ ์ค‘๊ด„ํ˜ธ }}๋กœ ๋ฌถ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐœ์š” ์™„๋ฃŒ๋œ ์ž‘์—…์˜ ์ƒํƒœ, ์ฆ‰ ์„ฑ๊ณต ๋˜๋Š” ์‹คํŒจ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ใ… ํ”„๋กœ์ ํŠธ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค ๋„ˆ์˜ ํ”„๋กœ์ ํŠธ. ๋”ฐ๋ผ์„œ ์ œ์–ด ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง„์ž 2, ๋ณ€์ˆ˜ ๋นŒ๋“œ๋ด‡-a ๋ฐ Python ๋ฌธ์ž์—ด ํ˜•์‹ ์ง€์ • ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋งค์šฐ ์œ ์ตํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉ”์ผ์•Œ๋ฆผ๊ธฐ ๋‹ค์Œ ์ธ์ˆ˜๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

fromaddr โ€“ ๋ชจ๋“  ์‚ฌ๋žŒ์ด ๋‰ด์Šค๋ ˆํ„ฐ๋ฅผ ๋ฐ›์„ ์ฃผ์†Œ.

๊ด€์‹ฌ ์žˆ๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด๋‚ด๊ธฐ=True๋Š” ๋งŒ๋“  ์†Œ์œ ์ž์™€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๋ฒ”ํ•˜๋‹ค.

์กฐํšŒ โ€” ๋‰ด์Šค๋ ˆํ„ฐ๋ฅผ ๋ฐ›๋Š” ์‚ฌ์šฉ์ž ์ด๋ฆ„์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ์ ‘๋ฏธ์‚ฌ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ด€๋ฆฌ์ž ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ์ฃผ์†Œ์—์„œ ๋‰ด์Šค๋ ˆํ„ฐ๋ฅผ ๋ฐ›๋Š” ๋ฐฉ๋ฒ• [์ด๋ฉ”์ผ ๋ณดํ˜ธ].

๋ฆด๋ ˆ์ดํ˜ธ์ŠคํŠธ ์„œ๋ฒ„๊ฐ€ ์—ด๋ฆฌ๋Š” ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. SMTP์€ smptํฌํŠธ ์ˆ˜์‹ ํ•˜๋Š” ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. SMTP ์„œ๋ฒ„.

๋ชจ๋“œ="๊ฒฝ๊ณ " ์ ์–ด๋„ ํ•˜๋‚˜์˜ ๋‹จ๊ณ„๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ฉ”์ผ๋ง์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. ๋นŒ๋“œ-a, ์ƒํƒœ ์‹คํŒจ ๋˜๋Š” ๊ฒฝ๊ณ ๋กœ ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์„ฑ๊ณตํ•  ๊ฒฝ์šฐ ๋‰ด์Šค๋ ˆํ„ฐ๋ฅผ ๋ณด๋‚ผ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€์ˆ˜์‹ ์ž ์†Œ์œ ์ž์™€ ํ•ด๋‹น ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ ์‚ฌ๋žŒ ์™ธ์— ์šฐํŽธ๋ฌผ์„ ๋ณด๋‚ด์•ผ ํ•˜๋Š” ์‚ฌ๋žŒ์˜ ๋ชฉ๋ก์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒ”ํ•˜๋‹ค.

๋ฉ”์‹œ์ง€ํฌ๋งท ๋ฉ”์‹œ์ง€ ํ˜•์‹, ํ•ด๋‹น ํ…œํ”Œ๋ฆฟ, ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜ ์ง‘ํ•ฉ์„ ์ง€์ •ํ•˜๋Š” ๊ฐœ์ฒด์ž…๋‹ˆ๋‹ค. ์ง„์ž 2. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ต์…˜ ์›ํ•˜๋Š”์†์„ฑ=์ฐธ ะธ ์›ํ•˜๋Š” ๋‹จ๊ณ„=์ฐธ ์ด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜ ์„ธํŠธ๋ฅผ ์ •์˜ํ•˜์‹ญ์‹œ์˜ค.

with['services']=[sendMessageToAll] ์„œ๋น„์Šค ๋ชฉ๋ก์„ ์ œ๊ณตํ•˜๋ฉฐ ๊ทธ ์ค‘ ์šฐ๋ฆฌ ์„œ๋น„์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์‹ ๊ณ ์ž.

์šฐ๋ฆฌ๋Š” ํ•ด๋ƒˆ๋‹ค! ์ถ•ํ•˜ํ•ด์š”

์šฐ๋ฆฌ๋Š” ์ž์ฒด ๊ตฌ์„ฑ์„ ๋งŒ๋“ค๊ณ  ๊ทธ๊ฒƒ์ด ๊ฐ€๋Šฅํ•œ ๊ธฐ๋Šฅ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ๋ด‡. ์ œ ์ƒ๊ฐ์—๋Š” ์ด ๋„๊ตฌ๊ฐ€ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ์ง€ ์ดํ•ดํ•˜๋Š” ๋ฐ ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์‚ฌ๋žŒ์—๊ฒŒ ๊ด€์‹ฌ์ด ์žˆ๋‚˜์š”? ๋‹น์‹ ์—๊ฒŒ ์œ ์šฉํ• ๊นŒ์š”? ๊ทธ ์‚ฌ๋žŒ์€ ํ•จ๊ป˜ ์ผํ•˜๊ธฐ ํŽธํ•œ๊ฐ€์š”? ๊ทธ๋ ‡๋‹ค๋ฉด ๋‚˜๋Š” ์ด ๊ธ€์„ ํ—›๋˜์ด ์“ฐ๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋”. ์ „๋ฌธ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ๋ด‡, ๋” ๋„“์–ด์กŒ๊ณ , ๋งค๋‰ด์–ผ๋„ ๋ฒˆ์—ญ๋˜์—ˆ์œผ๋ฉฐ, ์˜ˆ์ œ๋„ ๋” ๋งŽ์•„์กŒ์Šต๋‹ˆ๋‹ค.

๊ด€์‹ฌ์„ ๊ฐ€์ ธ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ–‰์šด์„ ๋นŒ์–ด์š”.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€