ΠΡΠ΅ Π½Π°ΡΠ°Π»ΠΎΡΡ Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎ ΡΠΈΠΌΠ»ΠΈΠ΄ ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· Π½Π°ΡΠΈΡ ΠΊΠΎΠΌΠ°Π½Π΄ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² ΠΏΠΎΠΏΡΠΎΡΠΈΠ» Π² ΡΠ΅ΡΡΠΎΠ²ΠΎΠΌ ΡΠ΅ΠΆΠΈΠΌΠ΅ Π²ΡΡΡΠ°Π²ΠΈΡΡ Π½Π°ΡΡΠΆΡ ΠΈΡ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π½Π°ΠΊΠ°Π½ΡΠ½Π΅ Π±ΡΠ»ΠΎ ΠΏΠΎΠ΄Π²Π΅ΡΠ³Π½ΡΡΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΈΠ·Π°ΡΠΈΠΈ. Π― Π²ΡΡΡΠ°Π²ΠΈΠ». ΠΡΠΈΠΌΠ΅ΡΠ½ΠΎ ΡΠ΅ΡΠ΅Π· 20 ΠΌΠΈΠ½ΡΡ ΠΏΠΎΡΡΡΠΏΠΈΠ»Π° ΠΏΡΠΎΡΡΠ±Π° ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΡΠ°ΠΌ Π΄ΠΎΠΏΠΈΠ»ΠΈΠ»ΠΈ ΠΎΡΠ΅Π½Ρ Π½ΡΠΆΠ½ΡΡ ΡΡΡΠΊΡ. Π― ΠΎΠ±Π½ΠΎΠ²ΠΈΠ». ΠΡΠ΅ ΡΠ΅ΡΠ΅Π· ΠΏΠ°ΡΡ ΡΠ°ΡΠΎΠ²β¦ Π½Ρ, Π²Ρ ΠΈ ΡΠ°ΠΊ Π΄ΠΎΠ³Π°Π΄ΡΠ²Π°Π΅ΡΠ΅ΡΡ, ΡΡΠΎ ΡΡΠ°Π»ΠΎ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡΡ Π΄Π°Π»ΡΡΠ΅β¦
Π―, ΠΏΡΠΈΠ·Π½Π°ΡΡΡΡ, Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ Π»Π΅Π½ΠΈΠ² (Ρ ΠΆΠ΅ ΡΠ°Π½Π΅Π΅ Π² ΡΡΠΎΠΌ ΠΏΡΠΈΠ·Π½Π°Π²Π°Π»ΡΡ? Π½Π΅Ρ?), ΠΈ, ΡΡΠΈΡΡΠ²Π°Ρ ΡΠΎΡ ΡΠ°ΠΊΡ, ΡΡΠΎ ΡΠΈΠΌΠ»ΠΈΠ΄Ρ ΠΈΠΌΠ΅ΡΡ Π΄ΠΎΡΡΡΠΏ Π² Jenkins, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Ρ Π½Π°Ρ Π²Π΅ΡΡ CI/CD, ΠΏΠΎΠ΄ΡΠΌΠ°Π»: Π΄Π° ΠΏΡΡΡΡ ΠΎΠ½ ΡΠ°ΠΌ Π΄Π΅ΠΏΠ»ΠΎΠΈΡ, ΡΠΊΠΎΠ»ΡΠΊΠΎ Π·Π°Π±Π»Π°Π³ΠΎΡΠ°ΡΡΡΠ΄ΠΈΡΡΡ! ΠΡΠΏΠΎΠΌΠ½ΠΈΠ» Π°Π½Π΅ΠΊΠ΄ΠΎΡ: Π΄Π°ΠΉ ΡΠ΅Π»ΠΎΠ²Π΅ΠΊΡ ΡΡΠ±Ρ ΠΈ ΠΎΠ½ Π±ΡΠ΄Π΅Ρ ΡΡΡ Π΄Π΅Π½Ρ; Π½Π°Π·ΠΎΠ²ΠΈ ΡΠ΅Π»ΠΎΠ²Π΅ΠΊΠ° Π‘ΡΡ ΠΈ ΠΎΠ½ Π±ΡΠ΄Π΅Ρ Π‘ΡΡ Π²ΡΡ ΠΆΠΈΠ·Π½Ρ. Π ΠΏΠΎΡΠ΅Π» ΠΌΠ°ΡΡΡΡΡΠΈΡΡ Π΄ΠΆΠΎΠ±Ρ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±Ρ ΡΠΌΠ΅Π»Π° Π΄Π΅ΠΏΠ»ΠΎΠΈΡΡ Π² ΠΊΡΠ±Π΅Ρ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π»ΡΠ±ΠΎΠΉ ΡΡΠΏΠ΅ΡΠ½ΠΎ ΡΠΎΠ±ΡΠ°Π½Π½ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π² Π½Π΅Π³ΠΎ Π»ΡΠ±ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ENV (ΠΌΠΎΠΉ Π΄Π΅Π΄ΡΡΠΊΠ°, β ΡΠΈΠ»ΠΎΠ»ΠΎΠ³, ΠΏΡΠ΅ΠΏΠΎΠ΄Π°Π²Π°ΡΠ΅Π»Ρ Π°Π½Π³Π»ΠΈΠΉΡΠΊΠΎΠ³ΠΎ Π² ΠΏΡΠΎΡΠ»ΠΎΠΌ, β ΡΠ΅ΠΉΡΠ°Ρ Π±Ρ ΠΏΠΎΠΊΡΡΡΠΈΠ» ΠΏΠ°Π»ΡΡΠ΅ΠΌ Ρ Π²ΠΈΡΠΊΠ° ΠΈ ΠΎΡΠ΅Π½Ρ Π²ΡΡΠ°Π·ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡΡΠ΅Π» Π±Ρ Π½Π° ΠΌΠ΅Π½Ρ, ΠΏΡΠΎΡΠΈΡΠ°Π² ΡΡΠΎ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅).
ΠΡΠ°ΠΊ, Π² Π·Π°ΠΌΠ΅ΡΠΊΠ΅ Ρ ΡΠ°ΡΡΠΊΠ°ΠΆΡ ΠΎ ΡΠΎΠΌ, ΠΊΠ°ΠΊ Ρ Π½Π°ΡΡΠΈΠ»ΡΡ:
- ΠΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡΡ Π·Π°Π΄Π°Π½ΠΈΡ Π² Jenkins’Π΅ ΠΈΠ· ΡΠ°ΠΌΠΎΠ³ΠΎ Π·Π°Π΄Π°Π½ΠΈΡ ΠΈΠ»ΠΈ ΠΈΠ· Π΄ΡΡΠ³ΠΈΡ Π·Π°Π΄Π°Π½ΠΈΠΉ;
- ΠΠΎΠ΄ΠΊΠ»ΡΡΠ°ΡΡΡΡ ΠΊ ΠΎΠ±Π»Π°ΡΠ½ΠΎΠΉ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ (Cloud shell) Ρ Π½ΠΎΠ΄Ρ Ρ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π½ΡΠΌ Π°Π³Π΅Π½ΡΠΎΠΌ Jenkins’Π°;
- ΠΠ΅ΠΏΠ»ΠΎΠΈΡΡ ΡΠ°Π±ΠΎΡΡΡ Π½Π°Π³ΡΡΠ·ΠΊΡ (workload) Π² Google Kubernetes Engine.
ΠΠ° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅, Ρ, ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ, Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π»ΡΠΊΠ°Π²Π»Ρ. ΠΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ, ΡΡΠΎ Ρ
ΠΎΡΡ Π±Ρ ΡΠ°ΡΡΡ ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΡ Ρ Π²Π°Ρ Π² Π³ΡΠ³Π»ΠΎΠ²ΠΎΠΌ ΠΎΠ±Π»Π°ΠΊΠ΅, Π°, ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ, Π²Ρ Π΅Π³ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΠΈ, ΡΠ°Π·ΡΠΌΠ΅Π΅ΡΡΡ, Ρ Π²Π°Ρ Π΅ΡΡΡ ΡΡΠ΅ΡΠ½Π°Ρ Π·Π°ΠΏΠΈΡΡ GCP. ΠΠΎ Π·Π°ΠΌΠ΅ΡΠΊΠ° Π½Π΅ ΠΎΠ± ΡΡΠΎΠΌ.
ΠΡΠΎ ΠΎΡΠ΅ΡΠ΅Π΄Π½Π°Ρ ΠΌΠΎΡ ΡΠΏΠ°ΡΠ³Π°Π»ΠΊΠ°. Π’Π°ΠΊΠΈΠ΅ Π·Π°ΠΌΠ΅ΡΠΊΠΈ ΠΌΠ½Π΅ Ρ ΠΎΡΠ΅ΡΡΡ ΠΏΠΈΡΠ°ΡΡ Π»ΠΈΡΡ Π² ΠΎΠ΄Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅: ΠΏΠ΅ΡΠ΅Π΄ΠΎ ΠΌΠ½ΠΎΠΉ ΡΡΠΎΡΠ»Π° Π·Π°Π΄Π°ΡΠ°, Ρ ΠΈΠ·Π½Π°ΡΠ°Π»ΡΠ½ΠΎ Π½Π΅ Π·Π½Π°Π», ΠΊΠ°ΠΊ Π΅Π΅ ΡΠ΅ΡΠΈΡΡ, ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π½Π΅ Π½Π°Π³ΡΠ³Π»ΠΈΠ»ΠΎΡΡ Π² Π³ΠΎΡΠΎΠ²ΠΎΠΌ Π²ΠΈΠ΄Π΅, ΠΏΠΎΡΡΠΎΠΌΡ Ρ Π΅Π³ΠΎ Π³ΡΠ³Π»ΠΈΠ» ΠΏΠΎ ΡΠ°ΡΡΡΠΌ ΠΈ Π² ΠΈΡΠΎΠ³Π΅ Π·Π°Π΄Π°ΡΡ ΡΠ΅ΡΠΈΠ». Π Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ Π² Π±ΡΠ΄ΡΡΠ΅ΠΌ, ΠΊΠΎΠ³Π΄Π° Ρ Π·Π°Π±ΡΠ΄Ρ, ΠΊΠ°ΠΊ Ρ ΡΡΠΎ ΡΠ΄Π΅Π»Π°Π», ΠΌΠ½Π΅ Π½Π΅ ΠΏΡΠΈΡΠ»ΠΎΡΡ Π²Π½ΠΎΠ²Ρ Π²ΡΠ΅ Π³ΡΠ³Π»ΠΈΡΡ ΠΏΠΎ ΠΊΡΡΠΊΠ°ΠΌ ΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡ Π²ΠΎΠ΅Π΄ΠΈΠ½ΠΎ, Ρ ΠΏΠΈΡΡ ΡΠ΅Π±Π΅ ΡΠ°ΠΊΠΈΠ΅ ΡΠΏΠ°ΡΠ³Π°Π»ΠΊΠΈ.
Disclaimer: 1. ΠΠ°ΠΌΠ΅ΡΠΊΠ° ΠΏΠΈΡΠ°Π»Π°ΡΡ Β«Π΄Π»Ρ ΡΠ΅Π±ΡΒ», Π½Π° ΡΠΎΠ»Ρ best practice Π½Π΅ ΠΏΡΠ΅ΡΠ΅Π½Π΄ΡΠ΅Ρ. Π‘ ΡΠ΄ΠΎΠ²ΠΎΠ»ΡΡΡΠ²ΠΈΠ΅ΠΌ ΠΏΠΎΡΠΈΡΠ°Ρ Π²Π°ΡΠΈΠ°Π½ΡΡ Β«Π° Π»ΡΡΡΠ΅ Π±ΡΠ»ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠ°ΠΊΒ» Π² ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΡΡ .
2. ΠΡΠ»ΠΈ ΠΏΡΠΈΠΊΠ»Π°Π΄Π½ΡΡ ΡΠ°ΡΡΡ Π·Π°ΠΌΠ΅ΡΠΊΠΈ ΡΡΠΈΡΠ°ΡΡ ΡΠΎΠ»ΡΡ, ΡΠΎ, ΠΊΠ°ΠΊ ΠΈ Π²ΡΠ΅ ΠΌΠΎΠΈ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΠ΅ Π·Π°ΠΌΠ΅ΡΠΊΠΈ, ΡΡΠ° β ΡΠ»Π°Π±ΠΎΡΠΎΠ»Π΅Π²ΠΎΠΉ ΡΠ°ΡΡΠ²ΠΎΡ.
ΠΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π½Π°ΡΡΡΠΎΠ΅ΠΊ Π·Π°Π΄Π°Π½ΠΈΠΉ Π² Jenkins
ΠΡΠ΅Π΄Π²ΠΈΠΆΡ Π²Π°Ρ Π²ΠΎΠΏΡΠΎΡ: Π° ΠΏΡΠΈ ΡΠ΅ΠΌ ΡΡΡ Π²ΠΎΠΎΠ±ΡΠ΅ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π΄ΠΆΠΎΠ±Ρ? ΠΠΏΠΈΡΠ°Π» ΡΡΡΠΊΠ°ΠΌΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΡΠΎΠΊΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° ΠΈ Π²ΠΏΠ΅ΡΠ΅Π΄!
ΠΡΠ²Π΅ΡΠ°Ρ: Ρ ΠΏΡΠ°Π²Π΄Π° Π»Π΅Π½ΠΈΠ²ΡΠΉ, Π½Π΅ Π»ΡΠ±Π»Ρ, ΠΊΠΎΠ³Π΄Π° ΠΆΠ°Π»ΡΡΡΡΡ: ΠΠΈΡΠ°, Π΄Π΅ΠΏΠ»ΠΎΠΉ ΠΊΡΠ°ΡΠΈΡΡΡ, Π²ΡΠ΅ ΠΏΡΠΎΠΏΠ°Π»ΠΎ! ΠΠ°ΡΠΈΠ½Π°Π΅ΡΡ ΡΠΌΠΎΡΡΠ΅ΡΡ, Π° ΡΠ°ΠΌ ΠΎΠΏΠ΅ΡΠ°ΡΠΊΠ° Π² Π·Π½Π°ΡΠ΅Π½ΠΈΠΈ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π½ΠΈΠ±ΡΠ΄Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° Π·Π°ΠΏΡΡΠΊΠ° Π·Π°Π΄Π°Π½ΠΈΡ. ΠΠΎΡΡΠΎΠΌΡ ΠΏΡΠ΅Π΄ΠΏΠΎΡΠΈΡΠ°Ρ Π²ΡΠ΅ Π΄Π΅Π»Π°ΡΡ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎ ΡΡΠ»ΠΏΡΡΡΠ½ΠΎ. ΠΡΠ»ΠΈ Π΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π»ΠΈΡΠΈΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ Π²Π²ΠΎΠ΄ΠΈΡΡ Π΄Π°Π½Π½ΡΠ΅ Π½Π°ΠΏΡΡΠΌΡΡ, Π΄Π°Π² Π²ΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΡΠΏΠΈΡΠΎΠΊ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Π΄Π»Ρ Π²ΡΠ±ΠΎΡΠ°, ΡΠΎ Ρ ΠΎΡΠ³Π°Π½ΠΈΠ·ΠΎΠ²ΡΠ²Π°Ρ Π²ΡΠ±ΠΎΡ.
ΠΠ»Π°Π½ ΡΠ°ΠΊΠΎΠ²: ΡΠΎΠ·Π΄Π°Π΅ΠΌ Π·Π°Π΄Π°Π½ΠΈΠ΅ Π² Jenkins, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΏΠ΅ΡΠ΅Π΄ Π·Π°ΠΏΡΡΠΊΠΎΠΌ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ Π±Ρ ΠΈΠ· ΡΠΏΠΈΡΠΊΠ° Π²ΡΠ±ΡΠ°ΡΡ Π²Π΅ΡΡΠΈΡ, ΡΠΊΠ°Π·Π°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π΄Π»Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ², ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Π΅ΠΌΡΡ Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ ΡΠ΅ΡΠ΅Π· ENV, Π΄Π°Π»Π΅Π΅ ΠΎΠ½ΠΎ ΡΠΎΠ±ΠΈΡΠ°Π΅Ρ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ ΠΈ ΠΏΡΡΠ°Π΅Ρ Π΅Π³ΠΎ Π² Container Registry. ΠΠ°Π»Π΅Π΅ ΠΎΡΡΡΠ΄Π° ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ Π² ΠΊΡΠ±Π΅ΡΠ΅ ΠΊΠ°ΠΊ workload Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ, Π·Π°Π΄Π°Π½Π½ΡΠΌΠΈ Π² Π΄ΠΆΠΎΠ±Π΅.
ΠΡΠΎΡΠ΅ΡΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΈ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Π·Π°Π΄Π°Π½ΠΈΡ Π² Jenkins’Π΅ ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°ΡΡ Π½Π΅ Π±ΡΠ΄Π΅ΠΌ, ΡΡΠΎ ΠΎΡΡΡΠΎΠΏΠΈΠΊ. ΠΡΠ΄Π΅ΠΌ ΠΈΡΡ ΠΎΠ΄ΠΈΡΡ ΠΈΠ· ΡΠΎΠ³ΠΎ, ΡΡΠΎ Π·Π°Π΄Π°Π½ΠΈΠ΅ Π³ΠΎΡΠΎΠ²ΠΎ. ΠΠ»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠΏΠΈΡΠΊΠ° Ρ Π²Π΅ΡΡΠΈΡΠΌΠΈ, Π½Π°ΠΌ Π½ΡΠΆΠ½Ρ Π΄Π²Π΅ Π²Π΅ΡΠΈ: ΡΠΆΠ΅ ΠΈΠΌΠ΅ΡΡΠΈΠΉΡΡ ΡΠΏΠΈΡΠΎΠΊ-ΠΈΡΡΠΎΡΠ½ΠΈΠΊ Ρ Π°ΠΏΡΠΈΠΎΡΠΈ Π²Π°Π»ΠΈΠ΄Π½ΡΠΌΠΈ Π½ΠΎΠΌΠ΅ΡΠ°ΠΌΠΈ Π²Π΅ΡΡΠΈΠΉ ΠΈ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ΡΠΈΠΏΠ° Choice parameter Π² Π·Π°Π΄Π°Π½ΠΈΠΈ. Π Π½Π°ΡΠ΅ΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΏΡΡΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π±ΡΠ΄Π΅Ρ Π½ΠΎΡΠΈΡΡ ΠΈΠΌΡ BUILD_VERSION, Π½Π° Π½Π΅ΠΉ ΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°ΡΡΡΡ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎ Π½Π΅ Π±ΡΠ΄Π΅ΠΌ. Π Π²ΠΎΡ Π½Π° ΡΠΏΠΈΡΠΊΠ΅-ΠΈΡΡΠΎΡΠ½ΠΈΠΊΠ΅ Π΄Π°Π²Π°ΠΉΡΠ΅ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΠΌΡΡ ΠΏΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅.
ΠΠ°ΡΠΈΠ°Π½ΡΠΎΠ² Π½Π΅ ΡΠ°ΠΊΠΎΠ΅ ΡΠΆ ΠΈ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ. ΠΠ½Π΅ ΡΡ ΠΎΠ΄Ρ Π² Π³ΠΎΠ»ΠΎΠ²Ρ ΠΏΡΠΈΡΠ»ΠΈ Π΄Π²Π°:
- ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Remote access API, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠ΅Π΄Π»Π°Π³Π°Π΅Ρ Jenkins ΡΠ²ΠΎΠΈΠΌ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΠΌ;
- ΠΠ°ΠΏΡΠ°ΡΠΈΠ²Π°ΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠΉ ΠΏΠ°ΠΏΠΊΠΈ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ (Π² Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΡΡΠΎ JFrog Artifactory, ΡΡΠΎ Π½Π΅ ΠΏΡΠΈΠ½ΡΠΈΠΏΠΈΠ°Π»ΡΠ½ΠΎ).
Jenkins Remote access API
ΠΠΎ ΡΠ»ΠΎΠΆΠΈΠ²ΡΠ΅ΠΉΡΡ ΠΏΡΠ΅ΠΊΡΠ°ΡΠ½ΠΎΠΉ ΡΡΠ°Π΄ΠΈΡΠΈΠΈ ΠΏΡΠ΅Π΄ΠΏΠΎΡΡΡ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΠΏΡΠΎΡΡΡΠ°Π½Π½ΡΡ
ΠΎΠ±ΡΡΡΠ½Π΅Π½ΠΈΠΉ.
ΠΠΎΠ·Π²ΠΎΠ»Ρ ΡΠ΅Π±Π΅ Π»ΠΈΡΡ Π²ΠΎΠ»ΡΠ½ΡΠΉ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ ΠΊΡΡΠΊΠ° ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ Π°Π±Π·Π°ΡΠ°
Jenkins ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ API Π΄Π»Ρ ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΌΠ°ΡΠΈΠ½Π½ΠΎ-ΠΏΠΎΠ½ΡΡΠ½ΠΎΠ³ΠΎ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΡΠ²ΠΎΠ΅ΠΌΡ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Ρ. <…> Π£Π΄Π°Π»Π΅Π½Π½ΡΠΉ Π΄ΠΎΡΡΡΠΏ ΠΏΡΠ΅Π΄Π»Π°Π³Π°Π΅ΡΡΡ Π² REST’ΠΎΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠΌ ΡΡΠΈΠ»Π΅. ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΎΡΡΡΡΡΡΠ²ΡΠ΅Ρ Π΅Π΄ΠΈΠ½Π°Ρ ΡΠΎΡΠΊΠ° Π²Ρ ΠΎΠ΄Π° ΠΊΠΎ Π²ΡΠ΅ΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠΌ, Π° Π²ΠΌΠ΅ΡΡΠΎ Π½Π΅Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ URL Π²ΠΈΠ΄Π° "…/api/", Π³Π΄Π΅ "…" ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡ, ΠΊ ΠΊΠΎΡΠΎΡΠΎΠΌΡ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ API.
ΠΠ½ΡΠΌΠΈ ΡΠ»ΠΎΠ²Π°ΠΌΠΈ, Π΅ΡΠ»ΠΈ Π·Π°Π΄Π°Π½ΠΈΠ΅ Π½Π° Π΄Π΅ΠΏΠ»ΠΎΠΉ, ΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΌΡ Π² Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ Π³ΠΎΠ²ΠΎΡΠΈΠΌ, Π΄ΠΎΡΡΡΠΏΠ½ΠΎ ΠΏΠΎ Π°Π΄ΡΠ΅ΡΡ http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build
, ΡΠΎ API-ΡΠ²ΠΈΡΡΡΠ»ΡΠΊΠΈ Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ Π·Π°Π΄Π°Π½ΠΈΡ Π΄ΠΎΡΡΡΠΏΠ½Ρ ΠΏΠΎ Π°Π΄ΡΠ΅ΡΡ http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/
ΠΠ°Π»Π΅Π΅ Ρ Π½Π°Ρ Π΅ΡΡΡ Π²ΡΠ±ΠΎΡ, Π² ΠΊΠ°ΠΊΠΎΠΌ Π²ΠΈΠ΄Π΅ ΠΏΠΎΠ»ΡΡΠ°ΡΡ Π²ΡΠ²ΠΎΠ΄. ΠΡΡΠ°Π½ΠΎΠ²ΠΈΠΌΡΡ Π½Π° XML, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ API ΡΠΎΠ»ΡΠΊΠΎ Π² ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΈΠ»ΡΡΡΠ°ΡΠΈΡ.
ΠΠ°Π²Π°ΠΉΡΠ΅ ΠΏΡΠΎΡΡΠΎ ΡΠ°ΠΊ ΠΏΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠΏΠΈΡΠΎΠΊ Π²ΡΠ΅Ρ Π·Π°ΠΏΡΡΠΊΠΎΠ² Π·Π°Π΄Π°Π½ΠΈΡ. ΠΠ°Ρ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΠ΅Ρ ΡΠΎΠ»ΡΠΊΠΎ ΠΈΠΌΡ ΡΠ±ΠΎΡΠΊΠΈ (displayName) ΠΈ Π΅Π΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ (result):
http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]
ΠΠΎΠ»ΡΡΠΈΠ»ΠΎΡΡ?
Π’Π΅ΠΏΠ΅ΡΡ ΠΎΡΡΠΈΠ»ΡΡΡΡΠ΅ΠΌ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ΅ Π·Π°ΠΏΡΡΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π² ΠΈΡΠΎΠ³Π΅ Ρ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠΌ SUCCESS. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ &exclude ΠΈ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° ΠΏΠ΅ΡΠ΅Π΄Π°Π΄ΠΈΠΌ Π΅ΠΌΡ ΠΏΡΡΡ Π΄ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π½Π΅ ΡΠ°Π²Π½ΠΎΠ³ΠΎ SUCCESS. ΠΠ°-Π΄Π°. ΠΠ²ΠΎΠΉΠ½ΠΎΠ΅ ΠΎΡΡΠΈΡΠ°Π½ΠΈΠ΅ β ΡΡΠΎ ΡΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠ΅. ΠΡΠΊΠ»ΡΡΠ°Π΅ΠΌ Π²ΡΠ΅ ΡΠΎ, ΡΡΠΎ Π½Π°Ρ Π½Π΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΠ΅Ρ:
http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]&exclude=freeStyleProject/allBuild[result!='SUCCESS']
Π‘ΠΊΡΠΈΠ½ΡΠΎΡ ΡΠΏΠΈΡΠΊΠ° ΡΡΠΏΠ΅ΡΠ½ΡΡ
ΠΡ ΠΈ ΠΏΡΠΎΡΡΠΎ Π΄Π»Ρ Π±Π°Π»ΠΎΠ²ΡΡΠ²Π° ΡΠ±Π΅Π΄ΠΈΠΌΡΡ, ΡΡΠΎ ΡΠΈΠ»ΡΡΡ Π½Π°Ρ Π½Π΅ ΠΎΠ±ΠΌΠ°Π½ΡΠ» (ΡΠΈΠ»ΡΡΡΡ ΠΆΠ΅ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π²ΡΡΡ!) ΠΈ Π²ΡΠ²Π΅Π΄Π΅ΠΌ ΡΠΏΠΈΡΠΎΠΊ Β«Π½Π΅-ΡΡΠΏΠ΅ΡΠ½ΡΡ Β»:
http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]&exclude=freeStyleProject/allBuild[result='SUCCESS']
Π‘ΠΊΡΠΈΠ½ΡΠΎΡ ΡΠΏΠΈΡΠΊΠ° Π½Π΅-ΡΡΠΏΠ΅ΡΠ½ΡΡ
Π‘ΠΏΠΈΡΠΎΠΊ Π²Π΅ΡΡΠΈΠΉ ΠΈΠ· ΠΏΠ°ΠΏΠΊΠΈ Π½Π° ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ ΡΠ΅ΡΠ²Π΅ΡΠ΅
ΠΡΡΡ ΠΈ Π²ΡΠΎΡΠΎΠΉ ΡΠΏΠΎΡΠΎΠ± ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠΏΠΈΡΠΎΠΊ Π²Π΅ΡΡΠΈΠΉ. ΠΠ½ ΠΌΠ½Π΅ Π½ΡΠ°Π²ΠΈΡΡΡ Π΄Π°ΠΆΠ΅ Π±ΠΎΠ»ΡΡΠ΅, ΡΠ΅ΠΌ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΊ API Jenkins’Π°. ΠΡ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Π΅ΡΠ»ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΡΠΏΠ΅ΡΠ½ΠΎ ΡΠΎΠ±ΡΠ°Π»ΠΎΡΡ, Π·Π½Π°ΡΠΈΡ Π΅Π³ΠΎ ΡΠΏΠ°ΠΊΠΎΠ²Π°Π»ΠΈ ΠΈ ΠΏΠΎΠ»ΠΎΠΆΠΈΠ»ΠΈ Π² ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ Π² ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΡΡ ΠΏΠ°ΠΏΠΊΡ. Π’ΠΈΠΏΠ°, ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ ΡΡΠΎ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ ΡΠ°Π±ΠΎΡΠΈΡ Π²Π΅ΡΡΠΈΠΉ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. Π’ΠΈΠΏΠ°. ΠΡ Π²ΠΎΡ ΠΈ ΡΠΏΡΠΎΡΠΈΠΌ Ρ Π½Π΅Π³ΠΎ, ΠΊΠ°ΠΊΠΈΠ΅ Π²Π΅ΡΡΠΈΠΈ Π½Π° Ρ ΡΠ°Π½Π΅Π½Π½ΠΈΠΈ. Π£Π΄Π°Π»Π΅Π½Π½ΡΡ ΠΏΠ°ΠΏΠΊΡ Π±ΡΠ΄Π΅ΠΌ curl’ΠΈΡΡ, grep’Π°ΡΡ ΠΈ awk’Π°ΡΡ. ΠΡΠ»ΠΈ ΠΊΠΎΠΌΡ-ΡΠΎ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ΅Π½ ΡΠ°Π½Π»Π°ΠΉΠ½Π΅Ρ, ΡΠΎ ΠΎΠ½ ΠΏΠΎΠ΄ ΡΠΏΠΎΠΉΠ»Π΅ΡΠΎΠΌ.
ΠΠΎΠΌΠ°Π½Π΄Π° ΠΎΠ΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΎΠΉ
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Π΄Π²Π΅ Π²Π΅ΡΠΈ: Ρ ΠΏΠ΅ΡΠ΅Π΄Π°Ρ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ ΡΠ΅ΠΊΠ²ΠΈΠ·ΠΈΡΡ Π΄Π»Ρ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΈ ΠΌΠ½Π΅ Π½Π΅ Π½ΡΠΆΠ½Ρ ΠΏΡΡΠΌΠΎ Π²ΠΎΠΎΠ±ΡΠ΅ Π²ΡΠ΅ Π²Π΅ΡΡΠΈΠΈ ΠΈΠ· ΠΏΠ°ΠΏΠΊΠΈ, ΠΈ Ρ ΠΎΡΠ±ΠΈΡΠ°Ρ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ΅, ΡΡΠΎ Π±ΡΠ»ΠΈ ΡΠΎΠ·Π΄Π°Π½Ρ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΌΠ΅ΡΡΡΠ°. ΠΡΡΠ΅Π΄Π°ΠΊΡΠΈΡΡΠΉΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ Π² ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠΈ Ρ Π²Π°ΡΠΈΠΌΠΈ ΡΠ΅Π°Π»ΠΈΡΠΌΠΈ ΠΈ ΠΏΠΎΡΡΠ΅Π±Π½ΠΎΡΡΡΠΌΠΈ:
curl -H "X-JFrog-Art-Api:VeryLongAPIKey" -s http://arts.myre.po/artifactory/awesomeapp/ | sed 's/a href=//' | grep "$(date +%b)-$(date +%Y)|$(date +%b --date='-1 month')-$(date +%Y)" | awk '{print $1}' | grep -oP '>K[^/]+' )
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π·Π°Π΄Π°Π½ΠΈΠΉ ΠΈ ΡΠ°ΠΉΠ» ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π·Π°Π΄Π°Π½ΠΈΡ Π² Jenkins
Π‘ ΠΈΡΡΠΎΡΠ½ΠΈΠΊΠΎΠΌ ΡΠΏΠΈΡΠΊΠ° Π²Π΅ΡΡΠΈΠΉ ΡΠ°Π·ΠΎΠ±ΡΠ°Π»ΠΈΡΡ. ΠΠ°Π²Π°ΠΉΡΠ΅ ΡΠ΅ΠΏΠ΅ΡΡ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ Π²ΠΊΡΡΡΠΈΠΌ Π² Π·Π°Π΄Π°Π½ΠΈΠ΅. ΠΠ»Ρ ΠΌΠ΅Π½Ρ ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΡΠΌ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ΠΌ Π±ΡΠ»ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΡΠ°Π³ Π² Π·Π°Π΄Π°Π½ΠΈΠΈ ΠΏΠΎ ΡΠ±ΠΎΡΠΊΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. Π¨Π°Π³, ΠΊΠΎΡΠΎΡΡΠΉ Π±Ρ Π²ΡΠΏΠΎΠ»Π½ΡΠ»ΡΡ Π² ΡΠ»ΡΡΠ°Π΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ° Β«ΡΡΠΏΠ΅Ρ Β».
ΠΡΠΊΡΡΠ²Π°Π΅ΠΌ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Π·Π°Π΄Π°Π½ΠΈΡ Π½Π° ΡΠ±ΠΎΡΠΊΡ ΠΈ ΡΠΊΡΠΎΠ»Π»ΠΈΠΌ Π² ΡΠ°ΠΌΡΠΉ Π½ΠΈΠ·. ΠΠΌΠ°ΠΊΠ°Π΅ΠΌ Π½Π° ΠΊΠ½ΠΎΠΏΠΎΡΠΊΠΈ: Add build step -> Conditional step (single). Π Π½Π°ΡΡΡΠΎΠΉΠΊΠ°Ρ ΡΠ°Π³Π° Π²ΡΠ±ΠΈΡΠ°Π΅ΠΌ ΡΡΠ»ΠΎΠ²ΠΈΠ΅ Current build status, Π²ΡΡΡΠ°Π²Π»ΡΠ΅ΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ SUCCESS, Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π² ΡΠ»ΡΡΠ°Π΅ ΡΡΠΏΠ΅Ρ Π° Run shell command.
Π ΡΠ΅ΠΏΠ΅ΡΡ ΡΠ°ΠΌΠΎΠ΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎΠ΅. ΠΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π·Π°Π΄Π°Π½ΠΈΠΉ Jenkins Ρ
ΡΠ°Π½ΠΈΡ Π² ΡΠ°ΠΉΠ»Π°Ρ
. Π ΡΠΎΡΠΌΠ°ΡΠ΅ XML. ΠΠΎ ΠΏΡΡΠΈ http://ΠΏΡΡΡ-Π΄ΠΎ-Π·Π°Π΄Π°Π½ΠΈΡ/config.xml
Π‘ΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°ΡΠ°ΡΡ ΡΠ°ΠΉΠ» Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠ΅ΠΉ, ΠΎΡΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°ΡΡ Π΅Π³ΠΎ Π½ΡΠΆΠ½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ ΠΈ ΠΏΠΎΠ»ΠΎΠΆΠΈΡΡ Π½Π° ΠΌΠ΅ΡΡΠΎ, ΠΎΡΠΊΡΠ΄Π° Π²Π·ΡΠ»ΠΈ.
ΠΠΎΠΌΠ½ΠΈΡΠ΅, Π²ΡΡΠ΅ ΠΌΡ Π΄ΠΎΠ³ΠΎΠ²ΠΎΡΠΈΠ»ΠΈΡΡ, ΡΡΠΎ Π΄Π»Ρ ΡΠΏΠΈΡΠΊΠ° Π²Π΅ΡΡΠΈΠΉ ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ BUILD_VERSION?
ΠΠ°Π²Π°ΠΉΡΠ΅ ΡΠΊΠ°ΡΠ°Π΅ΠΌ ΡΠ°ΠΉΠ» ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΠΈ Π·Π°Π³Π»ΡΠ½Π΅ΠΌ Π²Π½ΡΡΡΡ Π½Π΅Π³ΠΎ. ΠΡΠΎΡΡΠΎ ΡΡΠΎΠ±Ρ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ, ΡΡΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ Π½Π° ΠΌΠ΅ΡΡΠ΅ ΠΈ Π² ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ Π½ΡΠΆΠ½ΠΎΠ³ΠΎ Π²ΠΈΠ΄Π°.
Π‘ΠΊΡΠΈΠ½ΡΠΎΡ ΠΏΠΎΠ΄ ΡΠΏΠΎΠΉΠ»Π΅ΡΠΎΠΌ.
Π£ Π²Π°Ρ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΡΠΉ ΡΡΠ°Π³ΠΌΠ΅Π½Ρ config.xml Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ ΡΠ°ΠΊ ΠΆΠ΅. ΠΠ° ΡΠ΅ΠΌ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ, ΡΡΠΎ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° choices ΠΏΠΎΠΊΠ° ΡΡΠΎ ΠΎΡΡΡΡΡΡΠ²ΡΠ΅Ρ
Π£Π±Π΅Π΄ΠΈΠ»ΠΈΡΡ? ΠΡ Π²ΡΠ΅, ΠΏΠΈΡΠ΅ΠΌ ΡΠΊΡΠΈΠΏΡ, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ Π² ΡΠ»ΡΡΠ°Π΅ ΡΡΠΏΠ΅ΡΠ½ΠΎΠΉ ΡΠ±ΠΎΡΠΊΠΈ.
Π‘ΠΊΡΠΈΠΏΡ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ»ΡΡΠ°ΡΡ ΡΠΏΠΈΡΠΎΠΊ Π²Π΅ΡΡΠΈΠΉ, ΡΠΊΠ°ΡΠΈΠ²Π°ΡΡ ΡΠ°ΠΉΠ» ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ, ΠΏΠΈΡΠ°ΡΡ Π² Π½Π΅Π³ΠΎ Π² Π½ΡΠΆΠ½ΠΎΠ΅ Π½Π°ΠΌ ΠΌΠ΅ΡΡΠΎ ΡΠΏΠΈΡΠΎΠΊ Π²Π΅ΡΡΠΈΠΉ, Π° ΠΏΠΎΡΠΎΠΌ ΠΊΠ»Π°ΡΡΡ Π΅Π³ΠΎ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ. ΠΠ°. ΠΡΠ΅ Π²Π΅ΡΠ½ΠΎ. ΠΠΈΡΠ°ΡΡ ΡΠΏΠΈΡΠΎΠΊ Π²Π΅ΡΡΠΈΠΉ Π² XML’ΠΊΡ Π² ΡΠΎ ΠΌΠ΅ΡΡΠΎ, Π³Π΄Π΅ ΡΠΆΠ΅ Π΅ΡΡΡ ΡΠΏΠΈΡΠΎΠΊ Π²Π΅ΡΡΠΈΠΉ (Π±ΡΠ΄Π΅Ρ Π² Π±ΡΠ΄ΡΡΠ΅ΠΌ, ΠΏΠΎΡΠ»Π΅ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ Π·Π°ΠΏΡΡΠΊΠ° ΡΠΊΡΠΈΠΏΡΠ°). Π― Π·Π½Π°Ρ, Π² ΠΌΠΈΡΠ΅ Π΅ΡΠ΅ ΠΆΠΈΠ²ΡΡ Π»ΡΡΡΠ΅ Π»ΡΠ±ΠΈΡΠ΅Π»ΠΈ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΡΡ
Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΉ. Π― ΠΊ Π½ΠΈΠΌ Π½Π΅ ΠΎΡΠ½ΠΎΡΡΡΡ. Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅, ΠΏΠΎΠΆΠ°Π»ΡΠΉΡΡΠ°,
ΠΠΎΠ΄ ΡΠΏΠΎΠΉΠ»Π΅ΡΠΎΠΌ ΠΏΡΠΈΠ²ΠΎΠΆΡ ΠΊΠΎΠ΄, Π²ΡΠΏΠΎΠ»Π½ΡΡΡΠΈΠΉ Π²ΡΡΠ΅ΠΎΠΏΠΈΡΠ°Π½Π½ΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΡΠ΅Π»ΠΈΠΊΠΎΠΌ.
ΠΠΈΡΠ΅ΠΌ Π² ΠΊΠΎΠ½ΡΠΈΠ³ ΡΠΏΠΈΡΠΎΠΊ Π²Π΅ΡΡΠΈΠΉ ΠΈΠ· ΠΏΠ°ΠΏΠΊΠΈ Π½Π° ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ ΡΠ΅ΡΠ²Π΅ΡΠ΅
#!/bin/bash
############## Π‘ΠΊΠ°ΡΠΈΠ²Π°Π΅ΠΌ ΠΊΠΎΠ½ΡΠΈΠ³
curl -X GET -u username:apiKey http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_k8s/config.xml -o appConfig.xml
############## Π£Π΄Π°Π»ΡΠ΅ΠΌ ΠΈ Π·Π°Π½ΠΎΠ²ΠΎ ΡΠΎΠ·Π΄Π°Π΅ΠΌ xml-ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π΄Π»Ρ ΡΠΏΠΈΡΠΊΠ° Π²Π΅ΡΡΠΈΠΉ
xmlstarlet ed --inplace -d '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a[@class="string-array"]' appConfig.xml
xmlstarlet ed --inplace --subnode '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]' --type elem -n a appConfig.xml
xmlstarlet ed --inplace --insert '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a' --type attr -n class -v string-array appConfig.xml
############## Π§ΠΈΡΠ°Π΅ΠΌ Π² ΠΌΠ°ΡΡΠΈΠ² ΡΠΏΠΈΡΠΎΠΊ Π²Π΅ΡΡΠΈΠΉ ΠΈΠ· ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ
readarray -t vers < <( curl -H "X-JFrog-Art-Api:Api:VeryLongAPIKey" -s http://arts.myre.po/artifactory/awesomeapp/ | sed 's/a href=//' | grep "$(date +%b)-$(date +%Y)|$(date +%b --date='-1 month')-$(date +%Y)" | awk '{print $1}' | grep -oP '>K[^/]+' )
############## ΠΠΈΡΠ΅ΠΌ ΠΌΠ°ΡΡΠΈΠ² ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π·Π° ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠΌ Π² ΠΊΠΎΠ½ΡΠΈΠ³
printf '%sn' "${vers[@]}" | sort -r |
while IFS= read -r line
do
xmlstarlet ed --inplace --subnode '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a[@class="string-array"]' --type elem -n string -v "$line" appConfig.xml
done
############## ΠΠ»Π°Π΄Π΅ΠΌ ΠΊΠΎΠ½ΡΠΈΠ³ Π²Π·Π°Π΄
curl -X POST -u username:apiKey http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_k8s/config.xml --data-binary @appConfig.xml
############## ΠΡΠΈΠ²ΠΎΠ΄ΠΈΠΌ ΡΠ°Π±ΠΎΡΠ΅Π΅ ΠΌΠ΅ΡΡΠΎ Π² ΠΏΠΎΡΡΠ΄ΠΎΠΊ
rm -f appConfig.xml
ΠΡΠ»ΠΈ Π²Π°ΠΌ Π±ΠΎΠ»ΡΡΠ΅ ΠΏΠΎΠ½ΡΠ°Π²ΠΈΠ»ΡΡ Π²Π°ΡΠΈΠ°Π½Ρ Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ Π²Π΅ΡΡΠΈΠΉ ΠΈΠ· Jenkins’Π° ΠΈ Π²Ρ ΡΠ°ΠΊ ΠΆΠ΅ Π»Π΅Π½ΠΈΠ²Ρ, ΠΊΠ°ΠΊ Ρ, ΡΠΎ ΠΏΠΎΠ΄ ΡΠΏΠΎΠΉΠ»Π΅ΡΠΎΠΌ ΡΠΎΡ ΠΆΠ΅ ΡΠ°ΠΌΡΠΉ ΠΊΠΎΠ΄, Π½ΠΎ ΡΠΏΠΈΡΠΎΠΊ ΠΈΠ· Jenkins’Π°:
ΠΠΈΡΠ΅ΠΌ Π² ΠΊΠΎΠ½ΡΠΈΠ³ ΡΠΏΠΈΡΠΎΠΊ Π²Π΅ΡΡΠΈΠΉ ΠΈΠ· Jenkins'Π°
Π’ΠΎΠ»ΡΠΊΠΎ ΡΡΡΠΈΡΠ΅ ΠΌΠΎΠΌΠ΅Π½Ρ: Ρ ΠΌΠ΅Π½Ρ ΠΈΠΌΡ ΡΠ±ΠΎΡΠΊΠΈ ΡΠΎΡΡΠΎΠΈΡ ΠΈΠ· ΠΏΠΎΡΡΠ΄ΠΊΠΎΠ²ΠΎΠ³ΠΎ Π½ΠΎΠΌΠ΅ΡΠ° ΠΈ Π½ΠΎΠΌΠ΅ΡΠ° Π²Π΅ΡΡΠΈΠΈ, ΡΠ°Π·Π΄Π΅Π»Π΅Π½Π½ΡΡ
Π΄Π²ΠΎΠ΅ΡΠΎΡΠΈΠ΅ΠΌ. Π‘ΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, awk ΠΎΡΡΠ΅Π·Π°Π΅Ρ Π½Π΅Π½ΡΠΆΠ½ΡΡ ΡΠ°ΡΡΡ. ΠΠ»Ρ ΡΠ΅Π±Ρ ΡΡΡ ΡΡΡΠΎΠΊΡ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΠ΅ ΠΏΠΎΠ΄ Π²Π°ΡΠΈ Π½ΡΠΆΠ΄Ρ.
#!/bin/bash
############## Π‘ΠΊΠ°ΡΠΈΠ²Π°Π΅ΠΌ ΠΊΠΎΠ½ΡΠΈΠ³
curl -X GET -u username:apiKey http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_k8s/config.xml -o appConfig.xml
############## Π£Π΄Π°Π»ΡΠ΅ΠΌ ΠΈ Π·Π°Π½ΠΎΠ²ΠΎ ΡΠΎΠ·Π΄Π°Π΅ΠΌ xml-ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π΄Π»Ρ ΡΠΏΠΈΡΠΊΠ° Π²Π΅ΡΡΠΈΠΉ
xmlstarlet ed --inplace -d '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a[@class="string-array"]' appConfig.xml
xmlstarlet ed --inplace --subnode '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]' --type elem -n a appConfig.xml
xmlstarlet ed --inplace --insert '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a' --type attr -n class -v string-array appConfig.xml
############## ΠΠΈΡΠ΅ΠΌ Π² ΡΠ°ΠΉΠ» ΡΠΏΠΈΡΠΎΠΊ Π²Π΅ΡΡΠΈΠΉ ΠΈΠ· Jenkins
curl -g -X GET -u username:apiKey 'http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]&exclude=freeStyleProject/allBuild[result!=%22SUCCESS%22]&pretty=true' -o builds.xml
############## Π§ΠΈΡΠ°Π΅ΠΌ Π² ΠΌΠ°ΡΡΠΈΠ² ΡΠΏΠΈΡΠΎΠΊ Π²Π΅ΡΡΠΈΠΉ ΠΈΠ· XML
readarray vers < <(xmlstarlet sel -t -v "freeStyleProject/allBuild/displayName" builds.xml | awk -F":" '{print $2}')
############## ΠΠΈΡΠ΅ΠΌ ΠΌΠ°ΡΡΠΈΠ² ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π·Π° ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠΌ Π² ΠΊΠΎΠ½ΡΠΈΠ³
printf '%sn' "${vers[@]}" | sort -r |
while IFS= read -r line
do
xmlstarlet ed --inplace --subnode '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a[@class="string-array"]' --type elem -n string -v "$line" appConfig.xml
done
############## ΠΠ»Π°Π΄Π΅ΠΌ ΠΊΠΎΠ½ΡΠΈΠ³ Π²Π·Π°Π΄
curl -X POST -u username:apiKey http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_k8s/config.xml --data-binary @appConfig.xml
############## ΠΡΠΈΠ²ΠΎΠ΄ΠΈΠΌ ΡΠ°Π±ΠΎΡΠ΅Π΅ ΠΌΠ΅ΡΡΠΎ Π² ΠΏΠΎΡΡΠ΄ΠΎΠΊ
rm -f appConfig.xml
ΠΠΎ ΠΈΠ΄Π΅Π΅, Π΅ΡΠ»ΠΈ Π²Ρ ΠΏΡΠΎΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π»ΠΈ ΠΊΠΎΠ΄, Π½Π°ΠΏΠΈΡΠ°Π½Π½ΡΠΉ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ ΠΏΡΠΈΠΌΠ΅ΡΠΎΠ² Π²ΡΡΠ΅, ΡΠΎ Π² Π·Π°Π΄Π°Π½ΠΈΠΈ Π½Π° Π΄Π΅ΠΏΠ»ΠΎΠΉ Ρ Π²Π°Ρ ΡΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠΎΡΠ²ΠΈΡΡΡΡ Π²ΡΠΏΠ°Π΄Π°ΡΡΠΈΠΉ ΡΠΏΠΈΡΠΎΠΊ Ρ Π²Π΅ΡΡΠΈΡΠΌΠΈ. ΠΠΎΡ ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ ΠΊΠ°ΠΊ Π½Π° ΡΠΊΡΠΈΠ½ΡΠΎΡΠ΅ ΠΏΠΎΠ΄ ΡΠΏΠΎΠΉΠ»Π΅ΡΠΎΠΌ.
ΠΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ Π²Π΅ΡΡΠΈΠΉ
ΠΡΠ»ΠΈ Π²ΡΠ΅ ΠΎΡΡΠ°Π±ΠΎΡΠ°Π»ΠΎ, ΡΠΎ ΠΊΠΎΠΏΠΈΠΏΠ°ΡΡΠΈΡΠ΅ ΡΠΊΡΠΈΠΏΡ Π² Run shell command ΠΈ ΡΠΎΡ ΡΠ°Π½ΡΠΉΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ.
ΠΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊ Cloud shell
Π‘Π±ΠΎΡΡΠΈΠΊΠΈ Ρ Π½Π°Ρ Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°Ρ . Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΡΠ΅Π΄ΡΡΠ²Π° Π΄ΠΎΡΡΠ°Π²ΠΊΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΈ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΉ ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Ansible. Π‘ΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° ΡΠ΅ΡΡ Π·Π°Ρ ΠΎΠ΄ΠΈΡ ΠΎ ΡΠ±ΠΎΡΠΊΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΎΠ², Π²Π°ΡΠΈΠ°Π½ΡΠΎΠ² Π² Π³ΠΎΠ»ΠΎΠ²Ρ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΡ ΡΡΠΈ: ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Docker Π² Docker’Π΅, ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Docker Π½Π° ΠΌΠ°ΡΠΈΠ½Ρ Ρ Ansible’ΠΎΠΌ, Π»ΠΈΠ±ΠΎ ΡΠΎΠ±ΠΈΡΠ°ΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΡ Π² ΠΎΠ±Π»Π°ΡΠ½ΠΎΠΉ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ. ΠΡΠΎ ΠΏΠ»Π°Π³ΠΈΠ½Ρ Π΄Π»Ρ Jenkins ΠΌΡ Π΄ΠΎΠ³ΠΎΠ²ΠΎΡΠΈΠ»ΠΈΡΡ Π² ΡΡΠΎΠΉ Π·Π°ΠΌΠ΅ΡΠΊΠ΅ ΠΌΠΎΠ»ΡΠ°ΡΡ. ΠΠΎΠΌΠ½ΠΈΡΠ΅?
Π― ΡΠ΅ΡΠΈΠ»: Π½Ρ, ΡΠ°Π· ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΡ Β«ΠΈΠ· ΠΊΠΎΡΠΎΠ±ΠΊΠΈΒ» ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ±ΠΈΡΠ°ΡΡ Π² ΠΎΠ±Π»Π°ΡΠ½ΠΎΠΉ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ, ΡΠΎ Π·Π°ΡΠ΅ΠΌ Π³ΠΎΡΠΎΠ΄ΠΈΡΡ ΠΎΠ³ΠΎΡΠΎΠ΄? Keep it clean, Π²Π΅ΡΠ½ΠΎ? Π₯ΠΎΡΡ ΡΠΎΠ±ΠΈΡΠ°ΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΡ Jenkins’ΠΎΠΌ Π² ΠΎΠ±Π»Π°ΡΠ½ΠΎΠΉ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ, Π° ΠΏΠΎΡΠΎΠΌ ΠΎΡΡΡΠ΄Π° ΠΆΠ΅ ΠΏΡΠ»ΡΡΡ ΠΈΡ Π² ΠΊΡΠ±Π΅Ρ. Π’Π΅ΠΌ Π±ΠΎΠ»Π΅Π΅, ΡΡΠΎ Π²Π½ΡΡΡΠΈ ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΡ Ρ Π³ΡΠ³Π»Π° Π½Ρ ΠΎΠΎΠΎΡΠ΅Π½Ρ ΠΆΠΈΡΠ½ΡΠ΅ ΠΊΠ°Π½Π°Π»Ρ, ΡΡΠΎ Π±Π»Π°Π³ΠΎΠΏΡΠΈΡΡΠ½ΠΎ ΡΠΊΠ°ΠΆΠ΅ΡΡΡ Π½Π° ΡΠΊΠΎΡΠΎΡΡΠΈ Π΄Π΅ΠΏΠ»ΠΎΡ.
ΠΠ»Ρ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΊ ΠΎΠ±Π»Π°ΡΠ½ΠΎΠΉ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡ Π΄Π²Π΅ Π²Π΅ΡΠΈ: gcloud ΠΈ ΠΏΡΠ°Π²Π° Π΄ΠΎΡΡΡΠΏΠ° ΠΊ Google Cloud API Π΄Π»Ρ ΡΠΎΠ³ΠΎ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° ΠΠ, Ρ ΠΊΠΎΡΠΎΡΠΎΠΉ Π±ΡΠ΄Π΅Ρ ΡΡΠΎ ΡΠ°ΠΌΠΎΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡΡΡ.
ΠΠ»Ρ ΡΠ΅Ρ
, ΠΊΡΠΎ ΠΏΠ»Π°Π½ΠΈΡΡΠ΅Ρ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°ΡΡΡΡ Π²ΠΎΠΎΠ±ΡΠ΅ Π½Π΅ ΠΈΠ· Π³ΡΠ³Π»ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠ±Π»Π°ΠΊΠ°
ΠΡΠ³Π» Π΄ΠΎΠΏΡΡΠΊΠ°Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΎΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΈΠ½ΡΠ΅ΡΠ°ΠΊΡΠΈΠ²Π½ΠΎΠΉ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΈ Π² ΡΠ²ΠΎΠΈΡ
ΡΠ΅ΡΠ²ΠΈΡΠ°Ρ
. ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°ΡΡΡΡ ΠΊ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ Ρ
ΠΎΡΡ Ρ ΠΊΠΎΡΠ΅ΠΌΠ°ΡΠΈΠ½Ρ, ΠΊΠΎΠ»ΠΈ ΠΎΠ½Π° ΠΏΠΎΠ΄ *nix’Π°ΠΌΠΈ ΠΈ Ρ Π½Π΅Π΅ ΡΠ°ΠΌΠΎΠΉ Π΅ΡΡΡ ΠΊΠΎΠ½ΡΠΎΠ»Ρ.
ΠΡΠ»ΠΈ Π΅ΡΡΡ ΠΏΠΎΡΡΠ΅Π±Π½ΠΎΡΡΡ Π² ΡΠΎΠΌ, ΡΡΠΎΠ±Ρ Ρ ΠΎΡΠ²Π΅ΡΠΈΠ» ΡΡΠΎΡ Π²ΠΎΠΏΡΠΎΡ ΠΏΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅ Π² ΡΠ°ΠΌΠΊΠ°Ρ ΡΡΠΎΠΉ Π·Π°ΠΌΠ΅ΡΠΊΠΈ β ΠΏΠΈΡΠΈΡΠ΅ Π² ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΡΡ . ΠΠ°Π±Π΅ΡΠ΅ΡΡΡ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π³ΠΎΠ»ΠΎΡΠΎΠ² β Π½Π°ΠΏΠΈΡΡ Π°ΠΏΠ΄Π΅ΠΉΡ ΠΏΠΎ ΡΡΠΎΠΉ ΡΠ΅ΠΌΠ΅.
ΠΡΠΎΡΡΠ΅ΠΉΡΠΈΠΉ ΡΠΏΠΎΡΠΎΠ± Π΄Π°ΡΡ ΠΏΡΠ°Π²Π° β ΡΠ΅ΡΠ΅Π· Π²Π΅Π±-ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ.
- ΠΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ ΠΠ, Ρ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π² Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΌ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊ ΠΎΠ±Π»Π°ΡΠ½ΠΎΠΉ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ.
- ΠΡΠΊΡΠΎΠΉΡΠ΅ Π‘Π²Π΅Π΄Π΅Π½ΠΈΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° ΠΈ Π½Π°ΠΆΠΌΠΈΡΠ΅ ΠΠ·ΠΌΠ΅Π½ΠΈΡΡ.
- Π ΡΠ°ΠΌΠΎΠΌ Π½ΠΈΠ·Ρ ΡΡΡΠ°Π½ΠΈΡΡ Π²ΡΠ±Π΅ΡΠΈΡΠ΅ ΠΎΠ±Π»Π°ΡΡΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ Π΄ΠΎΡΡΡΠΏΠ° ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° ΠΠΎΠ»Π½ΡΠΉ Π΄ΠΎΡΡΡΠΏ ΠΊΠΎ Π²ΡΠ΅ΠΌ Cloud API.
Π‘ΠΊΡΠΈΠ½ΡΠΎΡ
- Π‘ΠΎΡ ΡΠ°Π½ΠΈΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΠΈ Π·Π°ΠΏΡΡΡΠΈΡΠ΅ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ.
ΠΠΎ ΠΎΠΊΠΎΠ½ΡΠ°Π½ΠΈΠΈ Π·Π°Π³ΡΡΠ·ΠΊΠΈ ΠΠ, ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΡΠ΅ΡΡ ΠΊ Π½Π΅ΠΉ ΠΏΠΎ SSH ΠΈ ΡΠ±Π΅Π΄ΠΈΡΠ΅ΡΡ, ΡΡΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Π±Π΅Π· ΠΎΡΠΈΠ±ΠΊΠΈ. ΠΠΎΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ:
gcloud alpha cloud-shell ssh
Π£ΡΠΏΠ΅ΡΠ½ΠΎΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ ΡΠ°ΠΊ
ΠΠ΅ΠΏΠ»ΠΎΠΉ Π² GKE
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΌΡ Π²ΡΡΡΠ΅ΡΠΊΠΈ ΡΡΡΠ΅ΠΌΠΈΠΌΡΡ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΠΏΠ΅ΡΠ΅ΠΉΡΠΈ Π½Π° IaC (Infrastucture as a Code), Π΄ΠΎΠΊΠ΅ΡΡΠ°ΠΉΠ»Ρ Ρ Π½Π°Ρ Ρ ΡΠ°Π½ΡΡΡΡ Π² Π³ΠΈΡΠ΅. ΠΡΠΎ Ρ ΠΎΠ΄Π½ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ. Π Π΄Π΅ΠΏΠ»ΠΎΠΉ Π² kubernetes ΠΎΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ yaml-ΡΠ°ΠΉΠ»ΠΎΠΌ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π°Π½Π½ΡΠΌ Π·Π°Π΄Π°Π½ΠΈΠ΅ΠΌ, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ°ΠΌ ΠΏΠΎ ΡΠ΅Π±Π΅ ΡΠΎΠΆΠ΅ ΠΊΠ°ΠΊ Π±Ρ ΠΊΠΎΠ΄. ΠΡΠΎ Ρ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ. Π ΠΎΠ±ΡΠ΅ΠΌ, Ρ ΠΊ ΡΠΎΠΌΡ, ΡΡΠΎ ΠΏΠ»Π°Π½ ΡΠ°ΠΊΠΎΠ²:
- ΠΠ΅ΡΠ΅ΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ BUILD_VERSION ΠΈ, ΠΎΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎ, Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ , ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄ΡΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π½Ρ ΡΠ΅ΡΠ΅Π· ENV.
- ΠΠ°ΡΠ°Π΅ΠΌ ΠΈΠ· Π³ΠΈΡΠ° Π΄ΠΎΠΊΠ΅ΡΡΠ°ΠΉΠ».
- ΠΠ΅Π½Π΅ΡΠΈΡΡΠ΅ΠΌ yaml Π΄Π»Ρ Π΄Π΅ΠΏΠ»ΠΎΡ.
- ΠΠ°Π»ΠΈΠ²Π°Π΅ΠΌ ΠΎΠ±Π° ΡΡΠΈΡ ΡΠ°ΠΉΠ»Π° ΠΏΠΎ scp Π² ΠΎΠ±Π»Π°ΡΠ½ΡΡ ΠΊΠΎΠ½ΡΠΎΠ»Ρ.
- ΠΠΈΠ»Π΄ΠΈΠΌ ΡΠ°ΠΌ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ ΠΈ ΠΏΡΡΠ°Π΅ΠΌ Π΅Π³ΠΎ Π² Container registry
- ΠΡΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ ΡΠ°ΠΉΠ» Π΄Π΅ΠΏΠ»ΠΎΡ Π½Π°Π³ΡΡΠ·ΠΊΠΈ Π² ΠΊΡΠ±Π΅Ρ.
ΠΠ°Π²Π°ΠΉΡΠ΅ Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ. Π Π°Π· Π·Π°Π³ΠΎΠ²ΠΎΡΠΈΠ»ΠΈ ΠΎΠ± ENV, ΡΠΎ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Π½Π°ΠΌ Π½Π°Π΄ΠΎ Π±ΡΠ΄Π΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π΄Π²ΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ²: PARAM1 ΠΈ PARAM2. ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΠΈΡ Π·Π°Π΄Π°Π½ΠΈΠ΅ Π½Π° Π΄Π΅ΠΏΠ»ΠΎΠΉ, ΡΠΈΠΏ β String Parameter.
Π‘ΠΊΡΠΈΠ½ΡΠΎΡ
ΠΠ΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ yaml Π±ΡΠ΄Π΅ΠΌ ΠΏΡΠΎΡΡΡΠΌ ΠΏΠ΅ΡΠ΅Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ echo Π² ΡΠ°ΠΉΠ». ΠΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΡΡΡ, ΡΠ°Π·ΡΠΌΠ΅Π΅ΡΡΡ, ΡΡΠΎ Π² Π΄ΠΎΠΊΠ΅ΡΡΠ°ΠΉΠ»Π΅ Ρ Π²Π°Ρ ΠΏΡΠΈΡΡΡcnΠ²ΡΡΡ PARAM1 ΠΈ PARAM2, ΡΡΠΎ ΠΈΠΌΡ Π½Π°Π³ΡΡΠ·ΠΊΠΈ Π±ΡΠ΄Π΅Ρ awesomeapp, Π° ΡΠΎΠ±ΡΠ°Π½Π½ΡΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ Π»Π΅ΠΆΠΈΡ Π² Container registry ΠΏΠΎ ΠΏΡΡΠΈ gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION, Π³Π΄Π΅ $BUILD_VERSION ΠΊΠ°ΠΊ ΡΠ°Π· ΠΈ Π±ΡΠ» Π²ΡΠ±ΡΠ°Π½ ΠΈΠ· Π²ΡΠΏΠ°Π΄Π°ΡΡΠ΅Π³ΠΎ ΡΠΏΠΈΡΠΊΠ°.
ΠΠΈΡΡΠΈΠ½Π³ ΠΊΠΎΠΌΠ°Π½Π΄
touch deploy.yaml
echo "apiVersion: apps/v1" >> deploy.yaml
echo "kind: Deployment" >> deploy.yaml
echo "metadata:" >> deploy.yaml
echo " name: awesomeapp" >> deploy.yaml
echo "spec:" >> deploy.yaml
echo " replicas: 1" >> deploy.yaml
echo " selector:" >> deploy.yaml
echo " matchLabels:" >> deploy.yaml
echo " run: awesomeapp" >> deploy.yaml
echo " template:" >> deploy.yaml
echo " metadata:" >> deploy.yaml
echo " labels:" >> deploy.yaml
echo " run: awesomeapp" >> deploy.yaml
echo " spec:" >> deploy.yaml
echo " containers:" >> deploy.yaml
echo " - name: awesomeapp" >> deploy.yaml
echo " image: gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION:latest" >> deploy.yaml
echo " env:" >> deploy.yaml
echo " - name: PARAM1" >> deploy.yaml
echo " value: $PARAM1" >> deploy.yaml
echo " - name: PARAM2" >> deploy.yaml
echo " value: $PARAM2" >> deploy.yaml
ΠΠ³Π΅Π½ΡΡ Jenkins’Π° ΠΏΠΎΡΠ»Π΅ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ gcloud alpha cloud-shell ssh ΠΈΠ½ΡΠ΅ΡΠ°ΠΊΡΠΈΠ²Π½ΡΠΉ ΡΠ΅ΠΆΠΈΠΌ Π½Π΅ Π΄ΠΎΡΡΡΠΏΠ΅Π½, ΠΏΠΎΡΡΠΎΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Ρ Π² ΠΎΠ±Π»Π°ΡΠ½ΡΡ ΠΊΠΎΠ½ΡΠΎΠ»Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° —command.
Π§ΠΈΡΡΠΈΠΌ Π΄ΠΎΠΌΠ°ΡΠ½ΡΡ ΠΏΠ°ΠΏΠΊΡ Π² ΠΎΠ±Π»Π°ΡΠ½ΠΎΠΉ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ ΠΎΡ ΡΡΠ°ΡΠΎΠ³ΠΎ Π΄ΠΎΠΊΠ΅ΡΡΠ°ΠΉΠ»Π°:
gcloud alpha cloud-shell ssh --command="rm -f Dockerfile"
ΠΠ»Π°Π΄Π΅ΠΌ ΡΠ²Π΅ΠΆΠ΅ΡΠΊΠ°ΡΠ΅Π½Π½ΡΠΉ Π΄ΠΎΠΊΠ΅ΡΡΠ°ΠΉΠ» Π² Π΄ΠΎΠΌΠ°ΡΠ½ΡΡ ΠΏΠ°ΠΏΠΊΡ ΠΎΠ±Π»Π°ΡΠ½ΠΎΠΉ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ scp:
gcloud alpha cloud-shell scp localhost:./Dockerfile cloudshell:~
Π‘ΠΎΠ±ΠΈΡΠ°Π΅ΠΌ, ΡΠ΅Π³ΠΈΡΡΠ΅ΠΌ ΠΈ ΠΏΡΡΠ°Π΅ΠΌ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Π² Container registry:
gcloud alpha cloud-shell ssh --command="docker build -t awesomeapp-$BUILD_VERSION ./ --build-arg BUILD_VERSION=$BUILD_VERSION --no-cache"
gcloud alpha cloud-shell ssh --command="docker tag awesomeapp-$BUILD_VERSION gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION"
gcloud alpha cloud-shell ssh --command="docker push gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION"
ΠΠ½Π°Π»ΠΎΠ³ΠΈΡΠ½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ ΠΏΠΎΡΡΡΠΏΠ°Π΅ΠΌ Ρ ΡΠ°ΠΉΠ»ΠΎΠΌ Π΄Π΅ΠΏΠ»ΠΎΡ. ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΡ, ΡΡΠΎ Π² ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ Π½ΠΈΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π²ΡΠΌΡΡΠ»Π΅Π½Π½ΡΠ΅ ΠΈΠΌΠ΅Π½Π° ΠΊΠ»Π°ΡΡΠ΅ΡΠ°, ΠΊΡΠ΄Π° ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Π΄Π΅ΠΏΠ»ΠΎΠΉ (awsm-cluster) ΠΈ ΠΈΠΌΡ ΠΏΡΠΎΠ΅ΠΊΡΠ° (awesome-project), Π³Π΄Π΅ Π½Π°Ρ ΠΎΠ΄Π΅ΡΡΡ ΠΊΠ»Π°ΡΡΠ΅Ρ.
gcloud alpha cloud-shell ssh --command="rm -f deploy.yaml"
gcloud alpha cloud-shell scp localhost:./deploy.yaml cloudshell:~
gcloud alpha cloud-shell ssh --command="gcloud container clusters get-credentials awsm-cluster --zone us-central1-c --project awesome-project &&
kubectl apply -f deploy.yaml"
ΠΠ°ΠΏΡΡΠΊΠ°Π΅ΠΌ Π·Π°Π΄Π°Π½ΠΈΠ΅, ΠΎΡΠΊΡΡΠ²Π°Π΅ΠΌ Π²ΡΠ²ΠΎΠ΄ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ ΠΈ Π½Π°Π΄Π΅Π΅ΠΌΡΡ ΡΠ²ΠΈΠ΄Π΅ΡΡ ΡΡΠΏΠ΅ΡΠ½ΡΡ ΡΠ±ΠΎΡΠΊΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°.
Π‘ΠΊΡΠΈΠ½ΡΠΎΡ
Π Π΄Π°Π»Π΅Π΅ ΠΈ ΡΡΠΏΠ΅ΡΠ½ΡΠΉ Π΄Π΅ΠΏΠ»ΠΎΠΉ ΡΠΎΠ±ΡΠ°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°
Π‘ΠΊΡΠΈΠ½ΡΠΎΡ
Π― ΡΠΌΡΡΠ»Π΅Π½Π½ΠΎ ΠΎΠ±ΠΎΡΠ΅Π» Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ΠΌ Π½Π°ΡΡΡΠΎΠΉΠΊΡ Ingress. ΠΠΎ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡΠΎΡΡΠΎΠΉ ΠΏΡΠΈΡΠΈΠ½Π΅: ΠΎΠ΄Π½Π°ΠΆΠ΄Ρ Π½Π°ΡΡΡΠΎΠΈΠ² Π΅Π³ΠΎ Π½Π° workload Ρ Π·Π°Π΄Π°Π½Π½ΡΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ, ΠΎΠ½ ΠΎΡΡΠ°Π½Π΅ΡΡΡ ΡΠ°Π±ΠΎΡΠΎΡΠΏΠΎΡΠΎΠ±Π½ΡΠΌ, ΡΠΊΠΎΠ»ΡΠΊΠΎ Π΄Π΅ΠΏΠ»ΠΎΠ΅Π² Ρ ΡΡΠΈΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ Π½ΠΈ ΠΏΡΠΎΠ²ΠΎΠ΄ΠΈ. ΠΡ ΠΈ Π²ΠΎΠΎΠ±ΡΠ΅, ΡΡΠΎ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π·Π° ΡΠ°ΠΌΠΊΠ°ΠΌΠΈ ΠΈΡΡΠΎΡΠΈΠΈ.
ΠΠΌΠ΅ΡΡΠΎ Π²ΡΠ²ΠΎΠ΄ΠΎΠ²
ΠΡΠ΅ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΡΠ΅ Π²ΡΡΠ΅ ΡΠ°Π³ΠΈ, Π½Π°Π²Π΅ΡΠ½ΠΎΠ΅, ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ Π½Π΅ Π΄Π΅Π»Π°ΡΡ, Π° ΠΏΡΠΎΡΡΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡΠ΄Ρ ΠΏΠ»Π°Π³ΠΈΠ½ Π΄Π»Ρ Jenkins’Π°, ΠΈΡ ΠΌΡΡΡΠ»ΡΠΎΠ½. ΠΠΎ Ρ ΠΏΠΎΡΠ΅ΠΌΡ-ΡΠΎ Π½Π΅ Π»ΡΠ±Π»Ρ ΠΏΠ»Π°Π³ΠΈΠ½Ρ. ΠΡ, ΡΠΎΡΠ½Π΅Π΅, ΠΏΡΠΈΠ±Π΅Π³Π°Ρ ΠΊ Π½ΠΈΠΌ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΡ Π±Π΅Π·ΡΡΡ ΠΎΠ΄Π½ΠΎΡΡΠΈ.
Π Π΅ΡΠ΅ ΠΌΠ½Π΅ ΠΏΡΠΎΡΡΠΎ Π½ΡΠ°Π²ΠΈΡΡΡ ΡΠ°ΡΠΊΠΎΠ²ΡΡΡΡΡ ΠΊΠ°ΠΊΡΡ-Π½ΠΈΠ±ΡΠ΄Ρ Π½ΠΎΠ²ΡΡ Π΄Π»Ρ ΠΌΠ΅Π½Ρ ΡΠ΅ΠΌΡ. Π’Π΅ΠΊΡΡ Π²ΡΡΠ΅ β Π² ΡΠΎΠΌ ΡΠΈΡΠ»Π΅ ΠΈ ΡΠΏΠΎΡΠΎΠ± ΠΏΠΎΠ΄Π΅Π»ΠΈΡΡΡΡ Π½Π°Ρ
ΠΎΠ΄ΠΊΠ°ΠΌΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Ρ ΡΠ΄Π΅Π»Π°Π», ΡΠ΅ΡΠ°Ρ ΠΎΠΏΠΈΡΠ°Π½Π½ΡΡ Π² ΡΠ°ΠΌΠΎΠΌ Π½Π°ΡΠ°Π»Π΅ Π·Π°Π΄Π°ΡΡ. ΠΠΎΠ΄Π΅Π»ΠΈΡΡΡΡ Ρ ΡΠ΅ΠΌΠΈ, ΠΊΡΠΎ, ΠΊΠ°ΠΊ ΠΈ, Π²ΠΎΠ²ΡΠ΅ Π½Π΅ Π»ΡΡΡΠΉ Π²ΠΎΠ»ΠΊ Π² Π΄Π΅Π²ΠΎΠΏΡΠ΅. ΠΡΠ»ΠΈ Ρ
ΠΎΡΡ Π±Ρ ΠΊΠΎΠΌΡ-ΡΠΎ ΠΌΠΎΠΈ Π½Π°Ρ
ΠΎΠ΄ΠΊΠΈ ΠΏΠΎΠΌΠΎΠ³ΡΡ β Π±ΡΠ΄Ρ Π΄ΠΎΠ²ΠΎΠ»Π΅Π½.
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com