(рдЫрд╡рд┐ рджреНрд╡рд╛рд░рд╛
рд╣рд╛рдп!
рдореЗрд░рд╛ рдирд╛рдо рдПрд╡рдЧреЗрдиреА рдЪреЗрд░реНрдХрд┐рди, рдореИрдВ рдПрдХ рдЦрдирди рдХрдВрдкрдиреА рдХреА рд╡рд┐рдХрд╛рд╕ рдЯреАрдо рдореЗрдВ рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╣реВрдВ рдкреЙрд▓реАрдореЗрдЯрд▓.
рдХреЛрдИ рднреА рдмрдбрд╝рд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╢реБрд░реВ рдХрд░рддреЗ рд╕рдордп, рдЖрдк рдпрд╣ рд╕реЛрдЪрдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ: "рдЗрд╕реЗ рд╕реЗрд╡рд╛ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдХреМрди рд╕рд╛ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИ?" рдПрдХ рдЖрдИрдЯреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдЕрдЧрд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг рдЬрд╛рд░реА рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХрдИ рдЪрд░рдгреЛрдВ рд╕реЗ рдЧреБрдЬрд░рддреА рд╣реИред рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реИ рдЬрдм рдЗрди рдЪрд░рдгреЛрдВ рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд╣реЛред рдХрд┐рд╕реА IT рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХрд╛ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг рдЬрд╛рд░реА рдХрд░рдиреЗ рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╣реА рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рд▓рдЧрд╛рддрд╛рд░ рдореЗрд▓ рдЬреЛрд▓. рдмрд┐рд▓реНрдбрдмреЙрдЯ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫрд╛ рд╕рд╣рд╛рдпрдХ рд╕рд╛рдмрд┐рдд рд╣реБрдЖред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВрдиреЗ рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХрд╛ рдПрдХ рд╕рд┐рдВрд╣рд╛рд╡рд▓реЛрдХрди рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдмрд┐рд▓реНрдбрдмреЙрдЯ. рдпрд╣ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдХрд┐рд╕рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИ? рдЙрдирд╕реЗ рдХреИрд╕реЗ рд╕рдВрдкрд░реНрдХ рдХрд░реЗрдВ рдФрд░ рдЙрдирдХреЗ рд╕рд╛рде рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рднрд╛рд╡реА рдХрд╛рдордХрд╛рдЬреА рд╕рдВрдмрдВрдз рдХреИрд╕реЗ рдмрдирд╛рдПрдВ? рдЖрдк рдЕрдкрдиреА рдорд╢реАрди рдкрд░ рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╛рд░реНрдпрд╢реАрд▓ рд╕реЗрд╡рд╛ рдмрдирд╛рдХрд░ рд╣рдорд╛рд░реЗ рдЕрдиреБрднрд╡ рдХреЛ рд╕реНрд╡рдпрдВ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╕рд╛рдордЧреНрд░реА
рд╕рд╛рдордЧреНрд░реА
1. рдмрд┐рд▓реНрдбрдмреЙрдЯ рдХреНрдпреЛрдВ?
рдкрд╣рд▓реЗ habr-e рдкрд░ рдореБрдЭреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓реЗрдЦ рдорд┐рд▓реЗ рдереЗ рд▓рдЧрд╛рддрд╛рд░ рдореЗрд▓ рдЬреЛрд▓ рд╕рд╛рде рдмрд┐рд▓реНрдбрдмреЙрдЯ. рдЬреИрд╕реЗ,
рд░реБрдХрдирд╛! рдХреНрдпрд╛ рдХрд┐рд╕реА рдиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕реЗ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ? рдпрд╣ рд╣рд╛рдБ рдирд┐рдХрд▓рд╛
рддреЛ рд▓реЛрдЧреЛрдВ рдХрд╛ рдкреНрд░рдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдХреНрдпрд╛ рддрд░реНрдХ рд╣реИ рдмрд┐рд▓реНрдбрдмреЛрдЯ? рдЖрдЦрд╝рд┐рд░рдХрд╛рд░, рдЕрдиреНрдп рдЙрдкрдХрд░рдг рднреА рд╣реИрдВ: рдХреНрд░реВрдЬ рдирд┐рдпрдВрддреНрд░рдг ╨╕ рдЬреЗрдирдХреАрдВрд╕. рдореИрдВ рдЗрд╕ рддрд░рд╣ рдЙрддреНрддрд░ рджреВрдВрдЧрд╛. рдЕрдзрд┐рдХрд╛рдВрд╢ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЗрдирдХреАрдВрд╕ рдФрд░ рд╕рддреНрдп рд╣реА рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛. рдЗрд╕рдХреА рдмрд╛рд░реА рдореЗрдВ, рдмрд┐рд▓реНрдбрдмреЙрдЯ - рдЕрдзрд┐рдХ рдЕрдиреБрдХреВрд▓реА, рдЬрдмрдХрд┐ рд╡рд╣рд╛рдВ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдЙрддрдиреА рд╣реА рд╕рд░рд▓рддрд╛ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЗрдирдХреАрдВрд╕. рдЪреБрдирд╛рд╡ рддреБрдореНрд╣рд╛рд░рд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЪреВрдБрдХрд┐ рд╣рдо рдПрдХ рд╡рд┐рдХрд╛рд╕рд╢реАрд▓ рд▓рдХреНрд╖реНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдХрд░рдг рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдРрд╕рд╛ рдХреНрдпреЛрдВ рди рдЪреБрдиреЗрдВ рдЬреЛ рд╕рд░рд▓ рдЪрд░рдгреЛрдВ рд╕реЗ рд╢реБрд░реВ рдХрд░рдХреЗ, рдПрдХ рдРрд╕реА рдмрд┐рд▓реНрдб рдкреНрд░рдгрд╛рд▓реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдФрд░ рдПрдХ рдЕрджреНрд╡рд┐рддреАрдп рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реЛред
рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдирдХрд╛ рд▓рдХреНрд╖реНрдп рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкрд╛рдпрдерди рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рд╕рд╡рд╛рд▓ рдЙрдарддрд╛ рд╣реИ: "рдПрдХ рдПрдХреАрдХрд░рдг рдкреНрд░рдгрд╛рд▓реА рдХреНрдпреЛрдВ рди рдЪреБрдиреЗрдВ рдЬрд┐рд╕рдХрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рднрд╛рд╖рд╛ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реЛ?" рдФрд░ рдЕрдм рд▓рд╛рдн рдкреЗрд╢ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рдЖ рдЧрдпрд╛ рд╣реИ рдмрд┐рд▓реНрдбрдмреЙрдЯ.
рддреЛ, рд╣рдорд╛рд░реА "рд╡рд╛рджреНрдп рдЪреМрдХрдбрд╝реА"ред рдЕрдкрдиреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдЪрд╛рд░ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреА рдкрд╣рдЪрд╛рди рдХреА рд╣реИ рдмрд┐рд▓реНрдбрдмреЙрдЯ:
- рдпрд╣ рдЬреАрдкреАрдПрд▓ рд▓рд╛рдЗрд╕реЗрдВрд╕ рдХреЗ рддрд╣рдд рдПрдХ рдУрдкрди рд╕реЛрд░реНрд╕ рдлреНрд░реЗрдорд╡рд░реНрдХ рд╣реИ
- рдпрд╣ рдПрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЯреВрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рдпрдерди рдХрд╛ рдЙрдкрдпреЛрдЧ рдФрд░ рдЖрд╡рд╢реНрдпрдХ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╡рд░рдг рд╣реИ
- рдпрд╣ рдЙрд╕ рдорд╢реАрди рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрд╡рд╕рд░ рд╣реИ рдЬрд┐рд╕ рдкрд░ рдЕрд╕реЗрдВрдмрд▓реА рд╣реЛрддреА рд╣реИ
- рдЖрдЦрд╝рд┐рд░рдХрд╛рд░, рдпреЗ рдПрдХ рдореЗрдЬрд╝рдмрд╛рди рдХреЗ рд▓рд┐рдП рдиреНрдпреВрдирддрдо рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдБ рд╣реИрдВред рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХреЗ рд▓рд┐рдП рдкрд╛рдпрдерди рдФрд░ рдЯреНрд╡рд┐рд╕реНрдЯреЗрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдФрд░ рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдФрд░ рдЬрд╛рд╡рд╛ рдорд╢реАрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред
2. рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░ рдХреЗ рдиреЗрддреГрддреНрд╡ рдореЗрдВ рдЕрд╡рдзрд╛рд░рдгрд╛
рдХрд╛рд░реНрдп рд╡рд┐рддрд░рдг рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХрд╛ рдХреЗрдВрджреНрд░ рд╣реИ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░. рдпрд╣ рдПрдХ рдРрд╕реА рд╕реЗрд╡рд╛ рд╣реИ рдЬреЛ:
- рдирдЬрд╝рд░ рд░рдЦрддрд╛ рд╣реИ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реНрд░реЛрдд рдЯреНрд░реА рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди
- рднреЗрдЬрддрд╛ рд╣реИ рдХрдорд╛рдВрдб рдЬрд┐рдиреНрд╣реЗрдВ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдФрд░ рдЙрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдХрд░ рд╕реЗрд╡рд╛ рджреНрд╡рд╛рд░рд╛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП
- рдЕрдзрд┐рд╕реВрдЪрд┐рдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдХреА рдЧрдИ рдХрд╛рд░реНрд░рд╡рд╛рдЗрдпреЛрдВ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдорд╛рд╕реНрдЯрд░.рд╕реАрдПрдлрдЬреА. рдпрд╣ рдлрд╝рд╛рдЗрд▓ рд░реВрдЯ рдореЗрдВ рд╣реИ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░. рдмрд╛рдж рдореЗрдВ рдореИрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рдпрд╣ рд░реВрдЯ рдХреИрд╕реЗ рдмрдирддрд╛ рд╣реИред рдлрд╝рд╛рдЗрд▓ рд╕реНрд╡рдпрдВ рдорд╛рд╕реНрдЯрд░.рд╕реАрдПрдлрдЬреА рдЗрд╕рдореЗрдВ рдПрдХ рдкрд╛рдпрдерди рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╣реИ рдЬреЛ рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИ рдмрд┐рд▓реНрдбрдмреЙрдЯ.
рдЕрдЧрд▓реА рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╡рд╕реНрддреБ рдмрд┐рд▓реНрдбрдмреЙрдЯ рдпрд╣ рдирд╛рдо рд╣реИ рдХрд╛рдордЧрд╛рд░. рдпрд╣ рд╕реЗрд╡рд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рд╣реЛрд╕реНрдЯ рдкрд░ рднрд┐рдиреНрди OS рдХреЗ рд╕рд╛рде, рдпрд╛ рд╢рд╛рдпрдж рдЙрд╕реА рдкрд░ рд▓реЙрдиреНрдЪ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░. рдпрд╣ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреИрдХреЗрдЬ рдФрд░ рдЪрд░ рдХреЗ рд╕рд╛рде рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рддреИрдпрд╛рд░ рдЖрднрд╛рд╕реА рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рднреА рдореМрдЬреВрдж рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЗрди рдЖрднрд╛рд╕реА рд╡рд╛рддрд╛рд╡рд░рдгреЛрдВ рдХреЛ рдкрд╛рдпрдерди рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рд╡рд░реНрдЪреБрдЕрд▓рдПрдиреНрд╡, рд╡реЗрдирд╡.
рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░ рд╕рднреА рдХреЛ рдЖрджреЗрд╢ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд╛рдордЧрд╛рд░-рдп, рдФрд░ рд╡рд╣, рдмрджрд▓реЗ рдореЗрдВ, рдЙрдиреНрд╣реЗрдВ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИред рдпрд╛рдиреА, рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЬрд╛рд░реА рд░рд╣ рд╕рдХрддреА рд╣реИ рдХрд╛рдордЧрд╛рд░-рдИ рд╡рд┐рдВрдбреЛрдЬрд╝ рдЪрд▓рд╛ рд░рд╣рд╛ рд╣реИ рдФрд░ рджреВрд╕рд░рд╛ рд╡рд░реНрдХрд░ рд▓рд┐рдирдХреНрд╕ рдЪрд▓рд╛ рд░рд╣рд╛ рд╣реИред
рдЪреЗрдХ рдЖрдЙрдЯ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реНрд░реЛрдд рдХреЛрдб рдкреНрд░рддреНрдпреЗрдХ рдкрд░ рд╣реЛрддрд╛ рд╣реИ рдХрд╛рдордЧрд╛рд░-рдЗред
3. рд╕реНрдерд╛рдкрдирд╛
рддреЛ рдЪрд▓рддреЗ рд╣реИрдВред рдореИрдВ рд╣реЛрд╕реНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ Ubuntu 18.04 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ред рдореИрдВ рдЙрд╕ рдкрд░ рдПрдХ рд░рдЦреВрдВрдЧрд╛ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░-рдП рдФрд░ рдПрдХ рдХрд╛рдордЧрд╛рд░-рдПрдХред рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ 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
рдЕрдЧрд▓рд╛ рдЪрд░рдг рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░рдирд╛ рд╣реИ рдЯреНрд╡реАрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ ╨╕ рдмрд┐рд▓реНрдбрдмреЙрдЯ, рд╕рд╛рде рд╣реА рдРрд╕реЗ рдкреИрдХреЗрдЬ рдЬреЛ рдЖрдкрдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ рдмрд┐рд▓реНрдбрдмреЙрдЯ-рдПрдХред
/*╨Т╤Б╨╡ ╤З╤В╨╛ ╨┐╨╛╨┤ 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. рдкрд╣рд▓рд╛ рдХрджрдо
рдмрдирд╛рдиреЗ рдХрд╛ рд╕рдордп рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░. рдпрд╣ рд╣рдорд╛рд░реЗ рдлреЛрд▓реНрдбрд░ рдореЗрдВ рд╣реЛрдЧрд╛ /рд╣реЛрдо/рдПрдЪрдПрдмреАрдЖрд░/рдорд╛рд╕реНрдЯрд░.
mkdir master
buildbot create-master master # ╨б╨╛╨▒╤Б╤В╨▓╨╡╨╜╨╜╨╛ ╤Б╨┤╨╡╤Б╤М ╨╕ ╤Б╨╛╨╖╨┤╨░╨╡╨╝
mkdir worker
buildbot-worker create-worker --umask=0o22 --keepalive=60 worker localhost:4000 yourWorkerName password
рдЬрдм рдЖрдк рджреМрдбрд╝рддреЗ рд╣реИрдВ рдХрд╛рдордЧрд╛рд░, рддреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдпрд╣ рдирд┐рд░реНрдорд┐рдд рд╣реЛ рдЬрд╛рдПрдЧрд╛ /рд╣реЛрдо/рдПрдЪрдПрдмреАрдЖрд░/рдХрд░реНрдордЪрд╛рд░реА рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рдирд╛рдо рд╡рд╛рд▓рд╛ рдлрд╝реЛрд▓реНрдбрд░, рдЬреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╣реИ рдорд╛рд╕реНрдЯрд░.рд╕реАрдПрдлрдЬреА. рдФрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рдирд╛рдо рд╡рд╛рд▓реЗ рдлреЛрд▓реНрдбрд░ рдореЗрдВ рдпрд╣ рдПрдХ рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдмрдирд╛рдПрдЧрд╛ рдирд┐рд░реНрдорд╛рдг, рдФрд░ рдРрд╕рд╛ рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦреЗрдВрдЧреЗ рдЬрд╛рдВрдЪ. рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╢реАрд▓ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХрд╛рдордЧрд╛рд░-рдФрд░ рдпрд╣ рдПрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдмрди рдЬрд╛рдПрдЧреА /home/habr/yourProject/build.
"рд╕реНрд╡рд░реНрдг рдЪрд╛рдмреА
рдФрд░ рдЕрдм рдореИрдВрдиреЗ рдкрд┐рдЫрд▓рд╛ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдХрд┐рд╕рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрд╛ рдерд╛: рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реНрд╡рд╛рдореА рд╕реЗ рдорд╛рдВрдЧ рдХрд░реЗрдВрдЧреЗ рдХрд╛рдордЧрд╛рд░-рдФрд░ рдЗрд╕ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рджреВрд░рд╕реНрде рд░реВрдк рд╕реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рд╣реИред рд╕реНрдерд┐рддрд┐ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдХ рдХреБрдВрдЬреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА
рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░ ╨╕ рдХрд╛рдордЧрд╛рд░ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рд╕рдВрдмрдВрдз рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ. рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЯреВрдЯ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдХрд╛рдордЧрд╛рд░ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕рдордп рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рд╣реВрдБ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░-рдПрдХред рдпрджрд┐ рдХреЛрдИ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рддреЛ рдХрдиреЗрдХреНрд╢рди рдкреБрдирдГ рдкреНрд░рд╛рд░рдВрдн рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЪрд╛рдмреА --рд░рдЦреЗрдВ=60 рдмрд╕ рдЙрд╕рдХреЗ рдмрд╛рдж рдХрд╛ рд╕рдордп рдмрддрд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдХрдиреЗрдХреНрдЯ рд░рд┐рдмреВрдЯред
5. рд╡рд┐рдиреНрдпрд╛рд╕. рд╕реНрдЯреЗрдк рдмрд╛рдИ рд╕реНрдЯреЗрдк рд░реЗрд╕рд┐рдкреА
рд╡рд┐рдиреНрдпрд╛рд╕ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░ рдорд╢реАрди рдХреЗ рдЙрд╕ рддрд░рдл рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╣рдордиреЗ рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХреА рдереА рдХреНрд░рд┐рдПрдЯ-рдорд╛рд╕реНрдЯрд░. рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдПрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╣реИ /рд╣реЛрдо/рдПрдЪрдПрдмреАрдЖрд░/рдорд╛рд╕реНрдЯрд░. рд╡рд┐рдиреНрдпрд╛рд╕ рдлрд╛рдЗрд▓ рдорд╛рд╕реНрдЯрд░.рд╕реАрдПрдлрдЬреА рдЕрднреА рддрдХ рдЕрд╕реНрддрд┐рддреНрд╡ рдореЗрдВ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХрдорд╛рдВрдб рдиреЗ рдкрд╣рд▓реЗ рд╣реА рдлрд╝рд╛рдЗрд▓ рдмрдирд╛ рд▓реА рд╣реИ рдорд╛рд╕реНрдЯрд░.рд╕реАрдПрдордЬреА.рдирдореВрдирд╛. рдЖрдкрдХреЛ рдЗрд╕рдХрд╛ рдирд╛рдо рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ рдорд╛рд╕реНрдЯрд░.рд╕реАрдПрдлрдЬреА.рдирдореВрдирд╛ ╨▓ рдорд╛рд╕реНрдЯрд░.рд╕реАрдПрдлрдЬреА
mv master.cfg.sample 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 рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░ рдХреЙрдиреНрдлрд┐рдЧ
c = 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))
рдХреБрдВрдЬреА рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрди_рд╕реНрд░реЛрдд рдбрд┐рдХреНрд╢рдирд░реА рд╕реА рдореЗрдВ рд╣рдореЗрдВ рдЙрд╕ рд╕реВрдЪреА рддрдХ рдкрд╣реБрдВрдЪ рдорд┐рд▓рддреА рд╣реИ рдЬрд╣рд╛рдВ рд╣рдо рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рд░рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рд╕рд╛рде рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рдкреЛрд▓ рдХрд░рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдПрдХ Git рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдирд┐рд╢реНрдЪрд┐рдд рдЕрдВрддрд░рд╛рд▓ рдкрд░ рд╕рд░реНрд╡реЗрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдкрд╣рд▓рд╛ рддрд░реНрдХ рдЖрдкрдХреЗ рднрдВрдбрд╛рд░ рдХрд╛ рдкрде рд╣реИред
рдХрд╛рд░реНрдпрджрд┐рд░ рдЙрд╕ рдлрд╝реЛрд▓реНрдбрд░ рдХреЗ рдкрде рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдХрд┐рдирд╛рд░реЗ рдкрд░ рд╣реИ рдХрд╛рдордЧрд╛рд░-рдкрде рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ /home/habr/worker/yourProject/build рдЧрд┐рдЯ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЗ рд╕реНрдерд╛рдиреАрдп рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдЧрд╛ред
рд╢рд╛рдЦрд╛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╢рд╛рдЦрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдкрд╛рд▓рди рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдорддрджрд╛рдирдЕрдВрддрд░рд╛рд▓ рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рд╕реЗрдХрдВрдб рдХреА рд╕рдВрдЦреНрдпрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд▓рд┐рдП рднрдВрдбрд╛рд░ рдХрд╛ рд╕рд░реНрд╡реЗрдХреНрд╖рдг рдХрд░реЗрдЧрд╛ред
рдХрд┐рд╕реА рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реИрдВред
рд╕рдмрд╕реЗ рд╕рд░рд▓ рддрд░реАрдХрд╛ рд╣реИ рдорддрджрд╛рди, рдЬрд┐рд╕рдХрд╛ рддрд╛рддреНрдкрд░реНрдп рдпрд╣ рд╣реИ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░ рд╕рдордп-рд╕рдордп рдкрд░ рд╕рд░реНрд╡рд░ рдХреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЗ рд╕рд╛рде рдкреЛрд▓ рдХрд░рддрд╛ рд╣реИред рдЕрдЧрд░ рдХрд░рдирд╛ рдлрд┐рд░, рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдкреНрд░рддрд┐рдмрд┐рдВрдмрд┐рдд рд╣реБрдП рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░ рдХреБрдЫ рджреЗрд░реА рд╕реЗ рдПрдХ рдЖрдВрддрд░рд┐рдХ рд╡рд╕реНрддреБ рдмрдирд╛рдПрдЧрд╛ рдкрд░рд┐рд╡рд░реНрддрди рдФрд░ рдЗрд╕реЗ рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЛ рднреЗрдЬреЗрдВ рд╕рдордпрдмрджреНрдзрдХ, рдЬреЛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдЪрд░рдгреЛрдВ рдХреЛ рд▓реЙрдиреНрдЪ рдХрд░реЗрдЧрд╛ рдХрд╛рдордЧрд╛рд░-рдЗред рдЗрдирдореЗрдВ рд╕реЗ рдЪрд░рдгреЛрдВ рдХрд╛ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЕрджреНрдпрддрди рднрдгреНрдбрд╛рд░. рдмрд┐рд▓рдХреБрд▓ рдЪрд╛рд▓реВ рдХрд╛рдордЧрд╛рд░рдпрд╣ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреА рдПрдХ рд╕реНрдерд╛рдиреАрдп рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдПрдЧрд╛ред рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╡рд┐рд╡рд░рдг рдиреАрдЪреЗ рдЕрдЧрд▓реЗ рджреЛ рдЕрдиреБрднрд╛рдЧреЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред (
рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдФрд░ рднреА рд╢рд╛рдирджрд╛рд░ рддрд░реАрдХрд╛ рдЗрд╕реЗ рд╣реЛрд╕реНрдЯ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╕рд░реНрд╡рд░ рд╕реЗ рд╕реАрдзреЗ рд╕рдВрджреЗрд╢ рднреЗрдЬрдирд╛ рд╣реИ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░- рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реЛрд░реНрд╕ рдХреЛрдб рдмрджрд▓рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВред рдРрд╕реЗ рдореЗрдВ рдЬреИрд╕реЗ рд╣реА рдбреЗрд╡рд▓рдкрд░ рдмрдирд╛рддрд╛ рд╣реИ рдХрд░рдирд╛, рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╡рд╛рд▓рд╛ рд╕рд░реНрд╡рд░ рдПрдХ рд╕рдВрджреЗрд╢ рднреЗрдЬреЗрдЧрд╛ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░-рдп. рдФрд░ рд╡рд╣, рдмрджрд▓реЗ рдореЗрдВ, рдПрдХ рд╡рд╕реНрддреБ рдмрдирд╛рдХрд░ рдЗрд╕реЗ рд░реЛрдХ рджреЗрдЧрд╛ рдкреАрдмреАрдЪреЗрдВрдЬрд╕реЛрд░реНрд╕. рдЗрд╕рдХреЗ рдмрд╛рдж, рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рд╕рдордпрдмрджреНрдзрдХ, рдЬреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдФрд░ рдЙрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рдЪрд░рдгреЛрдВ рдХреЛ рд╕рдХреНрд░рд┐рдп рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдкрджреНрдзрддрд┐ рдХрд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╣реБрдХ-рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╕рд░реНрд╡рд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯред рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд╣реБрдХ-рдП, рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдЬрдм рдХрд░рдирд╛-рдИ, рдЖрдкрдХреЛ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдкрд░рд┐рд╡рд░реНрддрди рднреЗрдЬреЗрдВ рдФрд░ рдиреЗрдЯрд╡рд░реНрдХ рдкрддрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░-рдПрдХред рдЖрдкрдХреЛ рдЙрд╕ рдиреЗрдЯрд╡рд░реНрдХ рдкреЛрд░реНрдЯ рдХреЛ рднреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рд╕реБрдиреЗрдЧрд╛ рдкреАрдмреАрдЪреЗрдВрдЬрд╕реЛрд░реНрд╕. рдкреАрдмреАрдЪреЗрдВрдЬрд╕реЛрд░реНрд╕, рд╡реИрд╕реЗ, рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░-рдПрдХред рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдорддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ-рдП рд╕рд░реНрд╡рд░ рдкрд░ рдЬрд╣рд╛рдВ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реНрдерд┐рдд рд╣реИред рдЖрдкрдХреЛ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХрд╛ рдмреИрдХрдЕрдк рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ред
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"]))
рд╢реЗрдбреНрдпреВрд▓рд░ - рдпрд╣ рдПрдХ рдРрд╕рд╛ рддрддреНрд╡ рд╣реИ рдЬреЛ рдПрдХ рдЯреНрд░рд┐рдЧрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреА рдЕрд╕реЗрдВрдмрд▓реА рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреА рдкреВрд░реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИред
рд╡реЗ рдкрд░рд┐рд╡рд░реНрддрди рдЬреЛ рд░рд┐рдХрд╛рд░реНрдб рдХрд┐рдпреЗ рдЧрдпреЗ рдкрд░рд┐рд╡рд░реНрддрди_рд╕реНрд░реЛрдд, рдХрд╛рд░реНрдп рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд░реВрдкрд╛рдВрддрд░рд┐рдд рд╣реЛ рдЧрдпрд╛ рдмрд┐рд▓реНрдбрдмреЙрдЯ-рдП рдЖрдкрддреНрддрд┐ рдХрд░рдирд╛ рдкрд░рд┐рд╡рд░реНрддрди рдФрд░ рдЕрдм рд╣рд░ рд╕рдордпрдмрджреНрдзрдХ рдЙрдирдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдпрд╣ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдирд┐рд░реНрдорд╛рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдмрдирд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рдпрд╣ рднреА рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдпреЗ рдЕрдиреБрд░реЛрдз рдХрддрд╛рд░ рдореЗрдВ рдЖрдЧреЗ рдХрдм рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдПрдХ рд╡рд╕реНрддреБ
рд╣рдо рд╡рд░реНрддрдорд╛рди рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдРрд╕рд╛ рджреЗрдЦрддреЗ рд╣реИрдВ рд╢реЗрдбреНрдпреВрд▓рд░ 2 рдЯреБрдХрдбрд╝реЗ рдмрдирд╛рдП рдЧрдП рд╣реИрдВ. рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░рддреНрдпреЗрдХ рдХрд╛ рдЕрдкрдирд╛ рдкреНрд░рдХрд╛рд░ рд╣реЛрддрд╛ рд╣реИред
рд╕рд┐рдВрдЧрд▓рдмреНрд░рд╛рдВрдЪ рд╢реЗрдбреНрдпреВрд▓рд░ - рд╢реЗрдбреНрдпреВрд▓ рдкрд░ рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХред рдпрд╣ рдПрдХ рд╢рд╛рдЦрд╛ рдкрд░ рдирдЬрд░ рд░рдЦрддрд╛ рд╣реИ рдФрд░ рдЙрд╕рдореЗрдВ рд░рд┐рдХреЙрд░реНрдб рдХрд┐рдП рдЧрдП рдмрджрд▓рд╛рд╡ рд╕реЗ рдЯреНрд░рд┐рдЧрд░ рд╣реЛрддрд╛ рд╣реИред рдЬрдм рд╡рд╣ рдкрд░рд┐рд╡рд░реНрддрди рджреЗрдЦрддрд╛ рд╣реИ, рддреЛ рд╡рд╣ рдмрд┐рд▓реНрдб рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рдореЗрдВ рджреЗрд░реА рдХрд░ рд╕рдХрддрд╛ рд╣реИ (рд╡рд┐рд╢реЗрд╖ рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЕрд╡рдзрд┐ рдХреЗ рд▓рд┐рдП рд╕реНрдердЧрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЯреНрд░реАрд╕реНрдЯреЗрдмрд▓рдЯрд╛рдЗрдорд░)ред рдирд╛рдо рдЙрд╕ рд╢реЗрдбреНрдпреВрд▓ рдХрд╛ рдирд╛рдо рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдмрд┐рд▓реНрдбрдмреЙрдЯ-рд╡реЗрдм рдЗрдВрдЯрд░рдлреЗрд╕ред рдореЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рдмрджрд▓реЗрдВ рдПрдХ рдлрд╝рд┐рд▓реНрдЯрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╢рд╛рдЦрд╛ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╢реЗрдбреНрдпреВрд▓ рдХреЛ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдореЗрдВ рдмрд┐рд▓реНрдбрд░рдирд╛рдо рдирд╛рдо рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдирд┐рд░реНрдорд╛рддрд╛-рдП, рдЬрд┐рд╕реЗ рд╣рдо рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж рд╕реЗрдЯ рдХрд░реЗрдВрдЧреЗред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдирд╛рдо рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдирд╛рдо рдХреЗ рд╕рдорд╛рди рд╣реЛрдЧрд╛: рдЖрдкрдХрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ.
рдлреЛрд░реНрд╕ рд╢реЗрдбреНрдпреВрд▓рд░ рдмрд╣реБрдд рд╕рд╛рдзрд╛рд░рдг рд╕реА рдмрд╛рдд рд╣реИ. рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╢реЗрдбреНрдпреВрд▓ рдорд╛рдЙрд╕ рдХреНрд▓рд┐рдХ рджреНрд╡рд╛рд░рд╛ рдЯреНрд░рд┐рдЧрд░ рд╣реЛрддрд╛ рд╣реИ рдмрд┐рд▓реНрдбрдмреЙрдЯ-рд╡реЗрдм рдЗрдВрдЯрд░рдлреЗрд╕ред рдкреИрд░рд╛рдореАрдЯрд░реНрд╕ рдХрд╛ рд╕рд╛рд░ рд╡реИрд╕рд╛ рд╣реА рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ рдЗрд╕рдореЗрдВ рд╣реИ рд╕рд┐рдВрдЧрд▓рдмреНрд░рд╛рдВрдЪ рд╢реЗрдбреНрдпреВрд▓рд░.
рдкреАрдПрд╕ рдирдВрдмрд░ 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": "."}))
periodicBuildTimer рдЗрд╕ рдЖрд╡рдзрд┐рдХрддрд╛ рдХрд╛ рд╕рдордп рд╕реЗрдХрдВрдб рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИред
рдмрд┐рд▓реНрдбрдлрд╝реИрдХреНрдЯрд░реА рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдмрдирд╛рддрд╛ рд╣реИ рдирд┐рд░реНрдорд╛рдг, рдлрд┐рд░ рдХреМрди рдирд┐рд░реНрдорд╛рддрд╛ рдХреЛ рднреЗрдЬрддрд╛ рд╣реИ рдХрд╛рдордЧрд╛рд░. рдореЗрдВ рдмрд┐рд▓реНрдбрдлрд╝реИрдХреНрдЯрд░реА рдкрд╛рд▓рди тАЛтАЛрдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЪрд░рдгреЛрдВ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд╛рдордЧрд╛рд░-рдп. рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдЪрд░рдг рдЬреЛрдбрд╝реЗ рдЬрд╛рддреЗ рд╣реИрдВ рдРрдбрд╕реНрдЯреЗрдк
рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдкрд╣рд▓рд╛ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдХрджрдо рд╣реИ рдЧрд┐рдЯ рдХреНрд▓реАрди -рдбреА -рдПрдл -рдПрдл -рдПрдХреНрд╕, рдлрд┐рд░ рдЧрд┐рдЯ рдЪреЗрдХрдЖрдЙрдЯ. рдпреЗ рдХреНрд░рд┐рдпрд╛рдПрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ рддрд░реАрдХрд╛, рдЬреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд╣реАрдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдПрдХ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рддрд╛рдЬрд╛. рдкреИрд░рд╛рдореАрдЯрд░ рдореЛрдб='рд╡реГрджреНрдзрд┐рд╢реАрд▓' рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдлрд╝рд╛рдЗрд▓реЗрдВ рдЙрд╕ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╕реЗ рд╣реИрдВ рдЬрд╣рд╛рдВ chechout, рднрдВрдбрд╛рд░ рд╕реЗ рдЧрд╛рдпрдм рд░рд╣рддреЗ рд╣реБрдП рднреА рдЕрдЫреВрддреЗ рд░рд╣реЗрдВред
рджреВрд╕рд░рд╛ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдЪрд░рдг рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реИ рдкрд░реАрдХреНрд╖рдг рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдирдорд╕реНрддреЗ рдУрд░ рдХрд╛рдордЧрд╛рд░-рдП рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╕реЗ /home/habr/worker/yourProject/build рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ PATHONPATH=... рдХреЗ рд╕рд╛рде, рдЖрдк рдЕрдкрдиреА рд╕реНрд╡рдпрдВ рдХреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдХрд┐рдирд╛рд░реЗ рдкрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд╛рдордЧрд╛рд░-рдПрдХ рд╣рд░ рдХрджрдо рдЙрдкрдпреЛрдЧ.рд╢реЗрд▓рдХрдорд╛рдВрдб. рдЗрди рд╕реНрдХреНрд░рд┐рдкреНрдЯреНрд╕ рдХреЛ рд╕реАрдзреЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд░рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рддреЛ рдлрд┐рд░ chechout-рд╡реЗ рдЗрд╕рдореЗрдВ рдЧрд┐рд░ рдЬрд╛рдпреЗрдВрдЧреЗ /home/habr/worker/yourProject/build. рд╣рд╛рд▓рд╛рдБрдХрд┐, рдлрд┐рд░ рднреА рджреЛ "рд▓реЗрдХрд┐рди" рд╣реИрдВ:
- рдХрд╛рдордЧрд╛рд░ рдПрдХ рдХреБрдВрдЬреА рдХреЗ рд╕рд╛рде рдмрдирд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП
--рдЙрдорд╛рд╕реНрдХ рддрд╛рдХрд┐ рдпрд╣ рдмрд╛рдж рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрди рдЕрдзрд┐рдХрд╛рд░реЛрдВ рдХреЛ рдЕрд╡рд░реБрджреНрдз рди рдХрд░реЗ рдЬрд╛рдВрдЪ-рдПрдХред - рдореЗрдВ git рдзрдХреНрдХрд╛-рдЗрди рд╕реНрдХреНрд░рд┐рдкреНрдЯреЛрдВ рдореЗрдВ рд╕реЗ рдЖрдкрдХреЛ рд╕рдВрдкрддреНрддрд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдирд┐рд╖реНрдкрд╛рджрдирдпреЛрдЧреНрдпрддрд╛рдХрд┐ рдмрд╛рдж рдореЗрдВ chechout-рдИ рдиреЗ 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))
рдЕрдм рдореИрдВ рдЖрдкрдХреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдКрдВрдЧрд╛ рдмрд┐рд▓реНрдбрд░ рдХреЙрдиреНрдлрд┐рдЧ.
рдирд╛рдо рдирд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ рдирд┐рд░реНрдорд╛рддрд╛-рдПрдХред рдпрд╣рд╛рдВ рд╣рдордиреЗ рдЗрд╕реЗ рдирд╛рдо рджрд┐рдпрд╛ рд╣реИ рдЖрдкрдХрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ. рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдЪрд╛рд▓реВ рдХрд╛рдордЧрд╛рд░- рдпрд╣реА рд░рд╛рд╕реНрддрд╛ рдмрдиреЗрдЧрд╛ /home/habr/worker/yourProject/build. рд╕рдордпрдмрджреНрдзрдХ рдвреВрдВрдв рд░рд╣реЗ рд╣реИрдВ рдирд┐рд░реНрдорд╛рддрд╛ рдмрд╕ рдЗрд╕реА рдирд╛рдо рд╕реЗ.
рдХрд╛рд░реНрдпрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдирд╛рдо рд╢реАрдЯ рд╢рд╛рдорд┐рд▓ рд╣реИ рдХрд╛рдордЧрд╛рд░-рдПрд╕ред рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЛ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рд╕реА['рд╢реНрд░рдорд┐рдХ'].
рдХрд╛рд░рдЦрд╛рдирд╛ - рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд┐рд░реНрдорд╛рдг, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдпрд╣ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ рдирд┐рд░реНрдорд╛рддрд╛. рд╡рд╣ рд╡рд╕реНрддреБ рднреЗрдЬ рджреЗрдЧрд╛ рдирд┐рд░реНрдорд╛рдг рдкрд░ рдХрд╛рдордЧрд╛рд░ рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╕рднреА рдЪрд░рдгреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдорд╛рдг-рдПрдХред
6. рдЖрдкрдХреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рдЙрджрд╛рд╣рд░рдг
рдпрд╣рд╛рдВ рдЙрджрд╛рд╣рд░рдг рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рд╣реИ рдЬрд┐рд╕реЗ рдореИрдВ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВ рдмрд┐рд▓реНрдбрдмреЙрдЯ
.
рд╣рдо рдЗрд╕реЗ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░рдгрд╛рд▓реА рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ SVN. рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реНрд╡рдпрдВ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдХреНрд▓рд╛рдЙрдб рдореЗрдВ рд╕реНрдерд┐рдд рд╣реЛрдЧреАред рдпрд╣рд╛рдБ рдЗрд╕ рдмрд╛рджрд▓ рдХрд╛ рдкрддрд╛ рд╣реИ
рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░ ╨╕ рдХрд╛рдордЧрд╛рд░ рдПрдХ рд╣реА рд╣реЛрд╕реНрдЯ рдкрд░ рдЪрд▓рд╛рдПрдБ рдкреНрд░реЛрдЬреЗрдХреНрдЯ.рд╣реЛрд╕реНрдЯ .рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░ рдЕрдкрдиреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдПрдХ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ /рд╣реЛрдо/рдПрдЪрдПрдмреАрдЖрд░/рдорд╛рд╕реНрдЯрд░. рдХрд╛рдордЧрд╛рд░ рдЗрд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрде рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ /рд╣реЛрдо/рдПрдЪрдПрдмреАрдЖрд░/рдХрд░реНрдордЪрд╛рд░реА. рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕рдВрдЪрд╛рд░ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░-рдП рдФрд░ рдХрд╛рдордЧрд╛рд░-рдП рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкреЛрд░реНрдЯ 4000 рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдмрд┐рд▓реНрдбрдмреЙрдЯ-рдП, рдпрд╛рдиреА 'рдкреАрдмреА' рдорд╕рд╡рд┐рджрд╛ рдмрдирд╛рдирд╛ред
рд▓рдХреНрд╖реНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрд╛рдпрдерди рдореЗрдВ рд▓рд┐рдЦреА рдЧрдИ рд╣реИред рдХрд╛рд░реНрдп рдЗрд╕рдХреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдирд╛, рдПрдХ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдирд╛, рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рддреИрдпрд╛рд░ рдХрд░рдирд╛ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рд╣реИред рд╡рд┐рдлрд▓рддрд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╕рднреА рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдИрдореЗрд▓ рджреНрд╡рд╛рд░рд╛ рдПрдХ рд╕рдВрджреЗрд╢ рднреЗрдЬрдирд╛ рд╣реЛрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реЛ рдХрд┐ рдХреЛрдИ рдЕрд╕рдлрд▓ рдХрд╛рд░реНрд░рд╡рд╛рдИ рд╣реБрдИ рд╣реИред
рд╡реЗрдм рдкреНрд░рджрд░реНрд╢рди рдмрд┐рд▓реНрдбрдмреЙрдЯ рд╣рдо рдкреЛрд░реНрдЯ 80 рд╕реЗ рдЬреБрдбрд╝реЗрдВрдЧреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ.рд╣реЛрд╕реНрдЯ. Apatch рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ. рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдореБрдбрд╝ рд╡рд╣рд╛рдБ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рд╡реЗрдм рд╕рд░реНрд╡рд░ рд╣реИ, рдмрд┐рд▓реНрдбрдмреЙрдЯ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ.
рдХреЗ рд▓рд┐рдП рдЖрдВрддрд░рд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд┐рд▓реНрдбрдмреЙрдЯ рд╣рдо рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░реЗрдВрдЧреЗ SQLite.
рдореЗрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реЛрд╕реНрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ smtp.рдЖрдкрдХрд╛.рдбреЛрдореЗрди - рдпрд╣ рдореЗрд▓ рд╕реЗ рдкрддреНрд░ рднреЗрдЬрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ [рдИрдореЗрд▓ рд╕рдВрд░рдХреНрд╖рд┐рдд] рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдХреЗ рдмрд┐рдирд╛. рд╣реЛрд╕реНрдЯ рдкрд░ рднреА 'рдПрд╕рдПрдордЯреАрдкреА ' рдорд┐рдирдЯреНрд╕ рдкреЛрд╕реНрдЯ 1025 рдкрд░ рд╕реБрдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред
рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рджреЛ рд▓реЛрдЧ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ: рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ ╨╕ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛. рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдкреНрд░рд╢рд╛рд╕рди рдХрд░рддрд╛ рд╣реИ рдмрд┐рд▓реНрдбрдмреЙрдЯ. рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд╣ рд╡реНрдпрдХреНрддрд┐ рд╣реИ рдЬреЛ рдкреНрд░рддрд┐рдмрджреНрдз рд╣реИ рдХрд░рдирд╛-рдПрд╕ред
рдирд┐рд╖реНрдкрд╛рджрдирдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИ pyinstaller. рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ Doxygen.
рдЗрд╕ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ рдпрд╣ рд▓рд┐рдЦрд╛: рдорд╛рд╕реНрдЯрд░.рд╕реАрдПрдлрдЬреА:
рдорд╛рд╕реНрдЯрд░.рд╕реАрдПрдлрдЬреА
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
рддреИрдпрд╛рд░! рдЕрдм рдмрд┐рд▓реНрдбрдмреЛрдЯ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░реЗрдЧрд╛ рдФрд░ рдЯреНрд░рд┐рдЧрд░ рдХрд░реЗрдЧрд╛ рдХрд░рдирд╛-рдп рдореЗрдВ SVN, рдЙрдкрд░реЛрдХреНрдд рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдЪрд░рдгреЛрдВ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдирд╛ред
рдиреАрдЪреЗ рдореИрдВ рдЙрдкрд░реЛрдХреНрдд рдХреА рдХреБрдЫ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ рдорд╛рд╕реНрдЯрд░.рд╕реАрдПрдлрдЬреА.
6.1 рдЖрдкрдХреЗ рдорд╛рд╕реНрдЯрд░.рд╕реАрдПрдлрдЬреА рдХреЗ рд░рд╛рд╕реНрддреЗ рдкрд░
рдореЗрд░реЗ рд▓рд┐рдЦрддреЗ рд╕рдордп рдорд╛рд╕реНрдЯрд░.рд╕реАрдПрдлрдЬреА рдХрдИ рддреНрд░реБрдЯрд┐рдпрд╛рдБ рд╣реЛрдВрдЧреА, рдЗрд╕рд▓рд┐рдП рд▓реЙрдЧ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдкрдврд╝рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдмрд┐рд▓реНрдбрдорд╛рд╕реНрдЯрд░-рдИрд╕реА рдирд┐рд░рдкреЗрдХреНрд╖ рдкрде /home/habr/master/twistd.log, рдФрд░ рдХрд┐рдирд╛рд░реЗ рдкрд░ рдХрд╛рдордЧрд╛рд░-рдП рдкреВрд░реНрдг рдкрде рдХреЗ рд╕рд╛рде /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_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 рдХреЗрд╡рд▓ рд╢рд╛рдЦрд╛ рддрдХ рдкрд╣реБрдБрдЪрддрд╛ рд╣реИ рд╕реВрдБ рдв. рд░рд╣рд╕реНрдпрдордп рдкреИрд░рд╛рдореАрдЯрд░ рд╕реНрдкреНрд▓рд┐рдЯ_рдлрд╝рд╛рдЗрд▓ = util.svn.split_file_alwaystrunk рдирд┐рдпрдо рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ: рдлрд╝реЛрд▓реНрдбрд░ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдХреИрд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░реЗрдВ SVN рд╢рд╛рдЦрд╛рдУрдВ рдкрд░. рд╡рд╣ рдЙрдиреНрд╣реЗрдВ рд╕рд╛рдкреЗрдХреНрд╖ рдкрде рднреА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреА рдмрд╛рд░реА рдореЗрдВ рд╕реНрдкреНрд▓рд┐рдЯ_рдлрд╛рдЗрд▓_рдСрд▓рд╡реЗрд╕реНрдЯреНрд░рдВрдХ рдпрд╣ рдХрд╣рдХрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддрд╛ рд╣реИ рдХрд┐ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдХреЗрд╡рд▓ рд╢рд╛рдорд┐рд▓ рд╣реИ рд╕реВрдБ рдв.
╨Т рд╢реЗрдбреНрдпреВрд▓рд░ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдлрд╝рд┐рд▓реНрдЯрд░ рдмрджрд▓реЗрдВрдХреМрди рджреЗрдЦрддрд╛ рд╣реИ рдХреЛрдИ рдирд╣реАрдВ рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдПрдХ рд╢рд╛рдЦрд╛ рдЬреЛрдбрд╝рддрд╛ рд╣реИ рд╕реВрдБ рдв рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рдПрд╕реЛрд╕рд┐рдПрд╢рди рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╕реНрдкреНрд▓рд┐рдЯ_рдлрд╛рдЗрд▓_рдСрд▓рд╡реЗрд╕реНрдЯреНрд░рдВрдХ. рдореЗрдВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдирд╛ рд╕реВрдБ рдв, рд▓реЙрдиреНрдЪ рдирд┐рд░реНрдорд╛рддрд╛ рдирд╛рдо рдХреЗ рд╕рд╛рде рдЖрдкрдХрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ.
рдЧреБрдг рдпрд╣рд╛рдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдХреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╕реНрд╡рд╛рдореА рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд░реНрдорд╛рдг рдФрд░ рдкрд░реАрдХреНрд╖рдг рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдореЗрд▓рд┐рдВрдЧ рд╕реВрдЪрд┐рдпрд╛рдВ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдВред
рдХрджрдо рдирд┐рд░реНрдорд╛рдг-a рдЬрд╛рдВрдЪ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЗ рд╕реНрдерд╛рдиреАрдп рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╕реНрдерд┐рдд рдХрд┐рд╕реА рднреА рдлрд╝рд╛рдЗрд▓ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣рдЯрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдХрд╛рдордЧрд╛рд░-рдПрдХред рдФрд░ рдлрд┐рд░ рдкреВрд░рд╛ рдХрд░реЛ svn рдЕрджреНрдпрддрди. рдореЛрдб рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдореЛрдб=рдкреВрд░реНрдг, рд╡рд┐рдзрд┐=рддрд╛рдЬрд╛. рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЙрд▓реНрдЯрдСрдирдЯреЗрд▓рд░ рдХрд╣рддрд╛ рд╣реИ рдХрд┐ рдпрджрд┐ 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 рд╕реНрд╡рд╛рдореА рдФрд░ рдмрдирд╛рдиреЗ рд╡рд╛рд▓реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдПрдХ рд╕рдВрджреЗрд╢ рднреЗрдЬрддрд╛ рд╣реИ рдХрд░рдирд╛.
рд▓реБрдХрдЕрдк - рдПрдХ рдкреНрд░рддреНрдпрдп рдЬрд┐рд╕реЗ рд╕рдорд╛рдЪрд╛рд░ рдкрддреНрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдирд╛рдо рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рд▓рд┐рдП рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкрддреЗ рдкрд░ рдиреНрдпреВрдЬрд╝рд▓реЗрдЯрд░ рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧрд╛ [рдИрдореЗрд▓ рд╕рдВрд░рдХреНрд╖рд┐рдд].
рд░рд┐рд▓реЗрд╣реЛрд╕реНрдЯ рдЙрд╕ рд╣реЛрд╕реНрдЯрдирд╛рдо рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕ рдкрд░ рд╕рд░реНрд╡рд░ рдЦреЛрд▓рд╛ рдЧрдпрд╛ рд╣реИ рдПрд╕рдПрдордЯреАрдкреАрддрдХ smptрдкреЛрд░реНрдЯ рдЙрд╕ рдкреЛрд░реНрдЯ рдирдВрдмрд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╕реБрдирддрд╛ рд╣реИ рдПрд╕рдПрдордЯреАрдкреА рд╕рд░реНрд╡рд░.
рдореЛрдб = "рдЪреЗрддрд╛рд╡рдиреА" рдХрд╛ рдХрд╣рдирд╛ рд╣реИ рдХрд┐ рдореЗрд▓ рдХреЗрд╡рд▓ рддрднреА рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрдм рдХрдо рд╕реЗ рдХрдо рдПрдХ рдЪрд░рдг рд╣реЛ рдирд┐рд░реНрдорд╛рдг-рдП, рдЬреЛ рд╕реНрдерд┐рддрд┐ рд╡рд┐рдлрд▓рддрд╛ рдпрд╛ рдЪреЗрддрд╛рд╡рдиреА рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реБрдЖред рд╕рдлрд▓рддрд╛ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рдорд╛рдЪрд╛рд░ рдкрддреНрд░ рднреЗрдЬрдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдЕрддрд┐рд░рд┐рдХреНрддрдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рдЗрд╕рдореЗрдВ рд╕реНрд╡рд╛рдореА рдФрд░ рдЗрд╕реЗ рдЕрдВрдЬрд╛рдо рджреЗрдиреЗ рд╡рд╛рд▓реЗ рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЙрди рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреА рд╕реВрдЪреА рд╣реЛрддреА рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рдореЗрд▓ рднреЗрдЬрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд░рдирд╛.
messageFormatter рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ рдЬреЛ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рд░реВрдк, рдЙрд╕рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдФрд░ рдЙрдкрд▓рдмреНрдз рдЪрд░ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ jinja2. рдЬреИрд╕реЗ рд╡рд┐рдХрд▓реНрдк рд╡рд╛рдВрдЯрдкреНрд░реЙрдкрд░реНрдЯреАрдЬрд╝ = рд╕рддреНрдп ╨╕ рд╡рд╛рдБрд╕реНрдЯрд╕реНрдЯреЗрдкреНрд╕ = рд╕рддреНрдп рдЙрдкрд▓рдмреНрдз рдЪрд░реЛрдВ рдХреЗ рдЗрд╕ рд╕реЗрдЯ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВред
with['services']=[sendMessageToAll] рд╕реЗрд╡рд╛рдУрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рд╣рдорд╛рд░реА рднреА рд╣реЛрдЧреА рд░рд┐рдкреЛрд░реНрдЯрд░.
рд╣рдордиреЗ рдпрд╣ рдХрд┐рдпрд╛! рдмрдзрд╛рдИ рд╣реЛ
рд╣рдордиреЗ рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдмрдирд╛рдпрд╛ рдФрд░ рдЗрд╕рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рджреЗрдЦреАред рдмрд┐рд▓реНрдбрдмреЙрдЯ. рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЖрдкрдХреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдЯреВрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдХреНрдпрд╛ рдЖрдк рдЙрд╕рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ? рдХреНрдпрд╛ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛? рдХреНрдпрд╛ рдЙрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╕рд╣рдЬ рд╣реИ? рддреЛ рдлрд┐рд░ рдореИрдВ рдпрд╣ рд▓реЗрдЦ рд╡реНрдпрд░реНрде рдирд╣реАрдВ рд▓рд┐рдЦ рд░рд╣рд╛ рд╣реВрдБред
рдФрд░ рдЖрдЧреЗред рдореИрдВ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рдкреЗрд╢реЗрд╡рд░ рд╕рдореБрджрд╛рдп рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗ рдмрд┐рд▓реНрдбрдмреЙрдЯ, рд╡реНрдпрд╛рдкрдХ рд╣реЛ рдЧрдпрд╛, рдореИрдиреБрдЕрд▓ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд┐рдпрд╛ рдЧрдпрд╛, рдФрд░ рднреА рдЕрдзрд┐рдХ рдЙрджрд╛рд╣рд░рдг рдереЗред
рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рд╕рднреА рдХрд╛ рдзрдиреНрдпрд╡рд╛рджред рдЖрдкрдХреЛ рдХрд╛рдордпрд╛рдмреА рдорд┐рд▓реЗред
рд╕реНрд░реЛрдд: www.habr.com