рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЕрдиреБрдХреВрд▓рд┐рдд рд╕реАрдЖрдИ / рд╕реАрдбреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╣реИред рдЬрдм рдбреЗрд╡рд▓рдкрд░ рдХрд╛рд░реНрдп рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЕрдкрдиреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ \ qa рдореЗрдВ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдмрд┐рд▓реНрдб рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд▓реЙрдиреНрдЪ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рдкрд░ рдбрд╛рд▓рддрд╛ рд╣реИред рдПрдХ рдЖрджрд░реНрд╢ рджреБрдирд┐рдпрд╛ рдореЗрдВ, рдкрд░реАрдХреНрд╖рдХ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реАрдЦрддрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рдкреВрд░рд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рд╡реЗ рдХрд┐рд╕ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рддреИрдирд╛рдд рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╡рд░реНрдХрдлрд╝реНрд▓реЛ рдирд┐рд░рдВрддрд░, рдирд┐рд░реНрдмрд╛рдз рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдХрдо рд╕рдВрдЪрд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рдХреЗрдВрджреНрд░рд┐рдд рдХрд╛рдо рд╕реЗ рд╡рд┐рдЪрд▓рд┐рдд рд╣реЛрддрд╛ рд╣реИред рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, рд╕рдм рдХреБрдЫ рдЗрддрдирд╛ рд░рд╕реАрд▓рд╛ рдирд╣реАрдВ рд╣реИред
рдФрд░ рдПрдХ рд╕реБрдмрд╣, рдЯреАрдо рд▓реАрдбрд░ рдиреЗ рдореБрдЭрд╕реЗ рдкреВрдЫрд╛: "рдХреНрдпрд╛ рдЖрдк рдЯреАрдПрдлрдПрд╕ рдХреЗ рд▓рд┐рдП рдРрд╕рд╛ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдмрд┐рд▓реНрдб рд╕реЗ рдЬреБрдбрд╝реЗ рдЯреИрдЧ рдЗрд╕ рдмрд┐рд▓реНрдб рд╕реЗ рдЧреБрдЬрд░рдиреЗ рдХреЗ рдмрд╛рдж рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЯреИрдЧ рдХреЛ рд▓рдЯрдХрд╛ рджреЗрдВ?"
рдореИрдВрдиреЗ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдмрд┐рд▓реНрдб \ рд░рд┐рд▓реАрдЬрд╝ рдХрд╛рд░реНрдп рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕рднреА рдирд┐рд░реНрдорд╛рдг рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕реНрд░реЛрдд
рдЬреАрдердм рдкрд░ рд╣реИрдВ, рдФрд░ рд╕рднреА рдЬрд╛рдирдХрд╛рд░реА рдЙрдкрд▓рдмреНрдз рд╣реИред
рд╣рдорд╛рд░рд╛ рдХрд╛рд░реНрдп рдХрд╛рд░реНрдп рдХреЗ рд░рдВрдЧ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдбреЗрд╡рд▓рдкрд░ рддреБрд░рдВрдд рдиреЛрдЯрд┐рд╕ рдХрд░реЗрдЧрд╛ рдпрджрд┐ рд╡рд╣ рд╡рд╛рдВрдЫрд┐рдд рдЯреИрдЧ рдбрд╛рд▓рдирд╛ рднреВрд▓ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдХреНрдпреВрдП рддреБрд░рдВрдд рджреЗрдЦрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЬрд╛рдВрдЪрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдпрд╣ рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд░ рдХрд╛рдо рдХреЛ рдЧрддрд┐ рджреЗрддрд╛ рд╣реИред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЖрд╡рд╢реНрдпрдХ рддрд░реНрдХ, рд╡рд┐рд╕реНрддрд╛рд░ рдореЗрдВ рдкреИрдХреЗрдЬрд┐рдВрдЧ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ред рддреЛ рдЕрдЧрд░ рдЖрдк рдЗрд╕ рддрд░рд╣ рдХреЗ рдкреНрд▓рдЧрдЗрди рдмрдирд╛рдиреЗ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдмрд┐рд▓реНрд▓реА рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред
рд╕рдмрд╕реЗ рдЕрдзреАрд░ рдХреЗ рд▓рд┐рдП:
рдЬреАрдереВрдм рдФрд░
рдмрд╛рдЬрд╛рд░ рдкрд░ рдПрдХ рддреИрдпрд╛рд░ рд╡рд┐рд╕реНрддрд╛рд░ред

Azure DevOps рдореЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рдмрдирд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдмреЛрд░реНрдб рдкрд░ рд╡рд┐рднрд┐рдиреНрди рд░рдВрдЧреЛрдВ рдореЗрдВ рдорд╛рд╕реНрдХ рдХреЛ рд░рдВрдЧрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рд╣рдо рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ:
- рдкреВрд░рд╛
- рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдбрд╛рд▓рд╛
- рдЕрднреА рддрдХ QA рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ
рдЖрдЗрдЯрдо рдХреЗ рд▓рд┐рдП рдмреА рдФрд░ рд╕реА рдЯреИрдЧ рд╕рдмрд╕реЗ рдЙрдкрдпреБрдХреНрдд рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЙрдиреНрд╣реЗрдВ рд╕реЗрдЯ рдХрд░рдирд╛ рдШреГрдгрд┐рдд рд╣реИ, рдФрд░ рд╣рд░ рдХреЛрдИ рдЗрд╕реЗ рдХрд░рдирд╛ рднреВрд▓ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рд╣рдо рдПрдХ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд▓рд┐рдЦреЗрдВрдЧреЗ, рдЬреЛ рддреИрдирд╛рддреА рдХреЗ рдмрд╛рдж рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЙрдиреНрд╣реЗрдВ рдЪрд┐рдкрдХрд╛ рджреЗрдЧрд╛ред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдореЗрдВ рдорд╛рдирд╡ рдХрд╛рд░рдХ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╕реНрдЯрдо рдмрд┐рд▓реНрдб \ рд░рд┐рд▓реАрдЬрд╝ рдЪрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдбреЗрд╡рд▓рдкрд░ рдЯреИрдЧ рдХреЛ рдиреАрдЪреЗ рд░рдЦрдирд╛ рднреВрд▓ рдЧрдпрд╛) рдФрд░ рдХреНрдпреВрдП рдХреА рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП (рдЖрдк рддреБрд░рдВрдд рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдЬрд╛рдБрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ)ред
рдЖрд╡рд╢реНрдпрдХ рд╢рд░реНрддреЗрдВ
рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдП:
- рдкрд╕рдВрджреАрджрд╛ рдЖрдИрдбреАрдИ
- рд╕реНрдерд╛рдкрд┐рдд рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ + рдиреЛрдб.рдЬреЗрдПрд╕ + рдПрдирдкреАрдПрдо (рдЕрдм рдореИрдВрдиреЗ рд╕рдВрд╕реНрдХрд░рдг 3.5.1 \ 12.4 \ 6.9.0 рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рд╣реИ)
- tfx-cli - рдкреИрдХреЗрдЬрд┐рдВрдЧ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рд▓рд┐рдП рдкреБрд╕реНрддрдХрд╛рд▓рдп (npm i -g tfx-cli)ред
-G рдзреНрд╡рдЬ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ
Microsoft рдХреЗ рдкрд╛рд╕ рдХреБрдЫ рдЕрдЪреНрдЫреЗ
рджрд╕реНрддрд╛рд╡реЗрдЬ рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рд╡реЗ рд╕рд┐рд░реНрдл рд╕рдмрд╕реЗ рдКрдкрд░ рд╣реИрдВ рдФрд░ рдмрддрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕ рддрд░рд╣ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдирд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЙрд╕реА рддрд░рд╣ рдмрд┐рд▓реНрдб \ рд░рд┐рд▓реАрдЬрд╝ рдХрд╛рд░реНрдп рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдбреЙрдХ рд╣реИред
рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдХреБрдЫ рдмрд┐рдВрджреБрдУрдВ рдХреЛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрддрд╛рдиреЗ рдпрд╛ рд╕рдордЭрд╛рдиреЗ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рджреЛрдиреЛрдВ рд▓реЗрдЦреЛрдВ рдореЗрдВ рдХрдорд┐рдпрд╛рдВ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЙрди рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдХреЗ рдЙрди рдмрд┐рдВрджреБрдУрдВ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реВрдВрдЧрд╛ рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореБрдЭреЗ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд▓рдЧ рд░рд╣реЗ рдереЗред
рдЖрдо рддреМрд░ рдкрд░, рдЖрдк рдХрд╛рдлреА рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдмрд┐рд▓реНрдб \ рд░рд┐рд▓реАрдЬрд╝ рд╕реНрдЯреЗрдк рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд░ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛ред
рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреНрдпреЛрдВ?
рдмрд┐рд▓реНрдб рд╕реНрдЯреЗрдк'рдП рдХрд╛ рдкрд╣рд▓рд╛ рдкрд╣рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг PowerShell'e рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛, рдХреЗрд╡рд▓ рд╣рдорд╛рд░реА рдЯреАрдо рдФрд░ рдХреБрдЫ рд▓реЛрдЧреЛрдВ рдХреЛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рдерд╛ред рд▓рдЧрднрдЧ рддреБрд░рдВрдд, рд╣рдореЗрдВ рдЗрд╕ рддрдереНрдп рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛ рдХрд┐ рдпрджрд┐ рдЖрдк рдбреЙрдХ рдмрд┐рд▓реНрдб рдПрдЬреЗрдВрдЯ рдкрд░ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдХрд╛рд░реНрдп рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдХреЛрдИ PowerShell рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдФрд░ рдХрд╛рд░реНрдп рдмрд╕ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕рдордп-рд╕рдордп рдкрд░, рд▓реЛрдЧреЛрдВ рд╕реЗ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреА рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реБрдИрдВ, рдЬрд┐рд╕рдХрд╛ рд╢реНрд░реЗрдп PowerShell kooky рдХреЛ рджрд┐рдпрд╛ рдЧрдпрд╛ред рдЗрд╕рд▓рд┐рдП рдирд┐рд╖реНрдХрд░реНрд╖ - рд╕рдорд╛рдзрд╛рди рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рд╕рдВрд░рдЪрдирд╛
|--- README.md |--- images |---extension-icon.png |--- TaskFolder ( build\release step'a) |--- vss-extension.json ( )
рдЕрдЧрд▓рд╛, рд╣рдореЗрдВ рдмрд┐рд▓реНрдб рд╕реНрдЯреЗрдк рдП рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
- рд╕реАрдбреА рдЯрд╛рд╕реНрдХ рдлреЛрд▓реНрдбрд░
- рдПрдирдкреАрдПрдо init
- npm azure- рдкрд╛рдЗрдкрд▓рд╛рдЗрдиреЛрдВ-рдЯрд╛рд╕реНрдХ-рд▓рд┐рдм - save && npm рд╕реНрдерд╛рдкрд┐рдд @ рдкреНрд░рдХрд╛рд░ / рдиреЛрдб - save-dev && npm рд╕реНрдерд╛рдкрд┐рдд @ рдкреНрд░рдХрд╛рд░ / q -save-dev рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ
- tsc - рдЗрдирд┐рдЯ
рд╡рд┐рдХрд╛рд╕ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, TaskFolder рдХреЗ рдЕрдВрджрд░, рд╣рдореЗрдВ task.json рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рдпрд╣ рд╕реНрд╡рдпрдВ рдмрд┐рд▓реНрдб рдЪрд░рдг рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрдЯ рдлрд╝рд╛рдЗрд▓ рд╣реИред рдЗрд╕рдореЗрдВ рд╕реЗрд╡рд╛ рдХреА рдЬрд╛рдирдХрд╛рд░реА (рд╕рдВрд╕реНрдХрд░рдг, рдирд┐рд░реНрдорд╛рддрд╛, рд╡рд┐рд╡рд░рдг) рд╢рд╛рдорд┐рд▓ рд╣реИ, рдЬреЛ рд╕рднреА рдЖрджрд╛рдиреЛрдВ рдХреЗ рд▓реЙрдиреНрдЪ рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд╛рддрд╛рд╡рд░рдг рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдо рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдлреЙрд░реНрдо рдкрд░ рджреЗрдЦреЗрдВрдЧреЗред
рдореИрдВ
рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рдЗрд╕рдХреА рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЕрдзреНрдпрдпрди рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВред
рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдлреЙрд░реНрдо рдкрд░ 2 рдЗрдирдкреБрдЯ'рдП рд╣реЛрдЧрд╛ - рд╡рд╣ рдЯреИрдЧ рдЬреЛ рд╣рдо рдХрд╛рдо рдХреА рд╡рд╕реНрддреБрдУрдВ рдореЗрдВ рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗ, рдФрд░ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдкреНрд░рдХрд╛рд░ (рдирд┐рд░реНрдорд╛рдг рдпрд╛ рд░рд┐рд▓реАрдЬрд╝) рдХрд╛ рд╡рд┐рдХрд▓реНрдкред
"inputs": [ { "name": "pipelineType", "type": "pickList", "label": "Specify type of pipeline", "helpMarkDown": "Specify whether task is used for build or release", "required": true, "defaultValue": "Build", "options":{ "Build": "Build", "Release": "Release" } }, { "name": "tagToAdd", "type": "string", "label": "Tag to add to work items", "defaultValue": "", "required": true, "helpMarkDown": "Specify a tag that will be added to work items" } ]
рдирд╛рдо рд╕реЗ, рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдХреЛрдб рдореЗрдВ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдЗрдирдкреБрдЯ рдХреЗ рдореВрд▓реНрдп рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░реЗрдВрдЧреЗред
TaskFolder рдореЗрдВ рдПрдХ index.ts рдмрдирд╛рдПрдБ рдФрд░ рдХреЛрдб рдХрд╛ рдкрд╣рд▓рд╛ рдЯреБрдХрдбрд╝рд╛ рд▓рд┐рдЦреЗрдВ
import * as tl from 'azure-pipelines-task-lib/task'; async function run() { try { const pipelineType = tl.getInput('pipelineType'); } catch (err) { tl.setResult(tl.TaskResult.Failed, err.message); } } run();
рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдЯреАрдПрдлрдПрд╕ рдХреЗ рдкрд╛рд╕ рдореМрдЬреВрджрд╛ рдЖрд░рдПрдПрд╕рдЯреА рдПрдкреАрдЖрдИ рдкрд░ рдПрдХ рдмрд╣реБрдд рд╕рдореГрджреНрдз рджрд╕реНрддрд╛рд╡реЗрдЬ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд▓рд╣рд╛рд▓ рд╣рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдорд╛рдг рд╕реЗ рдЬреБрдбрд╝реА рдЪреАрдЬреЗрдВ рдорд┐рд▓рдиреА рдЪрд╛рд╣рд┐рдПред
рдЖрд╕рд╛рди рдХреНрд╡реЗрд░реА рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ
npm install request --save && npm install request-promise-native --save
рдЗрд╕реЗ index.ts рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ
import * as request from "request-promise-native";
рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рд╡рд░реНрддрдорд╛рди рдмрд┐рд▓реНрдб рд╕реЗ рд╕рдВрд▓рдЧреНрди рдХрд╛рд░реНрдп рдЖрдЗрдЯрдо рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ
рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рд╛
REST API рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХреНрд╕реЗрд╕рдЯреЛрдХрди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
const accessToken = tl.getEndpointAuthorization('SystemVssConnection', true).parameters.AccessToken;
рдЕрдЧрд▓рд╛, рд╣реЗрдбрд░ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЛ "рдмрд┐рдпрд░рд░ $ {accessToken}" рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВ
рд╣рдо рдирд┐рд░реНрдорд╛рдг рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХрд╛рд░реНрдп рдЖрдЗрдЯрдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред
Url Azure DevOps рд╕рд░реНрд╡рд░ рдФрд░ TeamProject рдирд╛рдо рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рд╕реЗ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
const collectionUrl = process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"]; const teamProject = process.env["SYSTEM_TEAMPROJECT"];
async function getWorkItemsFromBuild() { const buildId = process.env["BUILD_BUILDID"]; const uri = `${collectionUrl}/${teamProject}/_apis/build/builds/${buildId}/workitems`; const options = createGetRequestOptions(uri); const result = await request.get(options); return result.value; }
function createGetRequestOptions(uri: string): any { let options = { uri: uri, headers: { "authorization": `Bearer ${accessToken}`, "content-type": "application/json" }, json: true }; return options; }
URL рджреНрд╡рд╛рд░рд╛ GET рдЕрдиреБрд░реЛрдз рдХреЗ рдЬрд╡рд╛рдм рдХреЗ рд░реВрдк рдореЗрдВ
${collectionUrl}/${teamProject}/_apis/build/builds/${buildId}/workitems
рд╣рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХрд╛ JSON рдорд┐рд▓рддрд╛ рд╣реИ
{ "count": 3, "value": [ { "id": "55402", "url": "https://.../_apis/wit/workItems/55402" }, { "id": "59777", "url": "https://.../_apis/wit/workItems/59777" }, { "id": "60199", "url": "https://.../_apis/wit/workItems/60199" } ] }
рдкреНрд░рддреНрдпреЗрдХ url рдХреЗ рд▓рд┐рдП, рдЙрд╕реА REST API рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдЖрдк рдХрд╛рд░реНрдп рдЖрдЗрдЯрдо рдкрд░ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдлрд┐рд▓рд╣рд╛рд▓, рд╣рдорд╛рд░реА рд░рди рдкрджреНрдзрддрд┐ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИред
рд░рд┐рд▓реАрдЬрд╝ рд╕реЗ рдХрд╛рд░реНрдп рдЖрдЗрдЯрдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рд╡рд┐рдзрд┐ рд▓рдЧрднрдЧ рдкрд╣рд▓реЗ рд╕реЗ рд╡рд░реНрдгрд┐рдд рдХреЗ рд╕рдорд╛рди рд╣реИред
async function run() { try { const pipelineType = tl.getInput('pipelineType'); const workItemsData = pipelineType === "Build" ? await getWorkItemsFromBuild() : await getWorkItemsFromRelease(); catch (err) { tl.setResult(tl.TaskResult.Failed, err.message); }
рдЕрдЧрд▓рд╛ рдХрджрдо рдкреНрд░рд╛рдкреНрдд рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП рдЯреИрдЧ рдХрд╛ рд╡рд░реНрддрдорд╛рди рд╕реЗрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдФрд░ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдПрдХ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╣реИред
рдЪрд▓реЛ рд░рди рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ:
async function run() { try { const pipelineType = tl.getInput('pipelineType'); const workItemsData = pipelineType === "Build" ? await getWorkItemsFromBuild() : await getWorkItemsFromRelease(); workItemsData.forEach(async (workItem: any) => { await addTagToWorkItem(workItem); }); } catch (err) { tl.setResult(tl.TaskResult.Failed, err.message); } }
рдЖрдЗрдП рдХрд╛рд░реНрдп рдЖрдЗрдЯрдо рдореЗрдВ рдПрдХ рдЯреИрдЧ рдЬреЛрдбрд╝рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдЙрд╕ рдЯреИрдЧ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдордиреЗ рдлреЙрд░реНрдо рдкрд░ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдерд╛ред
const tagFromInput = tl.getInput('tagToAdd');
рдХреНрдпреЛрдВрдХрд┐ 2 рдХрджрдо рдкреАрдЫреЗ рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдп рдЖрдЗрдЯрдо рдХреЗ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдпреВрдЖрд░рдПрд▓ рдорд┐рд▓рд╛, рдлрд┐рд░ рдЙрдирдХреА рдорджрдж рд╕реЗ рд╣рдо рдЖрд╕рд╛рдиреА рд╕реЗ рд╡рд░реНрддрдорд╛рди рдЯреИрдЧ рдХреА рд╕реВрдЪреА рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
const uri = workItem.url + "?fields=System.Tags&api-version=2.0"; const getOptions = createGetRequestOptions(uri) const result = await request.get(getOptions);
рдЬрд╡рд╛рдм рдореЗрдВ, рд╣рдореЗрдВ рдпрд╣ JSON рдорд┐рд▓рддрд╛ рд╣реИ:
{ "id": 55402, "rev": 85, "fields": { "System.Tags": "added-to-prod-package; test-tag" }, "_links": { "self": { "href": "https://.../_apis/wit/workItems/55402" }, "workItemUpdates": { "href": "https://.../_apis/wit/workItems/55402/updates" }, "workItemRevisions": { "href": "https://.../_apis/wit/workItems/55402/revisions" }, "workItemHistory": { "href": "https://.../_apis/wit/workItems/55402/history" }, "html": { "href": "https://..../web/wi.aspx?pcguid=e3c978d9-6ea1-406f-987d-5b03e24973a1&id=55402" }, "workItemType": { "href": "https://.../602fd27d-4e0d-4aec-82a0-dcf55c8eef73/_apis/wit/workItemTypes" }, "fields": { "href": "https://.../_apis/wit/fields" } }, "url": "https://.../_apis/wit/workItems/55402" }
рд╣рдо рд╕рднреА рдкреБрд░рд╛рдиреЗ рдЯреИрдЧ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдЙрдирдореЗрдВ рдПрдХ рдирдпрд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:
const currentTags = result.fields['System.Tags']; let newTags = ''; if (currentTags !== undefined) { newTags = currentTags + ";" + tagFromInput; } else { newTags = tagFromInput; }
рд╣рдо рдЖрдЗрдЯрдо рдПрдкреА рдХреЛ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрдЪ рдЕрдиреБрд░реЛрдз рднреЗрдЬрддреЗ рд╣реИрдВ:
const patchOptions = getPatchRequestOptions(uri, newTags); await request.patch(patchOptions) function getPatchRequestOptions(uri: string, newTags: string): any { const options = { uri: uri, headers: { "authorization": `Bearer ${accessToken}`, "content-type": "application/json-patch+json" }, body: [{ "op": "add", "path": "/fields/System.Tags", "value": newTags }], json: true }; return options }
рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдФрд░ рдкреИрдХреЗрдЬрд┐рдВрдЧ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░
рдЬреЛ рдХреБрдЫ рднреА рд╣реЛрддрд╛ рд╣реИ, рдЙрд╕рдХреА рд╕реБрдВрджрд░рддрд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВ tsconfig.json рдореЗрдВ рдХрдВрдкрд╛рдЗрд▓рд░ рдСрдЙрдВрд╕ рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВ
"outDir": "dist"
ред рдЕрдм, рдЕрдЧрд░ рд╣рдо рдЯрд╛рд╕реНрдХ рдлреЛрд▓реНрдбрд░ рдХреЗ рдЕрдВрджрд░ tsc рдХрдорд╛рдВрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдбрд┐рд╕реНрдЯрд░реНрдм рдлреЛрд▓реНрдбрд░ рдорд┐рд▓рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдЕрдВрджрд░ index.js рд╣реЛрдЧрд╛, рдЬреЛ рдЕрдВрддрд┐рдо рдкреИрдХреЗрдЬ рдкрд░ рдЬрд╛рдПрдЧрд╛ред
рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░рд╛ index.js рдбрд┐рд╕реНрдЯ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ рдФрд░ рдлрд┐рд░ рд╣рдо рдЗрд╕реЗ рдЕрдВрддрд┐рдо рдкреИрдХреЗрдЬ рдкрд░ рднреА рдХреЙрдкреА рдХрд░реЗрдВрдЧреЗ, рд╣рдореЗрдВ task.json рдХреЛ рдереЛрдбрд╝рд╛ рдареАрдХ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:
"execution": { "Node": { "target": "dist/index.js" } }
рдлрд╝рд╛рдЗрд▓ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ vss-extension.json рдореЗрдВ, рдЖрдкрдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдЕрдВрддрд┐рдо рдкреИрдХреЗрдЬ рдореЗрдВ рдХреНрдпрд╛ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
"files": [ { "path": "TaskFolder/dist", "packagePath": "TaskFolder/dist" }, { "path": "TaskFolder/node_modules", "packagePath": "TaskFolder/node_modules" }, { "path": "TaskFolder/icon.png", "packagePath": "TaskFolder/icon.png" }, { "path": "TaskFolder/task.json", "packagePath": "TaskFolder/task.json" } ]
рдЕрдВрддрд┐рдо рдЪрд░рдг - рд╣рдореЗрдВ рдЕрдкрдирд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдкреИрдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдорд╛рдВрдб рдЪрд▓рд╛рдПрдБ:
tfx extension create --manifest-globs ./vss-extension.json
рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдПрдХ * .vsix рдлрд╝рд╛рдЗрд▓ рдорд┐рд▓рддреА рд╣реИ, рдЬрд┐рд╕реЗ рдЖрдЧреЗ TFS рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
PS * .vsix рдлрд╝рд╛рдЗрд▓ рдореВрд▓ рд░реВрдк рд╕реЗ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╕рдВрдЧреНрд░рд╣ рд╣реИ, рдЖрдк рдЗрд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ 7-рдЬрд╝рд┐рдк рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЦреЛрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдЖрдкрдХреЛ рдЬреЛ рдХреБрдЫ рднреА рдЪрд╛рд╣рд┐рдП рд╡рд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдВрджрд░ рд╣реИред
рдХреБрдЫ рд╕реБрдВрджрд░рддрд╛ рдЬреЛрдбрд╝реЗрдВ
рдпрджрд┐ рдЖрдк рдкрд╛рдЗрдк рд▓рд╛рдЗрди рдореЗрдВ рдЬреЛрдбрд╝рддреЗ рд╕рдордп рдЕрдкрдиреЗ рдмрд┐рд▓реНрдб рд╕реНрдЯреЗрдк рдХрд╛ рдЪрдпрди рдХрд░рддреЗ рд╕рдордп рдПрдХ рдЫрд╡рд┐ рд░рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЯрд╛рд╕реНрдХ рдХреЗ рдмрдЧрд▓ рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред json рдФрд░ рдирд╛рдорд┐рдд icon.pngред рдЖрдкрдХреЛ рдЯрд╛рд╕реНрдХ рдореЗрдВ рдХреЛрдИ рдмрджрд▓рд╛рд╡ рдХрд░рдиреЗ рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИред
рдЖрдк vss-extension.json рдореЗрдВ рдПрдХ рдЕрдиреБрднрд╛рдЧ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:
"icons": { "default": "images/logo.png" }
рдпрд╣ рдЪрд┐рддреНрд░ рд╕реНрдерд╛рдиреАрдп рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреА рдЧреИрд▓рд░реА рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ
- Tfs_server_url / _gallery / manage рдкрд░ рдЬрд╛рдПрдВ
- рдЕрдкрд▓реЛрдб рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ
- рдкрд╣рд▓реЗ рдкреНрд░рд╛рдкреНрдд * .vsix рдлрд╝рд╛рдЗрд▓ рдХреЛ рдлреЗрдВрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдкрде рдпрд╛ drag'n'drop рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ
- рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдиреВ рдореЗрдВ рд╕рддреНрдпрд╛рдкрди рдкрд╛рд╕ рдХреЗ рдмрд╛рдж, рдЦреБрд▓рдиреЗ рд╡рд╛рд▓реЗ рдкреГрд╖реНрда рдкрд░ рджреГрд╢реНрдп рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ, рдЙрд╕ рд╕рдВрдЧреНрд░рд╣ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдЗрд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ
- рдЗрд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рдмрд╛рдж, рдЖрдк рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдирд┐рд░реНрдорд╛рдг step'a рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛
- рдЕрдкрдиреА рдЬрд░реВрд░рдд рдХреА рдкрд╛рдЗрдк рд▓рд╛рдЗрди рдЦреЛрд▓реЗрдВ
- Add stepaa рдХреЛ рдРрдб рдХрд░реЗрдВ
- рд╣рдо рд╡рд┐рд╕реНрддрд╛рд░ рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ

- рд╣рдо рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ

- рдЬреАрд╡рди рдХрд╛ рдЖрдирдВрдж рд▓реЗрдВ :)
рдирд┐рд╖реНрдХрд░реНрд╖
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВрдиреЗ рджрд┐рдЦрд╛рдпрд╛ рдХрд┐ рдХреИрд╕реЗ Azure DevOps рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд▓рдЧ-рдЗрди рдмрдирд╛рдпрд╛ рдЬрд╛рдП, рдЬреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд░рд┐рд▓реАрдЬрд╝ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдЯреИрдЧ рдбрд╛рд▓рддрд╛ рд╣реИред рд╕рд╣рдХрд░реНрдорд┐рдпреЛрдВ рдиреЗ рдЗрд╕реЗ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ рдмрдирд╛рдпрд╛, рдЬреЛ рдЦрд┐рдбрд╝рдХрд┐рдпреЛрдВ рдФрд░ рд▓рд┐рдирдХреНрд╕ рдмрд┐рд▓реНрдб рдПрдЬреЗрдВрдЯреЛрдВ рджреЛрдиреЛрдВ рдкрд░ рдЪрд▓рддрд╛ рд╣реИред
рдЗрд╕ рдкреНрд▓рдЧрдЗрди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд░ рдирд┐рд░рдВрддрд░ рдХрд╛рдо рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛ рдЧрдпрд╛ рд╣реИред рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЕрдм рдмрд╛рд╣рд░реА рдЪреАрдЬреЛрдВ рд╕реЗ рд╡рд┐рдЪрд▓рд┐рдд рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВ, рдФрд░ рдХреНрдпреВрдП рдЬрд▓реНрджреА рд╕реЗ рдирдП рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реАрдЦрддрд╛ рд╣реИред
рдПрдХ рдмрд╛рд░ рдлрд┐рд░, рдореБрдЭреЗ рдбрд╛рдЙрдирд▓реЛрдб
рд▓рд┐рдВрдХ :
рд▓рд┐рдВрдХ рдпрд╛рдж рд╣реИ
рд╣рдо рд╕рдВрд╢реЛрдзрди рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдФрд░ рд╕реБрдЭрд╛рд╡реЛрдВ рдХреЗ рд▓рд┐рдП рддрддреНрдкрд░ рд╣реИрдВ :)
рдкреБрдирд╢реНрдЪ
рдкреНрд▓рдЧрдЗрди рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЯреИрдЧ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдПрдХ рд╡рд┐рдЪрд╛рд░ рднреА рд╣реИред рдпрджрд┐ рдкрд░реАрдХреНрд╖рдХ рдХреЛ рдмрдЧ рдорд┐рд▓рд╛ рдФрд░ рдЖрдкрдХреЛ рдХрд╛рд░реНрдп рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реИ, рддреЛ рдЖрдк "рд╕рддреНрдпрд╛рдкрд┐рдд" рдЯреИрдЧ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред