ΠΠ΄Π½Π° ΠΎΡ Π½Π°ΠΉ-Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΈΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΊΠΎΡΡΠΎ Π½Π΅ Π΅ Π² Π±Π΅Π·ΠΏΠ»Π°ΡΠ½Π°ΡΠ° Π²Π΅ΡΡΠΈΡ Π½Π° GitLab, Π΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠ° Π΄Π° Π³Π»Π°ΡΡΠ²Π°ΡΠ΅ ΡΡΠ΅ΡΡ Π½ΡΠ»ΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ΡΠΎ, Π·Π° Π΄Π° ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΠ°ΡΠ΅ Π·Π°ΡΠ²ΠΊΠ°ΡΠ° Π·Π° ΡΠ»ΠΈΠ²Π°Π½Π΅ (MR), ΠΊΠ°ΡΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ Π·Π°Π΄ΡΠ»ΠΆΠΈΡΠ΅Π»Π½ΠΈΡ ΠΏΡΠ΅Π³Π»Π΅Π΄ Π½Π° ΠΊΠΎΠ΄Π°.
Π‘Π°ΠΌΠΈ ΡΠ΅ Π½Π°ΠΏΡΠ°Π²ΠΈΠΌ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π½Π°ΡΠ° ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π½ΠΎΡΡ - ΡΠ΅ Π΄Π΅Π°ΠΊΡΠΈΠ²ΠΈΡΠ°ΠΌΠ΅ Merge, Π΄ΠΎΠΊΠ°ΡΠΎ Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΡΠΈ Π½Π΅ Π΄Π°Π΄Π°Ρ βΠΏΠ°Π»Π΅Ρ Π½Π°Π³ΠΎΡΠ΅β Π½Π° MR.
ΠΠ°ΡΠΎ ΠΈΠ·ΠΎΠ±ΡΠΎ Π΅ ΡΠΎΠ²Π°?
ΠΠ°ΡΠ°ΡΠ° ΠΎΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈ Π΄Π° Π·Π°ΠΊΡΠΏΠΈ Π»ΠΈΡΠ΅Π½Π· Π·Π° GitLab. ΠΠΎ ΡΡΠΉ ΠΊΠ°ΡΠΎ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ°ΡΠ° ΡΠ΅ ΠΈΠ·Π²ΡΡΡΠ²Π° Π² Π·Π°ΡΠ²ΠΎΡΠ΅Π½ ΡΠΈΠΊΡΠ» Π±Π΅Π· Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ ΠΈΠ½ΡΠ΅ΡΠ½Π΅Ρ ΠΈ ΠΈΠΌΠ° ΡΡΡΠΈΠΊΡΠ½ΠΎ Π±ΡΠ΄ΠΆΠ΅ΡΠ½ΠΎ ΠΏΠ»Π°Π½ΠΈΡΠ°Π½Π΅, Π·Π°ΠΊΡΠΏΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° ΡΠ°ΠΌΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌΠΈ Π»ΠΈΡΠ΅Π½Π·ΠΈ Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠ°ΡΠ° ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π½ΠΎΡΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΎΡΠ½Π΅ΠΌΠ΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΌΠ΅ΡΠ΅ΡΠΈ ΠΈ ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ°Π±ΠΎΡΠΈΡΠ΅ ΡΠ΅Π³Π°.
Π ΡΠ΅Π·ΡΠ»ΡΠ°Ρ Π½Π° ΡΠΎΠ²Π° ΡΡΡΠ±Π²Π°:
- ΠΈΠ»ΠΈ Π½Π°ΠΏΡΠ»Π½ΠΎ Π·Π°Π±ΡΠ°Π½Π΅ΡΠ΅ ΡΠ»ΠΈΠ²Π°Π½Π΅ΡΠΎ Π² Π·Π°ΡΠΈΡΠ΅Π½ΠΈ ΠΊΠ»ΠΎΠ½ΠΎΠ²Π΅ Π·Π° Π½ΡΠΊΠΎΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΡΠΈ, Π½ΠΎ ΡΠΎΠ³Π°Π²Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΡΠΈΡΠ΅, ΠΊΠΎΠΈΡΠΎ ΠΈΠΌΠ°Ρ ΠΏΡΠ°Π²ΠΎ Π½Π° ΡΠ»ΠΈΠ²Π°Π½Π΅, ΠΏΠΎΠ»ΡΡΠ°Π²Π°Ρ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠΈ ΠΏΡΠΈ ΡΠ»ΠΈΠ²Π°Π½Π΅ Π½Π° MR Π½Π° Π΄ΡΡΠ³ΠΈ Ρ ΠΎΡΠ° ΠΊΠ°ΡΠΎ Π±ΠΎΠ½ΡΡ;
- ΠΈΠ»ΠΈ Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π°Ρ Π΄Π° ΠΏΡΠ°Π²ΠΈΡΠ΅ Π½Π΅ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΠ°Π½ΠΈ ΡΠ»ΠΈΠ²Π°Π½ΠΈΡ Ρ Π²Π°ΡΠΈΡ Π³Π»Π°Π²Π΅Π½ ΠΊΠ»ΠΎΠ½ Π±Π΅Π· ΠΏΡΠ΅Π³Π»Π΅Π΄ Π½Π° ΠΊΠΎΠ΄Π°, Π΄ΠΎΡΠΈ Π°ΠΊΠΎ ΡΠΎΠ²Π° Π΅ Junior, ΠΊΠΎΠΉΡΠΎ ΡΠΎΠΊΡ-ΡΠΎ ΡΠ΅ Π΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΠ» Π²ΡΠ΅ΡΠ°.
ΠΡΡΠ²ΠΎΡΠΎ Π½Π΅ΡΠΎ, ΠΊΠΎΠ΅ΡΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡ , Π±Π΅ΡΠ΅ Π΄Π° ΠΏΠΎΡΡΡΡΡ Π² Google, Π²ΡΡΠ²Π°ΠΉΠΊΠΈ, ΡΠ΅ Π½ΡΠΊΠΎΠΉ Π²Π΅ΡΠ΅ Π΅ ΠΏΡΠ°Π²ΠΈΠ» Π½Π΅ΡΠΎ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ (Π±Π΅Π· Π΄Π° ΠΏΡΠ΅ΡΠΈΠ·ΠΈΡΠ° ΠΊΠΎΠ΄Π°), Π½ΠΎ ΡΠ΅ ΠΎΠΊΠ°Π·Π°, ΡΠ΅ Π²ΡΠ΅ ΠΎΡΠ΅ Π½ΡΠΌΠ° ΡΠ°ΠΊΠ°Π²Π° ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π²ΡΠ² Π²Π΅ΡΡΠΈΡΡΠ° Π½Π° ΠΎΠ±ΡΠ½ΠΎΡΡΡΠ°.
ΠΠ±ΡΠ° ΡΡ Π΅ΠΌΠ° Π½Π° ΡΠ°Π±ΠΎΡΠ°
ΠΠ°ΡΠΎ ΠΏΡΠΈΠΌΠ΅Ρ, Π½Π΅ΠΊΠ° Π½Π°ΡΡΡΠΎΠΈΠΌ ΠΎΠ΄ΠΎΠ±ΡΠ΅Π½ΠΈΡ Π½Π° Π·Π°ΡΠ²ΠΊΠΈ Π·Π° ΡΠ»ΠΈΠ²Π°Π½Π΅ Π² ΡΠ΅ΡΡΠΎΠ²ΠΎ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅
- ΠΠ° ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ ΡΠΎΠΊΠ΅Π½ Π·Π° Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ GitLab API (ΡΡΠ΅Π· Π½Π΅Π³ΠΎ ΡΠ΅ ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π·Π° Π±ΡΠΎΡ Π½Π° Π³Π»Π°ΡΠΎΠ²Π΅ΡΠ΅ Π·Π° ΠΈ ΠΏΡΠΎΡΠΈΠ²)
- ΠΠΎΠ±Π°Π²Π΅ΡΠ΅ ΡΠΎΠΊΠ΅Π½ ΠΊΡΠΌ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈΡΠ΅ Π½Π° GitLab
- ΠΠ΅Π°ΠΊΡΠΈΠ²ΠΈΡΠ°ΠΉΡΠ΅ ΡΠ»ΠΈΠ²Π°Π½Π΅ΡΠΎ, Π°ΠΊΠΎ ΠΈΠΌΠ° Π³ΡΠ΅ΡΠΊΠΈ Π² ΠΏΡΠΎΡΠ΅ΡΠ° (Π°ΠΊΠΎ Π½ΡΠΌΠ° Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ Π³Π»Π°ΡΠΎΠ²Π΅ βΠ·Π°β)
- ΠΠ°ΡΡΡΠΎΠΉΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°ΡΠ° Π½Π° Π³Π»Π°ΡΠ° ΠΊΠ°ΡΠΎ ΡΠ°ΡΡ ΠΎΡ CI/CD ΡΡΡΠ±ΠΎΠΏΡΠΎΠ²ΠΎΠ΄Π°
- Π©Π΅ Π·Π°Π±ΡΠ°Π½ΠΈΠΌ ΠΈΠ·Π²ΡΡΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° Π°Π½Π³Π°ΠΆΠΈΠΌΠ΅Π½ΡΠΈ ΠΊΡΠΌ Π·Π°ΡΠΈΡΠ΅Π½ΠΈ ΠΊΠ»ΠΎΠ½ΠΎΠ²Π΅, Π½ΠΈΠ΅ ΠΏΡΠ°Π²ΠΈΠΌ Π²ΡΠΈΡΠΊΠΈ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ ΡΠ°ΠΌΠΎ ΡΡΠ΅Π· MR
- ΠΠ΅ΠΊΠ° Π΄Π° ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌ ΠΊΠ°ΠΊΠ²ΠΎ ΡΠ΅ Π΅ ΡΠ»ΡΡΠΈΠ»ΠΎ Π² ΠΊΡΠ°ΠΉΠ½Π° ΡΠΌΠ΅ΡΠΊΠ°
1. Π‘ΡΠ·Π΄Π°ΠΉΡΠ΅ ΡΠΎΠΊΠ΅Π½ Π·Π° Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ API
ΠΡΠΈΠ΄Π΅ΡΠ΅ Π½Π° ΠΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ β Π’ΠΎΠΊΠ΅Π½ΠΈ Π·Π° Π΄ΠΎΡΡΡΠΏ ΠΈ Π·Π°ΠΏΠΈΡΠ΅ΡΠ΅ ΡΠΎΠΊΠ΅Π½Π°:
ΠΠΊΠ°ΡΠ½Ρ Π·Π° ΠΏΠΎΠ»ΡΡΠ°Π²Π°Π½Π΅ Π½Π° ΡΠΎΠΊΠ΅Π½Π°
API Π΄ΠΎΡΡΡΠΏΡΡ Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΏΠΎΡΡΠΈ Π²ΡΠΈΡΠΊΠΎ Ρ Π²Π°ΡΠΈΡΠ΅ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ°, ΡΠ°ΠΊΠ° ΡΠ΅ ΠΏΡΠ΅Π΄Π»Π°Π³Π°ΠΌ Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΡΠ΅ ΠΎΡΠ΄Π΅Π»Π΅Π½ Π°ΠΊΠ°ΡΠ½Ρ Π² Gitlab, Π΄Π° ΠΌΡ Π΄Π°Π΄Π΅ΡΠ΅ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π½ΠΈ ΠΏΡΠ°Π²Π° Π·Π° Π²Π°ΡΠΈΡΠ΅ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ° (ΠΊΠ°ΡΠΎ Reporter) ΠΈ Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ ΡΠΎΠΊΠ΅Π½ Π·Π° ΡΠΎΠ·ΠΈ Π°ΠΊΠ°ΡΠ½Ρ.
2. ΠΠΎΠ±Π°Π²Π΅ΡΠ΅ ΡΠΎΠΊΠ΅Π½Π° ΠΊΡΠΌ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈΡΠ΅ Π½Π° Gitlab
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ Π² ΠΏΡΠ΅Π΄ΠΈΡΠ½Π°ΡΠ° ΡΡΡΠΏΠΊΠ° ΠΏΠΎΠ»ΡΡΠΈΡ ΠΌΠ΅ ΡΠΎΠΊΠ΅Π½ QmN2Y0NOUFlfeXhvd21ZS01aQzgK
ΠΡΠ²ΠΎΡΠ΅ΡΠ΅ ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ β CI/CD β ΠΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ β ΠΠΎΠ±Π°Π²ΡΠ½Π΅ Π½Π° ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° β GITLAB_TOKEN_FOR_CI
Π ΡΠ΅Π·ΡΠ»ΡΠ°Ρ Π½Π° ΡΠΎΠ²Π° ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅:
Π’ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΠΏΡΠ°Π²ΠΈ ΠΊΠ°ΠΊΡΠΎ Π² Π΅Π΄Π½ΠΎ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅, ΡΠ°ΠΊΠ° ΠΈ Π² Π³ΡΡΠΏΠ° ΠΎΡ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ°.
3. ΠΠΎΡΡΠ°Π²ΡΠΌΠ΅ Π·Π°Π±ΡΠ°Π½Π° Π½Π° Merge, Π°ΠΊΠΎ Π½Π΅ ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈ ΠΎΠ΄ΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ Π½Π° ΠΊΠΎΠ»Π΅Π³ΠΈΡΠ΅ ΡΠ»Π΅Π΄ ΠΏΡΠ΅Π³Π»Π΅Π΄Π° Π½Π° ΠΊΠΎΠ΄Π°
Π Π½Π°ΡΠΈΡ ΡΠ»ΡΡΠ°ΠΉ Π·Π°Π±ΡΠ°Π½Π°ΡΠ° Π·Π° ΡΠ»ΠΈΠ²Π°Π½Π΅ ΡΠ΅ Π±ΡΠ΄Π΅, ΡΠ΅ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅ΡΡΡ Π·Π° ΡΠ³Π»ΠΎΠ±ΡΠ²Π°Π½Π΅ ΡΠ΅ Π²ΡΡΠ½Π΅ Π³ΡΠ΅ΡΠΊΠ°, Π°ΠΊΠΎ Π½ΡΠΌΠ° Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ Π³Π»Π°ΡΠΎΠ²Π΅.
ΠΡΠΈΠ΄Π΅ΡΠ΅ Π² ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ β ΠΠ±ΡΠΈ β ΠΠ°ΡΠ²ΠΊΠΈ Π·Π° ΡΠ»ΠΈΠ²Π°Π½Π΅ β ΠΡΠΎΠ²Π΅ΡΠΊΠΈ Π·Π° ΡΠ»ΠΈΠ²Π°Π½Π΅ ΠΈ Π°ΠΊΡΠΈΠ²ΠΈΡΠ°ΠΉΡΠ΅ ΠΎΠΏΡΠΈΡΡΠ° Π‘Π³Π»ΠΎΠ±ΠΈΡΠ΅Π»Π½ΠΈΡΠ΅ Π»ΠΈΠ½ΠΈΠΈ ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ°Π±ΠΎΡΡΡ ΡΡΠΏΠ΅ΡΠ½ΠΎ.
4. ΠΠ°ΡΡΡΠΎΠΉΡΠ΅ ΡΡΡΠ±ΠΎΠΏΡΠΎΠ²ΠΎΠ΄Π°
ΠΠΊΠΎ Π²ΡΠ΅ ΠΎΡΠ΅ Π½Π΅ ΡΡΠ΅ Π½Π°ΠΏΡΠ°Π²ΠΈΠ»ΠΈ CI/CD ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ Π·Π° Π²Π°ΡΠ΅ΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
Π‘ΡΠ·Π΄Π°ΠΉΡΠ΅ ΡΠ°ΠΉΠ» Π² ΠΊΠΎΡΠ΅Π½Π° Π½Π° Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ΡΠΎ .gitlab-ci.yml Ρ ΠΏΡΠΎΡΡΠΎ ΡΡΠ΄ΡΡΠΆΠ°Π½ΠΈΠ΅:
stages:
- build
- test
variables:
NEED_VOTES: 1
include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"
run-myapp:
stage: build
script: echo "Hello world"
ΠΡΠ΄Π΅Π»Π½ΠΎ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ Π·Π° CI/CD ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ
ΠΠΈΡ
ΠΏΡΠ΅ΠΏΠΎΡΡΡΠ°Π» Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΎΡΠ΄Π΅Π»Π½ΠΎ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅, ΠΊΡΠ΄Π΅ΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΡΠ΅ ΡΠ°ΠΉΠ» myapp.gitlab-ci.yml, Π·Π° Π΄Π° Π½Π°ΡΡΡΠΎΠΈΡΠ΅ ΡΡΡΠ±ΠΎΠΏΡΠΎΠ²ΠΎΠ΄Π°. ΠΠΎ ΡΠΎΠ·ΠΈ Π½Π°ΡΠΈΠ½ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠΎ-Π΄ΠΎΠ±ΡΠ΅ Π΄Π° ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΠ°ΡΠ΅ Π΄ΠΎΡΡΡΠΏΠ° Π½Π° ΡΡΠ°ΡΡΠ½ΠΈΡΠΈΡΠ΅, ΠΊΠΎΠΈΡΠΎ ΠΌΠΎΠ³Π°Ρ Π΄Π° ΠΏΡΠΎΠΌΠ΅Π½ΡΡ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅ΡΠ° Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ ΠΈ Π΄Π° ΠΏΠΎΠ»ΡΡΠ°Ρ ΡΠΎΠΊΠ΅Π½ Π·Π° Π΄ΠΎΡΡΡΠΏ.
ΠΠ΅ΡΡΠΎΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Π½Π° Π½ΠΎΠ²ΠΈΡ ΡΡΡΠ±ΠΎΠΏΡΠΎΠ²ΠΎΠ΄Π΅Π½ ΡΠ°ΠΉΠ» ΡΠ΅ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ ΠΏΠΎΡΠΎΡΠ΅Π½ΠΎ, ΠΊΠ°ΡΠΎ ΠΎΡΠΈΠ΄Π΅ΡΠ΅ Π² Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ΡΠΎ Π½Π° myapp - ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ - CI / CD - Π‘Π³Π»ΠΎΠ±ΡΠ΅ΠΌΠΈ Π»ΠΈΠ½ΠΈΠΈ - ΠΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ CI ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π΅Π½ ΠΏΡΡ - ΠΏΠΎΡΠΎΡΠ΅ΡΠ΅ Π½ΠΎΠ² ΡΠ°ΠΉΠ», Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci
Π‘ΡΠ²Π΅Ρ: ΠΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡΠ΅ Π»ΠΈΠ½ΡΠ΅Ρ, Π·Π° Π΄Π° ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ Π² GitLab CI ΡΠ°ΠΉΠ»ΠΎΠ²Π΅
ΠΠΎΡΠΈ ΠΈ Π΄Π° ΡΠ°Π±ΠΎΡΠΈΡΠ΅ ΡΠ°ΠΌΠΈ, ΡΠ°Π±ΠΎΡΠ°ΡΠ° ΡΡΠ΅Π· MR ΡΠ΅ Π²ΠΈ Π±ΡΠ΄Π΅ Π΄ΠΎΠ±ΡΡ ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ, ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π°ΠΉΠΊΠΈ Π²ΡΠΈΡΠΊΠΈΡΠ΅ ΡΠΈ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ Π² ΡΡΡΠ±ΠΎΠΏΡΠΎΠ²ΠΎΠ΄Π½ΠΈΡΠ΅ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ ΠΏΡΠ΅Π· Π»ΠΈΠ½ΡΠ΅ΡΠ°. ΠΠΊΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ Π³ΡΠ΅ΡΠΊΠ° Π² ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ° Π½Π° YAML ΡΠ°ΠΉΠ»Π°, ΡΠΎΠ²Π° Π½ΡΠΌΠ° Π΄Π° Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈ Π΄Π° ΠΏΡΠ΅ΠΊΡΡΠ½Π΅ΡΠ΅ ΡΠ°Π±ΠΎΡΠ½ΠΈΡ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ, Π° ΠΏΡΠΎΡΡΠΎ ΡΠ΅ Π±Π»ΠΎΠΊΠΈΡΠ° Merge.
ΠΡΠΈΠΌΠ΅Ρ Π·Π° ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΈ Ρ Π»ΠΈΠ½ΡΠ΅ΡΠΈ, ΠΊΠΎΠΈΡΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π²Π³ΡΠ°Π΄ΠΈΡΠ΅ Π²ΡΠ² Π²Π°ΡΠΈΡ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ:
Π ΠΏΡΠΈΠΌΠ΅Ρ Π·Π° Π΅ΡΠ°ΠΏΠ° Π½Π° Π²Π°Π»ΠΈΠ΄ΠΈΡΠ°Π½Π΅:
stages:
- lint
lint:
stage: lint
image: sebiwi/gitlab-ci-validate:1.3.0
variables:
GITLAB_HOST: https://gitlab.com
script:
- CI_FILES=(./*.yml)
- for f in "${CI_FILES[@]}"; do
gitlab-ci-validate $f;
done;
ΠΡΡΠ°Π²Π° Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡΠ΅ Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡΠ° ΠΊΡΠΌ Π²Π°ΡΠΈΡ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ, Π·Π° Π΄Π° ΡΠ°Π±ΠΎΡΠΈ:
stages:
- test
variables:
NEED_VOTES: 1
include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"
ΠΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°ΡΠ° NEED_VOTES ΠΎΠΏΡΠ΅Π΄Π΅Π»Ρ ΠΊΠΎΠ»ΠΊΠΎ "ΠΏΠ°Π»Π΅ΡΠ° Π½Π°Π³ΠΎΡΠ΅" MR ΡΡΡΠ±Π²Π° Π΄Π° ΠΈΠΌΠ°, Π·Π° Π΄Π° Π΅ Π½Π°Π»ΠΈΡΠ½ΠΎ ΡΠ»ΠΈΠ²Π°Π½Π΅ΡΠΎ. Π‘ΡΠΎΠΉΠ½ΠΎΡΡ Π΅Π΄Π½ΠΎ ΠΎΠ·Π½Π°ΡΠ°Π²Π°, ΡΠ΅ Π²ΠΈΠ΅ ββΡΠ°ΠΌΠΈ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΎΠ΄ΠΎΠ±ΡΠΈΡΠ΅ Π²Π°ΡΠΈΡ MR, ΠΊΠ°ΡΠΎ Π³ΠΎ βΡ
Π°ΡΠ΅ΡΠ°ΡΠ΅β.
include Π²ΠΊΠ»ΡΡΠ²Π° ΡΠ΅ΡΡΠΎΠ²ΠΈΡ Π΅ΡΠ°ΠΏ, ΠΊΠΎΠΉΡΠΎ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° Π±ΡΠΎΡ Π½Π° "Ρ Π°ΡΠ΅ΡΠ²Π°Π½ΠΈΡΡΠ°".
ΠΠ°ΠΉ-ΠΏΡΠΎΡΡΠΈΡΡ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ myapp.gitlab-ci.yml ΠΊΠ°ΡΠΎ ΠΏΡΠΈΠΌΠ΅Ρ
stages:
- build
- test
variables:
NEED_VOTES: 0
include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"
run-myapp:
stage: build
image: openjdk
script:
- echo CI_MERGE_REQUEST_TARGET_BRANCH_NAME $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
- java HelloWorld.java
Π‘ΡΠ΄ΡΡΠΆΠ°Π½ΠΈΠ΅ Π½Π° check-approve.gitlab-ci.yml
ci-mr:
stage: test
script:
- echo ${CI_API_V4_URL}
- echo "CI_PROJECT_ID ${CI_PROJECT_ID}"
- echo "CI_COMMIT_SHA ${CI_COMMIT_SHA}"
- "export MR_ID=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .id else {} end" | grep --invert-match {})"
- "export MR_TITLE=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .title else {} end" | grep --invert-match {})"
- "export MR_WIP=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .work_in_progress else {} end" | grep --invert-match {})"
- "export MR_UPVOTES=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .upvotes else {} end" | grep --invert-match {})"
- "export MR_DOWNVOTES=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .downvotes else {} end" | grep --invert-match {})"
- MR_VOTES=$(expr ${MR_UPVOTES} - ${MR_DOWNVOTES})
- NEED_VOTES_REAL=${NEED_VOTES:-1}
- echo "MR_ID ${MR_ID} MR_TITLE ${MR_TITLE} MR_WIP ${MR_WIP} MR_UPVOTES ${MR_UPVOTES} MR_DOWNVOTES ${MR_DOWNVOTES}"
- echo "MR_VOTES ${MR_VOTES} Up vote = 1, down vote = -1, MR OK if votes >=${NEED_VOTES_REAL}"
- if [ "${MR_VOTES}" -ge "$(expr ${NEED_VOTES_REAL})" ];
then
echo "MR OK";
else
echo "MR ERROR Need more votes";
exit 1;
fi
image: laptevss/gitlab-api-util
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^release/.*$/'
ΠΠ°ΡΡΠ΅ΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ Π·Π° ΡΠΎΠ²Π° ΠΊΠ°ΠΊΠ²ΠΎ ΡΠ΅ ΡΠ»ΡΡΠ²Π° ΠΏΡΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°:
- Π·Π°Π΄Π°Π΄Π΅Π½ΠΎ Π΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ΡΠΎ, ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°ΡΠ° ΡΠ΅ Π±ΡΠ΄Π΅ ΡΠ°ΠΌΠΎ ΠΏΡΠΈ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° MR Π² master ΠΈΠ»ΠΈ release /* ΠΊΠ»ΠΎΠ½ΠΎΠ²Π΅
- ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ GitLab API, Π²Π·Π΅ΠΌΠ΅ΡΠ΅ Π±ΡΠΎΡ Π½Π° βΡ Π°ΡΠ΅ΡΠ²Π°Π½ΠΈΡΡΠ°β ΠΈ βΠ½Π΅Ρ Π°ΡΠ΅ΡΠ²Π°Π½ΠΈΡΡΠ°β
- ΠΈΠ·ΡΠΈΡΠ»Π΅ΡΠ΅ ΡΠ°Π·Π»ΠΈΠΊΠ°ΡΠ° ΠΌΠ΅ΠΆΠ΄Ρ ΠΏΠΎΠ»ΠΎΠΆΠΈΡΠ΅Π»Π½ΠΈΡΠ΅ ΠΈ ΠΎΡΡΠΈΡΠ°ΡΠ΅Π»Π½ΠΈΡΠ΅ ΠΎΡΠ³ΠΎΠ²ΠΎΡΠΈ
- Π°ΠΊΠΎ ΡΠ°Π·Π»ΠΈΠΊΠ°ΡΠ° Π΅ ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠ° ΠΎΡ ΡΡΠΎΠΉΠ½ΠΎΡΡΡΠ°, ΠΊΠΎΡΡΠΎ ΡΠΌΠ΅ Π·Π°Π΄Π°Π»ΠΈ Π² NEED_VOTES, ΡΠΎΠ³Π°Π²Π° Π±Π»ΠΎΠΊΠΈΡΠ°ΠΌΠ΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠ° Π·Π° ΡΠ»ΠΈΠ²Π°Π½Π΅
5. ΠΠ΅Π°ΠΊΡΠΈΠ²ΠΈΡΠ°ΠΉΡΠ΅ Π°Π½Π³Π°ΠΆΠΈΠΌΠ΅Π½ΡΠΈΡΠ΅ ΠΊΡΠΌ Π·Π°ΡΠΈΡΠ΅Π½ΠΈ ΠΊΠ»ΠΎΠ½ΠΎΠ²Π΅
ΠΠΈΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠΌΠ΅ ΠΊΠ»ΠΎΠ½ΠΎΠ²Π΅ΡΠ΅, Π·Π° ΠΊΠΎΠΈΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° ΠΈΠ·Π²ΡΡΡΠΈΠΌ ΠΏΡΠ΅Π³Π»Π΅Π΄ Π½Π° ΠΊΠΎΠ΄Π°, ΠΈ ΠΏΠΎΡΠΎΡΠ²Π°ΠΌΠ΅, ΡΠ΅ Ρ ΡΡΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΡΠ°Π±ΠΎΡΠΈ ΡΠ°ΠΌΠΎ ΡΡΠ΅Π· MR.
ΠΠ° Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΡΠΎΠ²Π°, ΠΎΡΠΈΠ΄Π΅ΡΠ΅ Π½Π° ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ β Π₯ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ β ΠΠ°ΡΠΈΡΠ΅Π½ΠΈ ΠΊΠ»ΠΎΠ½ΠΎΠ²Π΅:
6. ΠΡΠΎΠ²Π΅ΡΠΊΠ°
ΠΠ°Π΄Π°ΠΉΡΠ΅ NEED_VOTES: 0
ΠΡΠ°Π²ΠΈΠΌ MR ΠΈ ΠΏΠΎΡΡΠ°Π²ΡΠΌΠ΅ "dislike".
Π ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈΡΠ΅ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅:
Π‘Π΅Π³Π° ΠΏΠΎΡΡΠ°Π²Π΅ΡΠ΅ βΡ
Π°ΡΠ΅ΡΠ²Π°ΠΌβ ΠΈ ΠΈΠ·ΠΏΡΠ»Π½Π΅ΡΠ΅ ΠΏΠΎΠ²ΡΠΎΡΠ½Π° ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°:
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com