GitHub Actions — avtomatik test va deploy

~25 daq · Git · GitHub Imkoniyatlari

Muammodan boshlaylik

CI ishlayapti (38-dars): har PR da testlar. Lekin deploy hali qo'lda:

  1. Serverga SSH
  2. git pull
  3. npm ci && npm run build
  4. sudo 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

  1. Deploy uchun alohida SSH kalit (parolsiz):
ssh-keygen -t ed25519 -f deploy_key -N "" -C "github-actions"
  1. Ochiq kalit (deploy_key.pub) — serverdagi deploy foydalanuvchisining ~/.ssh/authorized_keys iga
  2. Yopiq kalit (deploy_key) — GitHub repozitoriy → Settings → Secrets and variables → Actions → New secret: SSH_KEY (44-dars)
  3. 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 tushmaydi
  • concurrency — bir vaqtda faqat bitta deploy; ikki merge ketma-ket bo'lsa — navbat
  • environment: production — GitHub da "Environments" bo'limida deploy tarixi; qo'shimcha himoya qo'yish mumkin (pastga qarang)
  • ${{ secrets.X }} — sirlar logda *** bo'lib ko'rinadi
  • rsync, 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 main dan 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:

  1. Eng tez — git revert (28-dars) → push → workflow avtomatik oldingi holatni deploy qiladi
  2. Qo'lda qayta ishga tushirish — Actions → oldingi muvaffaqiyatli run → Re-run all jobs (eski commit dan qayta deploy)
  3. Docker — oldingi image tegini deploy qilish

[!TIP] Workflow ga workflow_dispatch qo'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 deploy
  • environment: production — tasdiq, deploy tarixi, alohida sirlar
  • tags: ["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