เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”เปƒเบ™ Gitlab CE: เบ–เป‰เบฒเบšเปเปˆเบกเบตเบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™, เปเบ•เปˆเบ‚เป‰เบญเบเบเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™

เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”เปƒเบ™ Gitlab CE: เบ–เป‰เบฒเบšเปเปˆเบกเบตเบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™, เปเบ•เปˆเบ‚เป‰เบญเบเบเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™

เบซเบ™เบถเปˆเบ‡เปƒเบ™เบซเบ™เป‰เบฒเบ—เบตเปˆเบกเบตเบ„เบงเบฒเบกเบˆเปเบฒเป€เบ›เบฑเบ™เบ—เบตเปˆเบชเบธเบ”, เบ—เบตเปˆเบšเปเปˆเบกเบตเบขเบนเปˆเปƒเบ™เบชเบฐเบšเบฑเบšเบŸเบฃเบตเบ‚เบญเบ‡ GitLab, เปเบกเปˆเบ™เบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เปƒเบ™เบเบฒเบ™เบฅเบปเบ‡เบ„เบฐเปเบ™เบ™เบชเบฝเบ‡เบ•เปเปˆเบเบฑเบšเบเบฒเบ™ nullification repository เปเบฅเบฐเบเบฒเบ™เบ„เบงเบšเบ„เบธเบกเบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™ (MR), เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”เบšเบฑเบ‡เบ„เบฑเบš.

เปƒเบซเป‰เป€เบฎเบปเบฒเป€เบฎเบฑเบ”เบซเบ™เป‰เบฒเบ—เบตเปˆเบ•เปเบฒเปˆเบชเบธเบ”เบ—เบตเปˆเบ•เบปเบงเป€เบฎเบปเบฒเป€เบญเบ‡ - เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบซเป‰เบฒเบก Merge เบˆเบปเบ™เบเปˆเบงเบฒเบ™เบฑเบเบžเบฑเบ”เบ—เบฐเบ™เบฒเบซเบผเบฒเบเบ„เบปเบ™เบเบปเบเป‚เบ›เป‰ MR.

เป€เบ›เบฑเบ™เบซเบเบฑเบ‡เบญเบฑเบ™เบ™เบตเป‰เบˆเบถเปˆเบ‡เบˆเปเบฒเป€เบ›เบฑเบ™?

เบญเบปเบ‡เบเบฒเบ™เบˆเบฑเบ”เบ•เบฑเป‰เบ‡เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เบŠเบทเป‰เปƒเบšเบญเบฐเบ™เบธเบเบฒเบ” GitLab เป„เบ”เป‰เบขเปˆเบฒเบ‡เบ‡เปˆเบฒเบเบ”เบฒเบ. เปเบ•เปˆ, เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบงเปˆเบฒเบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒเปเบกเปˆเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบขเบนเปˆเปƒเบ™เบงเบปเบ‡เบ›เบดเบ”เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบญเบดเบ™เป€เบ•เบตเป€เบ™เบฑเบ”, เปเบฅเบฐเบกเบตเบเบฒเบ™เบงเบฒเบ‡เปเบœเบ™เบ‡เบปเบšเบ›เบฐเบกเบฒเบ™เบขเปˆเบฒเบ‡เป€เบ‚เบฑเป‰เบกเบ‡เบงเบ”, เบเบฒเบ™เบŠเบทเป‰เปƒเบšเบญเบฐเบ™เบธเบเบฒเบ”เบ„เบธเป‰เบกเบ„เบญเบ‡เบ•เบปเบ™เป€เบญเบ‡เบ—เบตเปˆเบกเบตเบซเบ™เป‰เบฒเบ—เบตเปˆเบ—เบตเปˆเบˆเปเบฒเป€เบ›เบฑเบ™เบชเบฒเบกเบฒเบ”เบฅเบฒเบเป„เบ›เป€เบ›เบฑเบ™เป€เบงเบฅเบฒเบซเบผเบฒเบเป€เบ”เบทเบญเบ™, เปเบ•เปˆเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบ•เป‰เบญเบ‡เป„เบ”เป‰เป€เบฎเบฑเบ”เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™.

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบ—เปˆเบฒเบ™เบˆเบฐเบ•เป‰เบญเบ‡:

  • เบซเบผเบทเบซเป‰เบฒเบกเบขเปˆเบฒเบ‡เบชเบปเบกเบšเบนเบ™ Merge เปƒเบ™เบชเบฒเบ‚เบฒเบ—เบตเปˆเป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™เบ›เบปเบเบ›เป‰เบญเบ‡เบชเปเบฒเบฅเบฑเบšเบ™เบฑเบเบžเบฑเบ”เบ—เบฐเบ™เบฒเบšเบฒเบ‡เบ„เบปเบ™, เปเบ•เปˆเบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบœเบนเป‰เบžเบฑเบ”เบ—เบฐเบ™เบฒเบ—เบตเปˆเบกเบตเบชเบดเบ”เบ—เบตเปˆเบˆเบฐ Merge เป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™เบ‚เบฑเบ”เปเบเป‰เบ‡เปƒเบ™เป€เบงเบฅเบฒเบ—เบตเปˆเบฅเบงเบก MRs เบ‚เบญเบ‡เบœเบนเป‰เบญเบทเปˆเบ™เป€เบ›เบฑเบ™เป‚เบšเบ™เบฑเบ”;
  • เบซเบผเบทเปƒเบซเป‰เป‚เบญเบเบฒเบ”เบ—เบตเปˆเบˆเบฐเป€เบฎเบฑเบ”เปƒเบซเป‰เบเบฒเบ™เบœเบฐเบชเบปเบกเบœเบฐเบชเบฒเบ™เบ—เบตเปˆเบšเปเปˆเบชเบฒเบกเบฒเบ”เบ„เบงเบšเบ„เบธเบกเป„เบ”เป‰เบเบฑเบšเบชเบฒเบ‚เบฒเบ•เบปเป‰เบ™เบชเบฐเบšเบฑเบšเบ‚เบญเบ‡เบ—เปˆเบฒเบ™เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”, เป€เบ–เบดเบ‡เปเบกเปˆเบ™เบงเปˆเบฒเบกเบฑเบ™เป€เบ›เบฑเบ™ Junior, เบœเบนเป‰เบ—เบตเปˆเบ–เบทเบเบˆเป‰เบฒเบ‡เปƒเบ™เบกเบทเป‰เบงเบฒเบ™เบ™เบตเป‰.

เบชเบดเปˆเบ‡เบ—เปเบฒเบญเบดเบ”เบ—เบตเปˆเบ‚เป‰เบญเบเป€เบฎเบฑเบ”เปเบกเปˆเบ™ Google, เป€เบŠเบทเปˆเบญเบงเปˆเบฒเบšเบฒเบ‡เบ„เบปเบ™เป„เบ”เป‰เป€เบฎเบฑเบ”เบšเบฒเบ‡เบชเบดเปˆเบ‡เบšเบฒเบ‡เบขเปˆเบฒเบ‡เบ—เบตเปˆเบ„เป‰เบฒเบเบ„เบทเบเบฑเบ™เปเบฅเป‰เบง (เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบ”เบฑเบ”เปเบ›เบ‡เบฅเบฐเบซเบฑเบ”), เปเบ•เปˆเบกเบฑเบ™เบ›เบฒเบเบปเบ”เบงเปˆเบฒเบšเปเปˆเบกเบตเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบ”เบฑเปˆเบ‡เบเปˆเบฒเบงเปƒเบ™เบชเบฐเบšเบฑเบšเบŠเบธเบกเบŠเบปเบ™เป€เบ—เบทเปˆเบญ.

เป‚เบ„เบ‡โ€‹เบเบฒเบ™โ€‹เบ—เบปเปˆเบงโ€‹เป„เบ›โ€‹เบ‚เบญเบ‡โ€‹เบเบฒเบ™โ€‹เป€เบฎเบฑเบ”โ€‹เบงเบฝเบโ€‹

เบ•เบปเบงเบขเปˆเบฒเบ‡, เปƒเบซเป‰เป€เบฎเบปเบฒเบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบฎเบงเบกเบขเบนเปˆเปƒเบ™เบšเปˆเบญเบ™เป€เบเบฑเบšเบ‚เปเป‰เบกเบนเบ™เบเบฒเบ™เบ—เบปเบ”เบชเบญเบš myapp:

  1. เปƒเบซเป‰เบชเป‰เบฒเบ‡ token เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡ GitLab API (เบœเปˆเบฒเบ™เบกเบฑเบ™เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป„เบ”เป‰เบฎเบฑเบšเบ‚เปเป‰เบกเบนเบ™เบเปˆเบฝเบงเบเบฑเบšเบˆเปเบฒเบ™เบงเบ™เบ‚เบญเบ‡เบเบฒเบ™เบฅเบปเบ‡เบ„เบฐเปเบ™เบ™เบชเบฝเบ‡ "เบชเปเบฒเบฅเบฑเบš" เปเบฅเบฐ "เบ•เปเปˆ")
  2. เปƒเบซเป‰เป€เบžเบตเปˆเบก token เปƒเบซเป‰เบเบฑเบšเบ•เบปเบงเปเบ› GitLab
  3. เปƒเบซเป‰เบ›เบดเบ”เบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™เปƒเบ™เบเปเบฅเบฐเบ™เบตเป€เบเบตเบ”เบ„เบงเบฒเบกเบœเบดเบ”เบžเบฒเบ”เปƒเบ™เบ—เปเปˆ (เบ–เป‰เบฒเบšเปเปˆเบกเบตเบ„เบฐเปเบ™เบ™ upvotes เบžเบฝเบ‡เบžเป)
  4. เบกเบฒเบ•เบฑเป‰เบ‡เบเบฒเบ™เบเบงเบ”เบชเบญเบšเบ„เบฐเปเบ™เบ™เบชเบฝเบ‡เป€เบ›เบฑเบ™เบชเปˆเบงเบ™เปœเบถเปˆเบ‡เบ‚เบญเบ‡เบ—เปเปˆ CI/CD
  5. เบžเบงเบเป€เบฎเบปเบฒเบซเป‰เบฒเบกเบเบฒเบ™เป€เบฎเบฑเบ”เบชเบฑเบ™เบเบฒเบเบฑเบšเบชเบฒเบ‚เบฒเบ—เบตเปˆเบ–เบทเบเบ›เบปเบเบ›เป‰เบญเบ‡; เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบ—เบฑเบ‡เบซเบกเบปเบ”เปเบกเปˆเบ™เป€เบฎเบฑเบ”เบœเปˆเบฒเบ™ MR เป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™
  6. เปƒเบซเป‰เบเบงเบ”เป€เบšเบดเปˆเบ‡เบชเบดเปˆเบ‡เบ—เบตเปˆเป€เบเบตเบ”เบ‚เบถเป‰เบ™เปƒเบ™เบ—เบตเปˆเบชเบธเบ”

1. เบชเป‰เบฒเบ‡ token เป€เบžเบทเปˆเบญเป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡ API

เป„เบ›เบ—เบตเปˆเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบœเบนเป‰เปƒเบŠเป‰ โ†’ Access Token เปเบฅเบฐเบ‚เบฝเบ™เป‚เบ—เป€เบ„เบฑเบ™เบฅเบปเบ‡:

เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”เปƒเบ™ Gitlab CE: เบ–เป‰เบฒเบšเปเปˆเบกเบตเบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™, เปเบ•เปˆเบ‚เป‰เบญเบเบเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™

เบšเบฑเบ™เบŠเบตเบ—เบตเปˆเบˆเบฐเป„เบ”เป‰เบฎเบฑเบšเป‚เบ—เป€เบ„เบฑเบ™
เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡ API เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบ—เปˆเบฒเบ™เป€เบฎเบฑเบ”เป€เบเบทเบญเบšเบ—เบธเบเบขเปˆเบฒเบ‡เบเบฑเบš repositories เบ‚เบญเบ‡เบ—เปˆเบฒเบ™, เบชเบฐเบ™เบฑเป‰เบ™เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเปเบ™เบฐเบ™เปเบฒเปƒเบซเป‰เบชเป‰เบฒเบ‡เบšเบฑเบ™เบŠเบต Gitlab เปเบเบเบ•เปˆเบฒเบ‡เบซเบฒเบ, เปƒเบซเป‰เบกเบฑเบ™เบชเบดเบ”เบ—เบดเบซเบ™เป‰เบญเบเบ—เบตเปˆเบชเบธเบ”เบเบฑเบš repositories เบ‚เบญเบ‡เบ—เปˆเบฒเบ™ (เป€เบŠเบฑเปˆเบ™: Reporter) เปเบฅเบฐเป„เบ”เป‰เบฎเบฑเบš token เบชเปเบฒเบฅเบฑเบšเบšเบฑเบ™เบŠเบตเบ™เบฑเป‰เบ™.

2. เป€เบžเบตเปˆเบก token เบเบฑเบšเบ•เบปเบงเปเบ› Gitlab

เบ•เบปเบงเบขเปˆเบฒเบ‡, เปƒเบ™เบ‚เบฑเป‰เบ™เบ•เบญเบ™เบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒเบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบฎเบฑเบš token QmN2Y0NOUFlfeXhvd21ZS01aQzgK

เป€เบ›เบตเบ”เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ โ†’ CI/CD โ†’ เบ•เบปเบงเปเบ› โ†’ เป€เบžเบตเปˆเบกเบ•เบปเบงเปเบ› โ†’ GITLAB_TOKEN_FOR_CI

เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”เปƒเบ™ Gitlab CE: เบ–เป‰เบฒเบšเปเปˆเบกเบตเบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™, เปเบ•เปˆเบ‚เป‰เบญเบเบเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบฎเบฑเบš:

เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”เปƒเบ™ Gitlab CE: เบ–เป‰เบฒเบšเปเปˆเบกเบตเบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™, เปเบ•เปˆเบ‚เป‰เบญเบเบเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™

เบ™เบตเป‰เบชเบฒเบกเบฒเบ”เป€เบฎเบฑเบ”เป„เบ”เป‰เบ—เบฑเบ‡เปƒเบ™เบซเบ™เบถเปˆเบ‡ repository เบซเบผเบทเปƒเบ™เบเบธเปˆเบกเบ‚เบญเบ‡ repositories.

3. เบžเบงเบเป€เบฎเบปเบฒเบงเบฒเบ‡เบ‚เปเป‰เบซเป‰เบฒเบกเบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™ Merge เบ–เป‰เบฒเบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบ‚เบญเบ‡เป€เบžเบทเปˆเบญเบ™เบฎเปˆเบงเบกเบ‡เบฒเบ™เบšเปเปˆเป„เบ”เป‰เบฎเบฑเบšเบซเบผเบฑเบ‡เบˆเบฒเบเบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบ„เบทเบ™เบฅเบฐเบซเบฑเบ”.

เปƒเบ™โ€‹เบเปโ€‹เบฅเบฐโ€‹เบ™เบตโ€‹เบ‚เบญเบ‡โ€‹เบžเบงเบโ€‹เป€เบฎเบปเบฒโ€‹, เบ‚เปเป‰โ€‹เบซเป‰เบฒเบกโ€‹เบเปˆเบฝเบงโ€‹เบเบฑเบšโ€‹เบเบฒเบ™ Merge เปเบกเปˆเบ™โ€‹เบงเปˆเบฒโ€‹เบ—เปเปˆโ€‹เบเบฒเบ™โ€‹เบ›เบฐโ€‹เบเบญเบšโ€‹เบˆเบฐโ€‹เบเบฑเบšโ€‹เบ„เบทเบ™โ€‹เบกเบฒโ€‹เบ„เบงเบฒเบกโ€‹เบœเบดเบ”โ€‹เบžเบฒเบ”โ€‹เบ–เป‰เบฒโ€‹เบซเบฒเบโ€‹เบงเปˆเบฒโ€‹เบšเปเปˆโ€‹เบกเบตโ€‹เบ„เบฐโ€‹เปเบ™เบ™โ€‹เบชเบฝเบ‡โ€‹เบžเบฝเบ‡โ€‹เบžเปโ€‹.

เป„เบ›โ€‹เบ—เบตเปˆ Settings โ†’ General โ†’ Merge Requests โ†’ Merge Checks เปเบฅเบฐโ€‹เป€เบ›เบตเบ”โ€‹เปƒเบŠเป‰โ€‹เบ‡เบฒเบ™โ€‹เบ—เบฒเบ‡โ€‹เป€เบฅเบทเบญเบโ€‹เบ‚เบญเบ‡โ€‹เบชเบฒเบ Assembly เบ•เป‰เบญเบ‡โ€‹เบชเปเบฒโ€‹เป€เบฅเบฑเบ”โ€‹เบขเปˆเบฒเบ‡โ€‹เบชเปเบฒโ€‹เป€เบฅเบฑเบ”โ€‹เบœเบปเบ™โ€‹.

เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”เปƒเบ™ Gitlab CE: เบ–เป‰เบฒเบšเปเปˆเบกเบตเบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™, เปเบ•เปˆเบ‚เป‰เบญเบเบเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™

4. เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ—เปเปˆ

เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบเบฑเบ‡เบšเปเปˆเป„เบ”เป‰เบชเป‰เบฒเบ‡เบ—เปเปˆ CI/CD เบชเปเบฒเบฅเบฑเบšเบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบเบ‚เบญเบ‡เบ—เปˆเบฒเบ™
เบชเป‰เบฒเบ‡เป„เบŸเบฅเปŒเบขเบนเปˆเปƒเบ™เบฎเบฒเบเบ‚เบญเบ‡ repository .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 เป€เบžเบทเปˆเบญเบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ—เปเปˆ. เบงเบดเบ—เบตเบ™เบตเป‰เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ„เบงเบšเบ„เบธเบกเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบ‚เบญเบ‡เบœเบนเป‰เป€เบ‚เบปเป‰เบฒเบฎเปˆเบงเบกเป„เบ”เป‰เบ”เบตเบเบงเปˆเบฒเบ—เบตเปˆเบชเบฒเบกเบฒเบ”เบ›เปˆเบฝเบ™เบ—เปเปˆเบเปเปˆเบชเป‰เบฒเบ‡เปเบฅเบฐเป„เบ”เป‰เบฎเบฑเบš token เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡.

เบชเบฐเบ–เบฒเบ™เบ—เบตเปˆเบ‚เบญเบ‡เป„เบŸเบฅเปŒเบ—เปเปˆเปƒเบซเบกเปˆเบˆเบฐเบ•เป‰เบญเบ‡เบ–เบทเบเบเปเบฒเบ™เบปเบ”เป‚เบ”เบเบเบฒเบ™เป„เบ›เบ—เบตเปˆ myapp repository - เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ - CI/CD - เป€เบชเบฑเป‰เบ™เบชเบฐเบžเบฒเปเบซเปˆเบ‡ - เป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ CI Custom - เบฅเบฐเบšเบธเป„เบŸเบฅเปŒเปƒเบซเบกเปˆ, e.g. myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci

เป€เบ„เบฑเบ”เบฅเบฑเบš: เปƒเบŠเป‰ linter เป€เบžเบทเปˆเบญเบ›เปˆเบฝเบ™เปเบ›เบ‡เป„เบŸเบฅเปŒ GitLab CI
เป€เบ–เบดเบ‡เปเบกเปˆเบ™เบงเปˆเบฒเบ—เปˆเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบ„เบปเบ™เบ”เบฝเบง, เบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบœเปˆเบฒเบ™ MR เบˆเบฐเป€เบ›เบฑเบ™เบเบฒเบ™เบŠเปˆเบงเบเป€เบซเบผเบทเบญเบ—เบตเปˆเบ”เบต, เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบ—เบฑเบ‡เบซเบกเบปเบ”เบ‚เบญเบ‡เบ—เปˆเบฒเบ™เบเบฑเบšเป„เบŸเบฅเปŒเบ—เปเปˆเบœเปˆเบฒเบ™ linter. เบ–เป‰เบฒเบ—เปˆเบฒเบ™เป€เบฎเบฑเบ”เบœเบดเบ”เบžเบฒเบ”เปƒเบ™ syntax เบ‚เบญเบ‡เป„เบŸเบฅเปŒ YAML, เบกเบฑเบ™เบˆเบฐเบšเปเปˆเบ—เปเบฒเบฅเบฒเบเบ—เปเปˆเบเบฒเบ™เบœเบฐเบฅเบดเบ”เบ‚เบญเบ‡เบ—เปˆเบฒเบ™, เปเบ•เปˆเบžเบฝเบ‡เปเบ•เปˆเบˆเบฐเบ‚เบฑเบ”เบ‚เบงเบฒเบ‡เบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™.

เบ•เบปเบงเบขเปˆเบฒเบ‡เบ‚เบญเบ‡เบ–เบฑเบ‡เบ—เบตเปˆเบกเบต linters เบ—เบตเปˆเบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบชเป‰เบฒเบ‡เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบ—เปเปˆเบ‚เบญเบ‡เบ—เปˆเบฒเบ™:

hub.docker.com/r/gableroux/gitlab-ci-lint
hub.docker.com/r/sebiwi/gitlab-ci-validate

เปเบฅเบฐเบ•เบปเบงเบขเปˆเบฒเบ‡เบ‚เบญเบ‡เบ‚เบฑเป‰เบ™เบ•เบญเบ™เบเบฒเบ™เบเบงเบ”เบชเบญเบš:

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 เบ•เป‰เบญเบ‡เบกเบตเป€เบžเบทเปˆเบญเปƒเบซเป‰ Merge เบชเบฒเบกเบฒเบ”เปƒเบŠเป‰เป„เบ”เป‰. เบกเบนเบ™เบ„เปˆเบฒเป€เบ—เบปเปˆเบฒเบเบฑเบšเบซเบ™เบถเปˆเบ‡เบซเบกเบฒเบเบ„เบงเบฒเบกเบงเปˆเบฒเบ•เบปเบงเบ—เปˆเบฒเบ™เป€เบญเบ‡เบชเบฒเบกเบฒเบ”เบญเบฐเบ™เบธเบกเบฑเบ” MR เบ‚เบญเบ‡เบ—เปˆเบฒเบ™เป‚เบ”เบเบเบฒเบ™ "เบกเบฑเบ" เบกเบฑเบ™.

เบ›เบฐเบเบญเบšเบกเบตเบ‚เบฑเป‰เบ™เบ•เบญเบ™เบเบฒเบ™เบ—เบปเบ”เบชเบญเบš, เป€เบŠเบดเปˆเบ‡เบเบงเบ”เบชเบญเบšเบˆเปเบฒเบ™เบงเบ™เบ‚เบญเบ‡ "เบกเบฑเบ".

เบ—เปเปˆเบ—เบตเปˆเบ‡เปˆเบฒเบเบ”เบฒเบเบ—เบตเปˆเบชเบธเบ”เป‚เบ”เบเปƒเบŠเป‰เบ•เบปเบงเบขเปˆเบฒเบ‡เบ‚เบญเบ‡ 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 เปƒเบ™เปเบกเปˆเบšเบปเบ”เบซเบผเบทเบชเบฒเบ‚เบฒ / * เบ›เปˆเบญเบ
  • เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ GitLab API, เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบฎเบฑเบšเบˆเปเบฒเบ™เบงเบ™เบ‚เบญเบ‡ "เบกเบฑเบ" เปเบฅเบฐ "เบšเปเปˆเบกเบฑเบ"
  • เบ„เบดเบ”เป„เบฅเปˆเบ„เบงเบฒเบกเปเบ•เบเบ•เปˆเบฒเบ‡เบฅเบฐเบซเบงเปˆเบฒเบ‡เบ„เปเบฒเบ•เบญเบšเปƒเบ™เบ—เบฒเบ‡เบšเบงเบเปเบฅเบฐเบ—เบฒเบ‡เบฅเบปเบš
  • เบ–เป‰เบฒเบ„เบงเบฒเบกเปเบ•เบเบ•เปˆเบฒเบ‡เปเบกเปˆเบ™เบซเบ™เป‰เบญเบเบเบงเปˆเบฒเบกเบนเบ™เบ„เปˆเบฒเบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบเปเบฒเบ™เบปเบ”เป„เบงเป‰เปƒเบ™ NEED_VOTES, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบžเบงเบเป€เบฎเบปเบฒเบชเบฐเบเบฑเบ”เบเบฑเป‰เบ™เบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เปƒเบ™เบเบฒเบ™เบฅเบงเบก

5. เบซเป‰เบฒเบกเบเบถเบ”เปเบฑเป‰เบ™เบเบฑเบšเบชเบฒเบ‚เบฒเบ—เบตเปˆเบ›เบปเบเบ›เป‰เบญเบ‡

เบžเบงเบเป€เบฎเบปเบฒเบเปเบฒเบ™เบปเบ”เบชเบฒเบ‚เบฒเบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”เปเบฅเบฐเบŠเบตเป‰เบšเบญเบเบงเปˆเบฒเบžเบงเบเป€เบ‚เบปเบฒเบชเบฒเบกเบฒเบ”เป€เบฎเบฑเบ”เบงเบฝเบเป„เบ”เป‰เบœเปˆเบฒเบ™ MR เป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™.

เป€เบžเบทเปˆเบญเป€เบฎเบฑเบ”เบชเบดเปˆเบ‡เบ™เบตเป‰, เป„เบ›เบ—เบตเปˆ Settings โ†’ Repository โ†’ Protected Branches:

เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”เปƒเบ™ Gitlab CE: เบ–เป‰เบฒเบšเปเปˆเบกเบตเบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™, เปเบ•เปˆเบ‚เป‰เบญเบเบเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™

6. เบเบงเบ”เบเบฒ

เบเบณเบ™เบปเบ” NEED_VOTES: 0

เบžเบงเบเป€เบฎเบปเบฒเบชเป‰เบฒเบ‡ MR เปเบฅเบฐเปƒเบชเปˆ "เบšเปเปˆเบกเบฑเบ".

เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”เปƒเบ™ Gitlab CE: เบ–เป‰เบฒเบšเปเปˆเบกเบตเบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™, เปเบ•เปˆเบ‚เป‰เบญเบเบเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™

เปƒเบ™โ€‹เบšเบฑเบ™โ€‹เบ—เบถเบโ€‹เบเบฒเบ™โ€‹เบเปเปˆโ€‹เบชเป‰เบฒเบ‡โ€‹:

เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”เปƒเบ™ Gitlab CE: เบ–เป‰เบฒเบšเปเปˆเบกเบตเบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™, เปเบ•เปˆเบ‚เป‰เบญเบเบเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™

เบ•เบญเบ™เบ™เบตเป‰เปƒเบชเปˆ "เบกเบฑเบ" เปเบฅเบฐเป€เบฅเบตเปˆเบกเบเบงเบ”เป€เบšเบดเปˆเบ‡เบญเบตเบเป€เบ—เบทเปˆเบญเบซเบ™เบถเปˆเบ‡:

เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบฅเบฐเบซเบฑเบ”เปƒเบ™ Gitlab CE: เบ–เป‰เบฒเบšเปเปˆเบกเบตเบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบฅเบงเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™, เปเบ•เปˆเบ‚เป‰เบญเบเบเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™