12 β CI/CD va GitHub Actions asoslari¶
β¬ οΈ Oldingi: 11 β Docker Compose Β· π README Β· Keyingi: 13 β Test va build pipeline β‘οΈ
Bu bobda: "menda ishladi-ku" muammosidan CI/CD (Continuous Integration / Continuous Delivery β uzluksiz integratsiya va yetkazib berish) avtomatlashtirishiga o'tamiz; GitHub Actions nima va workflow fayli qayerda yashashi (
.github/workflows/*.yml, YAML β probel, tab emas); workflow anatomiyasi βname,on(push, pull_request,workflow_dispatch=qo'lda,schedule=cron),jobs, har job'daruns-on: ubuntu-latestvasteps, har step'dauses(tayyor action) yokirun(buyruq); zamonaviy action'lar (actions/checkout@v6,actions/setup-node@v6) va eskirganset-outputo'rniga$GITHUB_OUTPUT/$GITHUB_ENV; runner nima (GitHub-hosted vs self-hosted), job vs step farqi, parallel job'lar,secretsvagithubcontext; va nihoyat birinchi haqiqiy workflow β checkout + Node sozlash +npm testβ hamda Actions tab'idagi loglarni o'qish.
Muammo: "menda ishladi-ku"¶
Tasavvur qiling β kichik jamoa bir Node.js loyihasini birga yozyapsiz. Siz funksiya qo'shdingiz, lokalda npm test o'tdi, git push qildingiz. Bir hafta o'tib hamkasbingiz boshqa branch'ni main'ga qo'shdi va sayt ishdan chiqdi. Sababi: uning kodi sizning testlaringizdan birini buzgan edi, lekin hech kim push qilishdan oldin testni qaytadan ishlatmagan.
Yoki yana yomonroq: deploy paytida kimdir npm install qilishni unutdi, yoki noto'g'ri branch'ni serverga ko'chirdi. Bularning hammasi bitta sababdan kelib chiqadi β qo'lda bajariladigan qadamlar unutiladi va xato qilinadi.
Yechim β bu takror, zerikarli, lekin muhim qadamlarni (test, lint, build, deploy) mashinaga topshirish. Har git push'da bir robot avtomatik testlarni ishlatsin, o'tmasa sizni ogohlantirsin, o'tsa yo'lga qo'ysin. Aynan shuni CI/CD deyiladi.
βΉοΈ CI/CD asosini Git & GitHub kitobida birinchi marta ko'rganmiz. U yerda fokus Git workflow'da edi; bu yerda DevOps nuqtai nazaridan β nega va qanday avtomatlashtirish ishlab chiqarishni ishonchli qilishiga qaraymiz.
CI/CD nima: ikkita oddiy g'oya¶
- CI β Continuous Integration (uzluksiz integratsiya): har bir o'zgarish (commit/push) markaziy repozitoriyga qo'shilganda, avtomatik ravishda build qilinadi va testdan o'tkaziladi. Maqsad β buzilgan kodni iloji boricha erta topish, "main har doim ishlaydigan holatda" bo'lsin.
- CD β Continuous Delivery / Deployment (uzluksiz yetkazib berish / joylash): CI o'tgach, kod avtomatik (yoki bitta tugma bosib) staging yoki production muhitiga joylanadi. Inson har deployni qo'lda qilmaydi.
π Asosiy qoida: agar bir ishni ikki martadan ko'p qo'lda qilayotgan bo'lsangiz, uni avtomatlashtirishni o'ylab ko'ring. CI/CD β "har push'da nima bo'lishi kerakligini" bir marta yozib qo'yib, keyin uni unutish.
Eski qo'lda usul (5-bobda ko'rgan SSH bilan qo'lda deploy) bilan solishtiring: u yerda har gal terminal ochib, server'ga kirib, git pull, npm install, qayta ishga tushirish qadamlarini qo'lda bajargandik. CI/CD shularning hammasini matn faylga yozadi va robot bajaradi.
GitHub Actions va workflow fayli¶
GitHub Actions β GitHub'ning o'ziga qurilgan CI/CD tizimi. Alohida server sozlashingiz shart emas: repozitoriyangizga maxsus YAML fayl qo'shasiz, GitHub uni o'qib, kerakli paytda avtomatik ishga tushiradi.
Workflow fayllari aniq bir joyda yashashi shart:
loyiha/
βββ .github/
β βββ workflows/
β βββ ci.yml <- bu yerga
β βββ deploy.yml
βββ src/
βββ package.json
βββ ...
π Papka nomi aniq .github/workflows/ bo'lishi shart (nuqtadan boshlanadi). Fayl kengaytmasi .yml yoki .yaml. Bitta repozitoriyada nechta workflow fayli bo'lsa, bo'lishi mumkin β GitHub .github/workflows/ ichidagi har bir faylni alohida workflow deb biladi.
β οΈ YAML β probelga sezgir til. Indentatsiya (chekinish) faqat probel bilan qilinadi, TAB bilan emas. Bir-ikki probel xato bo'lsa, GitHub workflow'ni umuman o'qiy olmaydi. Tahrirlovchingizda "tab'ni probelga aylantir" (insert spaces) sozlamasini yoqib qo'ying va odatda 2 probel chekinish ishlating.
Workflow anatomiyasi¶
Workflow faylining tuzilishi ichma-ich qatlamli: bitta workflow ichida bir nechta job, har job ichida bir nechta step. Quyidagi diagramma shu qatlamlarni ko'rsatadi.
Eng kichik to'liq workflow shunday ko'rinadi:
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
test:
name: Test va lint
runs-on: ubuntu-latest
steps:
- name: Kodni olish
uses: actions/checkout@v6
- name: Node sozlash
uses: actions/setup-node@v6
with:
node-version: '22'
cache: 'npm'
- name: Bog'liqliklarni o'rnatish
run: npm ci
- name: Testlarni ishga tushirish
run: npm test
Endi har bir kalitni ko'rib chiqamiz.
name β workflow nomi¶
Actions tab'ida ko'rinadigan inson o'qiy oladigan nom. Ixtiyoriy, lekin tavsiya etiladi.
on β qachon ishga tushadi (trigger)¶
on β workflow'ni nima qo'zg'atishini belgilaydi. To'rtta eng ko'p ishlatiladigan trigger:
on:
push: # repoga push bo'lganda
branches: [main] # faqat main branch
pull_request: # PR ochilganda/yangilanganda
branches: [main]
workflow_dispatch: # Actions tab'idan QO'LDA tugma bilan
schedule: # vaqt jadvali bo'yicha (cron)
- cron: '0 3 * * *' # har kuni soat 03:00 UTC
pushβ kimdir kodni repoga yuborsa. Eng keng tarqalgan: har push'da test ishlasin.pull_requestβ PR ochilganda yoki yangilanganda. PR'nimain'ga qo'shishdan oldin testlar o'tishini tekshiradi.workflow_dispatchβ Actions tab'idagi "Run workflow" tugmasi orqali qo'lda ishga tushirish. Deploy kabi inson qarori kerak bo'lgan ishlar uchun zo'r.scheduleβcronifodasi bilan vaqt jadvali. Tungi audit, backup, bog'liqlik tekshiruvi uchun.
π‘
cronformati eslatma:'0 3 * * *'β beshta maydon:daqiqa soat kun-oy oy hafta-kuni. Bu yerda har kuni 03:00 da.scheduleUTC vaqtida ishlaydi β mahalliy vaqtga moslang. (Bash bobida cron'ni batafsil ko'rgandik.)
jobs β bajariladigan ishlar¶
jobs ichida bir yoki bir nechta job bo'ladi. Har job β alohida, toza mashinada ishlaydi. Yuqorida bitta job bor: test.
runs-on β qaysi mashinada¶
Har job'da runs-on bo'lishi shart β qaysi turdagi runner'da (mashinada) ishlashini ko'rsatadi. Odatda ubuntu-latest (eng yangi barqaror Ubuntu). Boshqalar: windows-latest, macos-latest.
steps β qadamlar¶
Job ichida ketma-ket bajariladigan qadamlar. Har step ikki xil bo'ladi:
usesβ tayyor action'ni chaqiradi (boshqalar yozgan qayta ishlatiladigan blok), masalanactions/checkout@v6.runβ to'g'ridan-to'g'ri shell buyrug'i, masalanrun: npm test.
Har step'da ixtiyoriy name (logda ko'rinadigan nom) va env (o'sha step uchun muhit o'zgaruvchilari) bo'lishi mumkin.
Job vs Step: muhim farq¶
Bu ikkisini chalkashtirmang:
| Job | Step | |
|---|---|---|
| Qayerda ishlaydi | O'z alohida toza mashinasida | Job'ning o'sha mashinasida |
| Bir-biriga ta'siri | Default'da parallel, izolyatsiya qilingan | Ketma-ket, bir fayl tizimini bo'lishadi |
| Misol | "test" job va "build" job | "checkout" step, "npm test" step |
π Ikki job default holda parallel (bir vaqtda) ishlaydi va bir-birining fayllarini ko'rmaydi β har biri toza mashinada boshlanadi. Agar build job test'dan keyin ishlashini xohlasangiz, needs: test bilan bog'lashingiz kerak (buni 13-bobda chuqurroq ko'ramiz).
Bir job ichidagi step'lar esa ketma-ket ishlaydi va bir xil fayl tizimini bo'lishadi: shuning uchun checkout step kodni yuklab oladi, keyingi npm ci step o'sha kodni ko'radi.
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo "men test job'man"
lint:
runs-on: ubuntu-latest # test bilan PARALLEL ishlaydi
steps:
- run: echo "men lint job'man"
Runner nima¶
Runner β workflow step'larini aslida bajaradigan mashina (server). Ikki xil bo'ladi:
- GitHub-hosted runner β GitHub har ishga tushishda siz uchun toza, vaqtinchalik virtual mashina ajratadi (
ubuntu-latestva h.k.). Ish tugagach mashina o'chiriladi. Hech narsa sozlashingiz shart emas. Public repolar uchun bepul, private uchun cheklangan bepul daqiqalar bor. - Self-hosted runner β o'zingizning serveringizda runner dasturini o'rnatib, GitHub'ga ulaysiz. Maxsus apparat (GPU), ichki tarmoqqa kirish yoki ko'p daqiqa kerak bo'lganda ishlatiladi. Boshqaruvi (yangilash, xavfsizlik) sizning zimmangizda.
Boshlovchilar uchun GitHub-hosted yetarli β biz shularni ishlatamiz.
Quyidagi diagramma push'dan natijagacha bo'lgan butun oqimni ko'rsatadi: GitHub triggerni sezadi, runner ajratiladi, step'lar ketma-ket bajariladi, oxirida muvaffaqiyat yoki xato belgisi qo'yiladi.
Secrets va context¶
CI ichida ko'pincha maxfiy ma'lumot kerak bo'ladi: registry paroli, deploy SSH kaliti, API token. Bularni faylga hech qachon yozmang. GitHub repo sozlamalarida (Settings β Secrets and variables β Actions) saqlanadi va workflow'da ${{ secrets.NOM }} orqali olinadi:
- name: Registry'ga login
run: echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
β οΈ Secret qiymatlari logda avtomatik yashiriladi (
***bo'lib chiqadi). Lekin baribir secret'niechoqilmang yoki faylga yozmang β ehtiyot shart.
GitHub yana bir qancha tayyor ma'lumotni github context orqali beradi β joriy commit, branch, kim ishga tushirgani va h.k.:
Eng ko'p ishlatiladigani: github.sha (commit hash), github.ref_name (branch/tag nomi), github.repository (user/repo), github.actor (ishga tushirgan foydalanuvchi).
Step'lar orasida ma'lumot uzatish β to'g'ri usul¶
Bir step natijani hisoblab, keyingi step ishlatishi kerak bo'lsa, natijani $GITHUB_OUTPUT fayliga yozasiz:
- name: Versiyani aniqlash
id: meta
run: echo "sha_short=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
- name: Ishlatish
run: echo "Qisqa SHA = ${{ steps.meta.outputs.sha_short }}"
Muhit o'zgaruvchisini keyingi step'larga uzatish uchun esa $GITHUB_ENV:
β οΈ Eskirgan usulni ishlatmang. Eski qo'llanmalarda
echo "::set-output name=x::qiymat"va::save-state::ko'rinasiz β bular o'chirilgan va endi ishlamaydi. Zamonaviy usul β$GITHUB_OUTPUTva$GITHUB_ENVfayllariga>>bilan yozish.
Zamonaviy action versiyalari¶
Action'lar uses: egasi/nom@versiya ko'rinishida chaqiriladi. Versiyani doim ko'rsating. 2026-yil holatiga tasdiqlangan asosiy action'lar:
- uses: actions/checkout@v6 # kodni runner'ga yuklab oladi
- uses: actions/setup-node@v6 # kerakli Node versiyasini o'rnatadi
- uses: actions/setup-python@v5 # Python uchun
- uses: actions/cache@v5 # keshlash
- uses: actions/upload-artifact@v4 # build natijasini saqlash
β οΈ Eskirgan versiyalarni ishlatmang.
actions/checkout@v2va@v3eskirgan (eski Node runtime'ida ishlaydi, GitHub ogohlantirish beradi). Doim joriy major versiyani ishlating:actions/checkout@v6. Shubha bo'lsa, action'ning GitHub sahifasidagi "Releases"ni tekshiring β versiyani ixtiro qilmang.
π‘ @v6 deb major versiyaga bog'lansangiz, GitHub o'sha major ichidagi eng yangi patchni avtomatik oladi (xavfsizlik tuzatishlari kelib turadi). To'liq aniqlik kerak bo'lsa, commit SHA'ga bog'lash mumkin (@a1b2c3...), lekin boshlang'ich uchun @v6 yetarli.
Amaliyot: birinchi workflow'ingiz¶
Endi yuqoridagi ci.yml ni haqiqiy repoga qo'shamiz. Namuna ilovamiz β kitob bo'ylab ishlatib kelayotgan oddiy "vazifalar" (todo) Node.js API'si.
1-qadam. Loyiha ildizida papka va fayl yarating:
2-qadam. .github/workflows/ci.yml faylini yarating (mazmuni β yuqoridagi to'liq workflow).
3-qadam. package.json'da test buyrug'i borligiga ishonch hosil qiling. Test hali yo'q bo'lsa, vaqtinchalik shu ishni beradi:
4-qadam. Commit qilib push qiling:
βΉοΈ Illustrativ qadam: push qilingach, GitHub'da repozitoriyangizning Actions tab'ini ochish, workflow ishga tushganini va loglarni ko'rish haqiqiy GitHub repozitoriyasini talab qiladi (bu kitobda offline ko'rsatib bo'lmaydi). Quyidagi tavsiflar siz o'z repongizda ko'radigan natijaga mos.
Loglarni o'qish¶
git push qilgach, GitHub triggerni darhol sezadi. Repo sahifasida Actions tab'iga o'ting:
- Workflow ro'yxati β chapda "CI" ko'rinadi, har ishga tushish (run) bitta qator.
- Run ichida β
testjob ko'rinadi: yashil β (o'tdi) yoki qizil β (xato). - Job ichida β har step alohida ochiladigan blok. Bossangiz, o'sha step'ning to'liq terminal chiqishi ko'rinadi.
Tipik muvaffaqiyatli chiqish shunday ko'rinadi (qisqartirilgan):
Run npm test
> vazifalar-api@1.0.0 test
> node --test
β vazifa qo'shiladi (12.3ms)
β bo'sh ro'yxat qaytariladi (1.1ms)
# tests 2
# pass 2
# fail 0
Agar test yiqilsa, qizil β chiqadi va aynan qaysi step, qaysi qatorda xato bo'lgani logda ko'rinadi. PR'da esa bu natija to'g'ridan-to'g'ri PR sahifasida "checks" bo'limida ko'rinadi β buzilgan PR'ni qo'shishdan oldin ko'rasiz.
π‘ Logni o'qishda eng tez yo'l: yiqilgan (qizil) step'ni oching, oxirigacha aylantiring β xato xabari odatda eng pastda bo'ladi. Step nomini ma'noli qo'ysangiz (name:), qaysi bosqichda yiqilganini bir qarashda tushunasiz.
12-bob mashqlari¶
Quyidagi mashqlarda YAML yozasiz. Strukturani lokalda tekshirish uchun foydali: faylni
python -c "import yaml; yaml.safe_load(open('ci.yml'))"bilan parse qiling β xatosiz o'tsa, sintaksis to'g'ri. Haqiqiy ishga tushirish GitHub repozitoriyasini talab qiladi.
Oson¶
.github/workflows/papkasi nima uchun kerak va fayl kengaytmasi qanday bo'lishi mumkin? Bir nechta workflow fayli bo'lsa nima bo'ladi?on:kalitidagipush,pull_request,workflow_dispatch,scheduletriggerlarini bittadan jumlada izohlang.- Job bilan step orasidagi uchta farqni ayting (qayerda ishlashi, parallel/ketma-ket, fayl tizimini bo'lishish).
usesbilanrunstep'lari farqi nimada? Har biriga bittadan misol yozing.
O'rta¶
- Quyidagi workflow'da
on:push'da, lekin faqatmainbranch'da ishga tushishini sozlang vanamebering.
Yechim
`branches: [main]` filtri faqat `main`'ga push bo'lganda ishga tushiradi. Boshqa branch'larga push'da workflow o'tkazib yuboriladi.- Python loyihasi uchun checkout + Python 3.12 sozlash +
pip install -r requirements.txt+pytestishlatadigan workflow yozing.
Yechim
`on: [push, pull_request]` β qisqa yozuv: ikkala triggerni filtersiz yoqadi.- Bir workflow'da ikkita parallel job yarating:
testvalint. Har biri o'zechobuyrug'ini bajarsin. Ular bir vaqtda ishlashini tushuntiring.
Yechim
`test` va `lint` orasida bog'liqlik (`needs`) yo'q, shuning uchun GitHub ularni ikkita alohida toza mashinada **bir vaqtda** ishga tushiradi. Bu jami vaqtni qisqartiradi.workflow_dispatchniinputsbilan qo'shing: foydalanuvchi "muhit" qiymatini (defaultstaging) tanlay olsin. Workflow ichida shu inputniechoqiling.
Yechim
Actions tab'idagi "Run workflow" tugmasi bosilganda matn kiritish maydoni chiqadi. Qiymat workflow ichida `${{ inputs.muhit }}` orqali olinadi.- Workflow'da joriy commit qisqa SHA'sini hisoblab (
github.shaning birinchi 7 belgisi), keyingi step'da ishlatib chiqaring.$GITHUB_OUTPUTishlating.
Yechim
`${GITHUB_SHA::7}` β bash'da satrning birinchi 7 belgisi. `id: meta` step'ga nom beradi, natija `steps.meta.outputs.sha_short` orqali olinadi. Eskirgan `::set-output` ni **ishlatmaymiz**.Qiyin¶
-
To'liq CI workflow yozing:
pushvapull_request(faqatmain) hamdaworkflow_dispatch'da ishlasin; Node 22 sozlasin (npm keshi bilan),npm civanpm testqilsin. Har step'ga ma'nolinamebering.Yechim
name: CI on: push: branches: [main] pull_request: branches: [main] workflow_dispatch: jobs: test: name: Test va lint runs-on: ubuntu-latest steps: - name: Kodni olish uses: actions/checkout@v6 - name: Node sozlash uses: actions/setup-node@v6 with: node-version: '22' cache: 'npm' - name: Bog'liqliklarni o'rnatish run: npm ci - name: Testlarni ishga tushirish run: npm testcache: 'npm'βsetup-nodekeshlashni yoqadi, keyingi run'lardanpm citezroq bo'ladi.npm ci(clean install)package-lock.json'ga aniq mos o'rnatadi β CI uchunnpm install'dan afzal. -
Quyidagi workflow ikkita xatoga ega. Toping va tuzating.
Yechim
Ikki xato: 1.
testjob'daruns-onyo'q β har job qaysi mashinada ishlashini ko'rsatishi shart. 2.actions/checkout@v3eskirgan β@v6ishlating. (Qo'shimcha:on:ostidagipushindentatsiyasi noto'g'ri βpush:mustaqil kalit bo'lishi kerak.)Tuzatilgan:
-
scheduletrigger bilan har kuni soat 06:00 (UTC) danpm auditishlaydigan "tungi xavfsizlik tekshiruvi" workflow yozing.workflow_dispatchham qo'shing (qo'lda ham ishga tushira olish uchun).Yechim
name: Nightly audit on: schedule: - cron: '0 6 * * *' workflow_dispatch: jobs: audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version: '22' - run: npm audit --omit=devcron: '0 6 * * *'β har kuni 06:00 UTC.scheduleUTC'da ishlaydi, mahalliy vaqtga moslang.workflow_dispatchqo'shilgani uchun jadval kutmasdan qo'lda ham sinab ko'rasiz. -
Deploy workflow'da
secretsdan SSH kaliti va server manzilini olib,github.shani log qiladigan xavfsiz struktura yozing (haqiqiy deploy buyrug'i o'rnigaechoqo'ying β illustrativ).Yechim
name: Deploy on: workflow_dispatch: jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Ma'lumotni log qilish run: echo "Deploy commit ${{ github.sha }} -> server ${{ secrets.DEPLOY_HOST }}" - name: Deploy (illustrativ) env: SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }} run: echo "bu yerda ssh/rsync bo'lardi (real serverga ulanish kerak)"Secret'lar repo Settings β Secrets and variables β Actions'da saqlanadi va faqat
${{ secrets.NOM }}orqali olinadi β faylga yozilmaydi. SSH kalitini step'ningenv'iga berdik, logda u***bo'lib yashiriladi. Real deploy 15-bobda batafsil ko'riladi.
β¬ οΈ Oldingi: 11 β Docker Compose Β· π README Β· Keyingi: 13 β Test va build pipeline β‘οΈ