GitHub Actions — avtomatik test va deploy
Muammodan boshlaylik
CI ishlayapti (38-dars): har PR da testlar. Lekin deploy hali qo'lda:
- Serverga SSH
git pullnpm ci && npm run buildsudo systemctl restart dokon
Har deploy — 10 daqiqa va "kim oxirgi deploy qildi? qaysi versiya?" savollari. Juma kechqurun hech kim deploy qilishni xohlamaydi.
Maqsad: main ga merge → bir necha daqiqada production da. Inson aralashuvisiz, har safar bir xil.
Umumiy sxema
PR merge ──→ main ga push
│
▼
┌──── test ────┐
│ lint, test │
└──────┬───────┘
│ ✅
▼
┌──── build ───┐
│ npm run build│
└──────┬───────┘
│ ✅
▼
┌──── deploy ──┐
│ serverga │ ← sirlar: SSH kalit, token
└──────────────┘
Test muvaffaqiyatsiz — deploy bo'lmaydi.
1-variant: VPS ga SSH orqali
Linux kursidagi (44-dars) server — ilova systemd xizmati sifatida ishlaydi.
Tayyorgarlik
- Deploy uchun alohida SSH kalit (parolsiz):
ssh-keygen -t ed25519 -f deploy_key -N "" -C "github-actions"
- Ochiq kalit (
deploy_key.pub) — serverdagideployfoydalanuvchisining~/.ssh/authorized_keysiga - Yopiq kalit (
deploy_key) — GitHub repozitoriy → Settings → Secrets and variables → Actions → New secret:SSH_KEY(44-dars) - Yana:
SERVER_HOST=45.12.34.56
Workflow
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
concurrency:
group: production
cancel-in-progress: false
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22, cache: npm }
- run: npm ci
- run: npm test
deploy:
needs: test
runs-on: ubuntu-latest
environment:
name: production
url: https://dokon.uz
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22, cache: npm }
- name: Build
run: |
npm ci
npm run build
- name: SSH kalitni sozlash
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -H ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts
- name: Fayllarni yuklash
run: |
rsync -az --delete -e "ssh -i ~/.ssh/deploy_key" \
dist/ package.json package-lock.json \
deploy@${{ secrets.SERVER_HOST }}:/opt/dokon/app/
- name: Qayta ishga tushirish
run: |
ssh -i ~/.ssh/deploy_key deploy@${{ secrets.SERVER_HOST }} \
"cd /opt/dokon/app && npm ci --omit=dev && sudo systemctl restart dokon"
- name: Health check
run: |
sleep 5
curl -sf https://dokon.uz/api/health
needs: test— testlar o'tmasa, deploy ishga tushmaydiconcurrency— bir vaqtda faqat bitta deploy; ikki merge ketma-ket bo'lsa — navbatenvironment: production— GitHub da "Environments" bo'limida deploy tarixi; qo'shimcha himoya qo'yish mumkin (pastga qarang)${{ secrets.X }}— sirlar logda***bo'lib ko'rinadirsync,ssh— Linux kursi (34, 35-darslar)- Health check — sayt javob bermasa, workflow ❌ — darhol bilasiz
2-variant: Docker image
Docker kursining 41-darsida batafsil: build → GHCR ga push → serverda docker compose pull && up -d. Afzalligi: serverda Node.js va build vositalari kerak emas, rollback — oldingi image tegi.
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
3-variant: Platformalar (Vercel, Netlify, Railway)
Frontend va oddiy ilovalar uchun — ko'pincha workflow umuman kerak emas: platformani GitHub repozitoriyga ulaysiz, va u har push da o'zi build va deploy qiladi, har PR uchun preview URL beradi (33-dars). Bu DevDocs saytining o'zi ham aynan shunday — Vercel orqali.
Workflow faqat qo'shimcha nazorat kerak bo'lganda: avval o'z testlaringiz, keyin platforma CLI si bilan deploy.
Environments — production ni himoyalash
Settings → Environments → production:
- Required reviewers — deploy job ishga tushishidan oldin belgilangan odam tasdiqlashi kerak ("Approve and deploy" tugmasi)
- Wait timer — masalan, 5 daqiqa kutish
- Deployment branches — faqat
maindan deploy - Environment secrets — production sirlari faqat shu environment dagi job larga ko'rinadi
Staging uchun — alohida environment, tasdiqsiz.
jobs:
deploy-staging:
environment: staging
# ... avtomatik
deploy-production:
needs: deploy-staging
environment: production # ← tasdiq kutadi
Teg bo'yicha reliz deploy
Har bir merge emas, faqat versiya chiqarilganda (36-dars):
on:
push:
tags: ["v*"]
npm version minor
git push --follow-tags # → v2.5.0 → workflow → production
Rollback
Deploy xato bo'ldi:
- Eng tez —
git revert(28-dars) → push → workflow avtomatik oldingi holatni deploy qiladi - Qo'lda qayta ishga tushirish — Actions → oldingi muvaffaqiyatli run → Re-run all jobs (eski commit dan qayta deploy)
- Docker — oldingi image tegini deploy qilish
[!TIP] Workflow ga
workflow_dispatchqo'shing — Actions tabida qo'lda "Run workflow" tugmasi paydo bo'ladi. Favqulodda holatda (yoki CI dan tashqari deploy kerak bo'lganda) bir bosishda ishga tushirish mumkin.
Bildirishnomalar
- name: Telegram
if: failure()
run: |
curl -s "https://api.telegram.org/bot${{ secrets.TG_TOKEN }}/sendMessage" \
-d chat_id=${{ secrets.TG_CHAT }} \
-d text="❌ Deploy muvaffaqiyatsiz: ${{ github.repository }} @ ${{ github.sha }}"
if: failure() — faqat oldingi qadam xato bo'lganda. if: success(), if: always() ham bor.
Nima uchun shunday?
Nima uchun deploy ni avtomatlashtirish shunchalik muhim — 10 daqiqalik qo'lda ish katta muammomi?
Muammo vaqtda emas — chastota va ishonchda. Qo'lda deploy qo'rqinchli: qadamlar unutiladi, kim nima qilgani noma'lum, va shuning uchun deploy kam-kamdan qilinadi — katta to'plamlarda, ya'ni xavfliroq (33-dars). Avtomatik deploy esa zerikarli va oldindan aytib bo'ladigan: har safar bir xil qadamlar, testdan o'tgan kod, log da to'liq tarix. Natijada jamoa kuniga bir necha marta xotirjam deploy qiladi, va har bir deploy kichik. "Deploy qilish qo'rqinchli bo'lsa — uni tez-tez qiling" — DevOps madaniyatining asosiy g'oyalaridan biri.
Xulosa
Eslab qoling:
- Zanjir: test → build → deploy;
needs:— test o'tmasa deploy yo'q - VPS: SSH kalit → Secrets →
rsync+ssh+systemctl restart→ health check - Docker: image → GHCR → serverda
compose pull && up -d - Vercel/Netlify — GitHub ga ulash, avtomatik deploy va PR preview
concurrency— bir vaqtda bitta deployenvironment: production— tasdiq, deploy tarixi, alohida sirlartags: ["v*"]— faqat relizlarni deploy- Rollback: revert → avtomatik deploy; yoki Re-run
if: failure()— xatoda bildirishnoma
Keyingi dars
40-dars: GitHub Pages — statik saytni deploy qilish