CI/CD o'zi nima?
Tags: webdev, devops, javascript, tutorial
Published: 2022-05-27 15:40:01

## Bismillah!
<u>_Taxminiy o'qish vaqti: ~6 daqiqa_</u>

Assalom Alaykum!

> _**Diskleymer**: ba'zi atamalardan shundayligicha foydalanildi, tarjimasi ga'latiroq yoki notanish ko'rinmasligi uchun. Ba'zi iboralar esa ixchamroq ko'rinishga keltrildi, release -> reliz._

Ushbu turkum maqolalardan ko'zlangan asosiy maqsad, web servislarini `reliz` qilish jarayoni bilan qiynalayotgan, dasturning yangi imkoniyatlarni foydalanuvchilariga ishonchli va tez yetkazishda muammolarga duch kelayotgan jamoalar (`team`) uchun `frontend`da qo'llaniladigan keng tarqalgan amaliyotlarni jamlagan muxtasar qo'llanma sifatida yozildi. Maqoladagi ko'rsatmalar asosan kamida 2-4 kishilik jamoa bo'lib ishlayotgan `frontend` dasturchilar uchun qaratilgan bo'lsada, ba'zi umumiy tushunchalar `backend` developerlar uchun ham foydali bo'lishi mumkin. Ushbu post juda ko'plab men tanigan va shaxsan tanimagan dasturchilarning tajribalaridan kelib chiqib yozilganiga qaramay albatta xato va kamchiliklardan holi emas. Agar biron xato yoki kamchilik topsangiz albatta sharhlar bandida buni bildiring!

> _**reliz** bu muayyan davr (e.g. `sprint`) mobaynida dasturiy ta'minotga yangi qo'shilgan `feature` ya'ni imkoniyatlar va `bugfix` ya'ni dastur xatolariga tuzatmalarning foydalanuvchilarga taqdim etilishidir. Boshqa til bilan aytsak, muayyan dasturiy ta'minotning oxirgi/yangi versiyasini `production`ga chiqarish._

---

### `CI/CD` o'zi nima?
 
Dasturiy ta'minotni `reliz` qilish, agar to'g'ri tashkil etilmasa, bosh-og'riq-beruvchi va ko'p vaqt talab qiladigan jarayon bo'lishi mumkin. Kodni reliz qilishga tayyor bo'lish bilan bog'liq vaqt majburiyatlari ya'ni `deadline`lar ( `savdo/marketing` bo'limlari bosimi ostida) asab torlarini yanada taranglashtiradi. Buni hal qilishni oson yo'li bormi? Albatta bor, **CI/CD** :rocket:

>_**CI** ya'ni `Continuous Integration`: dastur kodiga qo'shilgan har bir o'zgarishni (git `commit`) dastur kodi joylashgan markaziy `repository`ga avtomalashtirilgan shaklda davomiy qo'shib borish_
>_**CD** ya'ni `Continuous Delivery(Deployment)`: dastur kodini avtomalashtirilgan shaklda doimiy `deploy` qilish amaliyoti._

`CI/CD` dasturiy ta'minot ishlab chiqish va shu jarayon bilan bog'liq bo'lgan barcha `operativ ishlar` o'rtasida ko'prik vazifasini bajaruvchi avtomalashtirilgan amaliyotlar majmuasidir (operativ ishlar: `server`, `DB`, `OS`, `virtualization`, `containerization`, `dependent libs` va boshqa dastur ishlashi uchun zarur bo'lgan vositalarni o'rnatish, boshqarish va davomiy xizmat ko'rsatib turish).  Boshqa rakursdan qaraganda esa, `CI/CD` bu so'nggi 10 yillikda dasturiy ta'minot ishlab chiqishning de-facto standartiga aylangan `Agile & DevOps`  madaniyat/harakatining namoyon bo'lishi ya'ni realizatsiyasidir.

> _**deployment** yoki **deploy** qilish bu dastur kodini ishchi holatga keltirishdir._

[**CI/CD**](https://www.redhat.com/en/topics/devops/what-is-ci-cd) ko'p IT kompaniyalarda o'z dasturiy mahsulotlarini (`webapp`, `web-service`, `mobile app` va hkz) foydalanuvchilariga qulay, tez va sifatli tarzda yetkazib berishini yangi darajaga olib chiqdi. `CI/CD`, ya'ni dasturiy ta'minot ishlab chiqish jarayonining barcha bosqichlarini iloji boricha avtomatlashtirish, har qanday jamoaga (kompaniya) quyidagi imkoniyatlarni taqdim etadi:

- risklarni kamaytirish: avtomatlashtirilgan testlar dasturiy ta'minotning ishonchliligini yaxshigina kafolatlaydi va keyingi relizlarda ham regressiyalar yuz berish ehtimolini ancha kamaytiradi yoki yo'qotadi.
- `better code quality`: dastur kodininig sifatli bo'lishiga ya'ni uning izchil va muayyan kodlash qoidalariga amal qilinishini osonlashtiradi.
- davomiy va bir maromdagi relizlarni chiqarish imkoniyati: dasturning yangi versiyasini `deploy` qilish anavaviy usullardan ko'ra ancha qulay, oson va tezroq.
- bozorga tezroq kirish: `CI/CD pipeline` dan asosiy ko'zlangan maqsadlardan biri ham tayyor bo'lgan dasturiy mahsulotni, keyinchalik esa uning yangi imokoniyatlarini foydalanuvchilarga tez yetkazib berib turishni ancha osonlashtirishdir.
- yangi qo'shilgan lekin muammoli `feature`larni tezda va ortiqcha qiyinchiliklarsiz `revert` ya'ni ortga qaytara olishlik qobilyatini beradi.
- dasturchilar va operativ ishchilar (e.g. sysadmin) o'rtasidagi `friction` ya'ni kelishmovchiliklarni oldini oladi.
- dasturchilarning vaqtini tejash: dasturchilarning vaqti juda qimmat, shuning uchun ularning asosiy vaqti kod yozish bilan o'tishi kerak, `production` ga chiqarilgan relizdagi muammolarni topish bilan emas. 

Demak reliz qilishgacha bo'lgan deyarli barcha jarayonlarni avtomatlashtirish ya'ni inson omilini kamaytirish orqali dasturiy ta'minotning iloji boricha xatolardan holi, **barqaror** va sifatli bo'lishiga olib keladi.

>_**CI/CD pipeline**: dastur kodidagi o'zgarishlarni asosiy `repo`ga qo'shishdan tortib to uni `reliz` qilishgacha bo'lgan barcha ketma-ket o'zaro bog'liq bosqichlarni o'z ichiga olgan jarayonning nomlanishi. Mingta gapdan bitta rasm yaxshiroq._
![CI/CD pipeline](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4vialoslqu2pee4516rg.png)

Jamoa bilan yangi `CI/CD pipeline`ni ishlab chiqar ekanmiz, (yoki allaqachon mavjud bo'lganini takomillashtirish bo'lsin) bu ishda eng muhim jihatlardan biri bu asosiy kuchni qayerga yo'naltirishni aniq qilib olish:

- **formatlash, linting, unit/integration testlar va code coverage**
jamoadagi dasturchilarning muayyan kodlash qoidalariga rioya qilib kod yozishi va doimiy `unit/integration` testlar yozib turishi jamoani samaradorligini, `uzoq muddatli tezligini` (lekin boshlanishida ko'proq vaqt oladi) va barqarorligini sezilarli oshiradi. Demak ushbu qismni dasturdagi kichik miqyosli ammo muhim xato va kamchiliklarini aniqlovchi birinchi himoya fronti sifatida ko'radigan bo'lsak, bu yerdagi amaliyotlar asosan muayyan jamoa tarkibidagi dasturchilargagina ta'sir etadi. Bu amaliyotlarning asosiy farqlovchi xususiyati bu tez ishlashi (bir necha soniyalar) va agarda xato topilsa ham tezda `fail` bo'lishidir. `Code coverage` esa o'z nomi bilan dasturning qancha qismi testlar bilan qoplanganini aniqlab beruvchi indikatordir.

- **E2E (end-to-end) testlar, code review va preview branch deploymentlar**
himoyaning bu o'rta fronti `kross-funksional` (ya'ni bir necha jamoalarni qamrab oluvchi) amaliyotlardan tashkil topgan bo'lib odatda ancha ko'proq vaqt oladi. Agar `e2e` testlarni misol qilib oladigan bo'lsak, bu turdagi testlar `frontend` va `backend` jamoa a'zolariga dasturning eng muhim qismlarini (`user flow`) birgalikda tekshirish imkonini beradi. `Code review`lar esa 1-frontdan o'tib ketgan xatolarni ya'ni asosan dasturning mahtiqiy xatolari, taklif etilgan yechimdagi kamchiliklar, ularning dasturlashdagi ma'lum va mashxur tamoyillarga (`DRY`, `SOLID`, `KISS`, `SOC`, `YAGNI` va [boshqa umumiy](https://thefullstack.xyz/dry-yagni-kiss-tdd-soc-bdfu)) amal qilingan yoki qilinmaganini aniqlashda, yoki taklif etilgan yechim `feature requirement specs`ga qanchalik to'g'ri kelgan-kelmaganini aniqlashda o'rni beqiyosdir. Va oxirgisi bu har bir PR (Pull Request) uchun alohida `preview` deploymentlarga ega bo'lish (bunday deploymentlar takrorlanmas `URL`ga ega bo'lishi bilan ajralib turadi). Har bir bunday deployment bu sizning frontend loyihangizning ma'lum bir o'zgarishlarga ega versiyasidir. Bunday deploymentlar nafaqat jamoa ichida `code review`ni tezligini oshiradi balki bundan tashqari `design` va `product` teamlar siz tanishtirgan o'zgarishlarni (e.g. dasturga yangi qo'shilgan imkoniyatlar) qulay va tezda tasdiqlashini ham osonlashtiradi.

- **feature flag, accessibility auditlar/testlar, performance testlar va cross-browser testlar**
bu esa himoyaning so'nggi fronti bo'lib asosan reliz va relizdan keyingi `more-customer-facing` amaliyotlardan tashkil topgan. Xususan, **feature flaglar** bu muayyan dastur imkoniyatini masofadan turib dasturni qayta deploy qilmasdan (ya'ni hech qanday koddagi o'zgarishsiz) o'chirib/yoqib qo'yish imkoniyati yoki biron yangi `feature`ni foydalanuvchilarga ko'rsatmasdan turib deploy qila olishlik imkoniyatini beruvchi vositadir. **ff**lar yordamida `canary reliz`lar, `kill switch`, `A/B testing` va bir qancha boshqa ishlarni amalga oshirsa bo'ladi. **Accessibility audit/testlar** : bularni CI/CD pipelinimizni oxirgi qismi desak ham bo'ladi, lekin shunga qaramasdan eng muhim va eng qiyin bosqichlardan biri chunki odatda frontendimizni `100% accessible` qilishni kafolatlash deyarli imkonsiz. Lekin shunga harakat qilinish kerak.

>_**linting** bu dastur kodini statik tahlil qilish jarayoni bo'lib, dasturdagi `bug`lar ya'ni xatolar va koddagi stilistik nomutanosibliklarni topishda ishlatiladi._

>_**e2e testlar** bu sodda qilib aytganda dasturning butun jabhalarini, `database`, `backend` va `frontend`ni qamrab oluvchi va eng qimmat va eng ko'p vaqt talab qiladigan testlar. Ayni paytda, bu turdagi teslarni dastur kodining haqiqatda muammolarsiz ishlayotganini eng to'g'ri ko'rsatib beruvchi indikator deb qarasak ham bo'ladi._

> _**feature requirement specs** bu dasturning muayyan `feature`sini nimaligi, qanday ishlashi va nima natija berishi kerakligi bildiruvchi texnik xujjat, sodda qilib aytsak  dasturchilar/proyekt managerlar shunga qarab dasturga yangi imkoniyatlarni qo'shishadi. FRS ni [SRS](https://en.wikipedia.org/wiki/Software_requirements_specification) (Software requirements specification) ning kichikroq versiyasi desak ham bo'ladi._

Demak, `CI/CD pipeline`ning har bir bosqichini ta'sir doirasining kengliga qarab shartli 3 guruhga bo'lib olsak bo'ladi:
- faqat muayyan jamoa miqyosida
  - `unit/integration` testlar (odatda `code coverage` bilan), `linting`, `formatlash` va `type checker`lar 
- bir necha jamoalarni qamrab oluvchi (ya'ni kompaniya darajasida)
  - `e2e` testlar, `code review`, `preview deployment`lar va avtomatlashtirilgan relizlar
- jamoa(lar)ni, kompaniyani va barcha foydalanuvchilarni qamrab oluvchi.
  - `feature flaglar`, `accessibility` auditlar/testlar va `performance` testlar.

Kelgusu qismlarda bularning har biri bilan alohida-alohida va chuqurroq tanishib chiqamiz.

> Maqsadimiz o'zbek tilida IT bilan bo'gliq sifatli contentni ko'paytirish va ularni hammaga qulay uslubda tarqatishdir. Bunda eng katta muammolarimizdan biri bu sohaga oid inglizcha atamalarni qanday qilib tushinarli tarzda, o'z ma'nosidan chiqib ketmagan holda qisqa va lo'nda shaklda yetkazishdir. Chunki to'g'ridan to'g'ri (direct) tarjima ko'p hollarda haddan tashqari uzun, tushunarsiz va o'zining dastlabki ma'nosidan chiqib ketgan shaklga kelib qolishidir. Shuning uchun sarbast (erkin) uslubni (postimizda boshida ham bu haqida biroz to'xtalgandik) sinab ko'rishga qaror qildik. Haligi aytishgandek: Best of both worlds :) !