CI/CD — GitHub Actions bilan avtomatik deploy
Muammodan boshlaylik
Jamoada 4 dasturchi. Har kim o'z kompyuterida test qiladi (yoki qilmaydi). Juma kuni kimdir TypeScript xatosi bor kodni main ga qo'shdi — build yiqildi. Boshqa safar testlar o'tmaydigan o'zgarish production ga chiqdi. Deploy esa — 68-darsdagi 6 ta buyruqni qo'lda, tartibni adashtirmasdan bajarish.
CI/CD nima?
| Ma'nosi | |
|---|---|
| CI (Continuous Integration) | Har bir push va Pull Request da avtomatik: lint, tur tekshiruvi, test, build |
| CD (Continuous Deployment) | main ga qo'shilgan va tekshiruvlardan o'tgan kod avtomatik production ga |
push / PR ──▶ lint ──▶ typecheck ──▶ test ──▶ build ──▶ (main) deploy
✗ xato — to'xtaydi, merge va deploy yo'q
Hayotiy o'xshatma
Aeroportdagi parvoz oldi tekshiruvi. Har bir samolyot — uchuvchi qanchalik tajribali bo'lmasin — bir xil ro'yxat bo'yicha tekshiriladi: yoqilg'i, dvigatel, rul. Birorta band bajarilmasa — parvoz yo'q. Tekshiruvni inson emas, tartib boshqaradi.
CI workflow
# .github/workflows/ci.yml
name: CI
on:
pull_request:
push:
branches: [main]
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
tekshirish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- name: Lint
run: npm run lint
- name: TypeScript
run: npx tsc --noEmit
- name: Unit testlar
run: npx vitest run
- uses: actions/cache@v4
with:
path: .next/cache
key: nextjs-${{ hashFiles('package-lock.json') }}-${{ hashFiles('**/*.ts', '**/*.tsx') }}
restore-keys: nextjs-${{ hashFiles('package-lock.json') }}-
- name: Build
run: npm run build
env:
DATABASE_URL: postgresql://fake:fake@localhost:5432/fake
AUTH_SECRET: ci-uchun-soxta-maxfiy-kalit-kamida-32-belgi
NEXT_TELEMETRY_DISABLED: 1
concurrency— yangi push kelsa, eski ishga tushirish bekor qilinadicache: npmva.next/cache— keyingi build lar ancha tez (kesh build dan oldin tiklanadi)- Build uchun soxta env qiymatlari — haqiqiy kalitlar CI ga kerak emas (agar build vaqtida bazaga murojaat qilinmasa)
E2E — alohida job
e2e:
runs-on: ubuntu-latest
needs: tekshirish
services:
postgres:
image: postgres:17-alpine
env:
POSTGRES_PASSWORD: test
POSTGRES_DB: dokon_test
ports: ["5432:5432"]
options: --health-cmd pg_isready --health-interval 5s --health-retries 10
env:
DATABASE_URL: postgresql://postgres:test@localhost:5432/dokon_test
AUTH_SECRET: ${{ secrets.E2E_AUTH_SECRET }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22, cache: npm }
- run: npm ci
- run: npx prisma migrate deploy && npx prisma db seed
- run: npx playwright install --with-deps chromium
- run: npx playwright test
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with: { name: playwright-report, path: playwright-report/ }
Branch protection
GitHub → Settings → Branches → Add rule (main):
- ✅ Require a pull request before merging
- ✅ Require status checks to pass —
tekshirish,e2e - ✅ Require branches to be up to date
Endi CI o'tmagan kod main ga tushmaydi.
CD — Vercel
Vercel GitHub bilan ulangan bo'lsa (66-dars), deploy avtomatik — alohida workflow shart emas. CI faqat sifatni tekshiradi; branch protection tufayli main ga faqat tekshiruvdan o'tgan kod tushadi va production deploy ham faqat shu koddan bo'ladi.
CD — o'z server (VPS)
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
concurrency: production
steps:
- name: Serverga deploy
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_KEY }}
script: |
set -e
cd /var/www/dokon
git pull --ff-only
npm ci
npx prisma migrate deploy
npm run build
pm2 reload dokon
environment: production — GitHub da Environments → production → "Required reviewers": deploy bitta tugma bilan tasdiqlangandan keyin boshlanadi (ixtiyoriy).
Docker image bilan — yaxshiroq
Build ni CI da qilib, tayyor image ni serverga yuborish — serverning resurslari band bo'lmaydi va har bir versiya aniq belgilangan:
- 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 }}
build-args: NEXT_PUBLIC_SITE_URL=https://dokon.uz
cache-from: type=gha
cache-to: type=gha,mode=max
Serverda: docker compose pull web && docker compose up -d web. Rollback — oldingi sha tag iga qaytish.
[!WARNING] SSH kalit va boshqa maxfiy qiymatlar — faqat Settings → Secrets and variables → Actions da. Ularni workflow fayliga yoki loglarga hech qachon yozmang. Deploy uchun alohida, cheklangan huquqli foydalanuvchi va alohida SSH kalit yarating.
Migratsiyalar xavfsizligi
Deploy paytida bir lahza eski kod va yangi baza (yoki aksincha) birga ishlaydi. Migratsiyalarni orqaga mos yozing:
- Avval ustun qo'shiladi (ixtiyoriy) — eski kod uni e'tiborsiz qoldiradi
- Yangi kod deploy qilinadi
- Keyingi deploy da eski ustun o'chiriladi
Ustunni bitta deploy da o'chirib, nomini o'zgartirish — deploy davomida xatolar.
[!TIP] Dependabot yoki Renovate ni yoqing — ular bog'liqliklar yangilanishi uchun avtomatik Pull Request ochadi, CI esa yangilanish hech narsani buzmaganini tekshiradi. Xavfsizlik yamoqlari (masalan, Next.js zaifliklari — 42-dars) kechikmaydi.
Tez-tez uchraydigan xatolar
1. CI da haqiqiy production kalitlari
Kerak emas va xavfli. Build uchun soxta qiymatlar; E2E uchun test kalitlari.
2. Build vaqtida bazaga murojaat
Statik sahifa generateStaticParams da bazadan o'qisa — CI da baza kerak. Bunday sahifalar uchun CI da test bazasi yoki dinamik render.
3. set -e siz deploy skripti
npm run build xato berdi, lekin skript davom etib pm2 reload qildi — sayt buzilgan holatda.
Xulosa
CI: har PR/push da lint → tsc → vitest → build; e2e — alohida job, test baza bilan
concurrency, npm va .next/cache keshi — tezlik
Branch protection — CI o'tmasa merge yo'q
Vercel — CD avtomatik; VPS — ssh-action yoki Docker image (ghcr.io + sha tag)
Secrets — GitHub Secrets; environment: production — tasdiqlash
set -e; migratsiyalar orqaga mos
Keyingi bo'lim
70-dars: Internationalization — next-intl bilan ko'p tilli ilova
Ilg'or mavzular: o'zbek, rus va ingliz tillarida sayt — URL, SEO va server komponentlar bilan.