CI/CD — GitHub Actions bilan avtomatik build
Muammodan boshlaylik
Hozirgi deploy jarayoni:
- Kompyuterda
docker build docker push(agar unutilmasa)- Serverga SSH,
docker compose pull && up -d
Muammolar: kimdir testlarni ishga tushirmay push qildi; Mac da arm64 image yasaldi (38-dars); yangi jamoa a'zosi tartibni bilmaydi; kimning kompyuteridagi qaysi o'zgarishlar image ga tushdi — noma'lum.
CI/CD — bularning hammasini avtomatlashtiradi: main ga push → testlar → build → registry → deploy. Har safar bir xil, insondan mustaqil.
GitHub Actions asoslari
.github/workflows/ papkasidagi YAML fayllar. GitHub ularni o'z serverlarida (runner) ishga tushiradi.
name: CI # nomi
on: # qachon
push:
branches: [main]
pull_request:
jobs: # nima
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: echo "Salom"
1-qadam: testlar
# .github/workflows/docker.yml
name: Docker
on:
push:
branches: [main]
tags: ["v*"]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Test image ni yasash
uses: docker/build-push-action@v6
with:
context: .
target: dev
load: true
tags: dokon-api:test
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Testlar
run: docker run --rm dokon-api:test npm test
target: dev— dev bog'liqliklari bor bosqich (testlar uchun)load: true— image ni runner ning lokal Docker iga yuklashcache-from/to: type=gha— qatlam keshini GitHub Actions keshida saqlash. Busiz har bir run noldan build — 5 daqiqa; kesh bilan — 30 soniya
Baza kerak bo'lgan integratsion testlar uchun: docker compose -f compose.test.yaml up --abort-on-container-exit --exit-code-from api.
2-qadam: build va GHCR ga push
build:
needs: test # testlar o'tgandan keyingina
if: github.event_name == 'push' # PR larda push yo'q
runs-on: ubuntu-latest
permissions:
contents: read
packages: write # GHCR ga yozish
outputs:
tag: ${{ steps.meta.outputs.version }}
steps:
- uses: actions/checkout@v4
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=sha,prefix=sha-
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}
- uses: docker/build-push-action@v6
with:
context: .
target: production
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
GITHUB_TOKEN— GitHub avtomatik beradi, alohida token yaratish shart emas;packages: writeruxsati yetarlimetadata-action— 38-darsdagi teglash strategiyasi avtomatik:mainga push →sha-a3f9c2b,latestv1.4.2tegi →1.4.2,1.4
platforms— amd64 + arm64 (QEMU orqali)
Versiya chiqarish:
git tag v1.4.2
git push origin v1.4.2
3-qadam: xavfsizlik skaneri
- name: Trivy skaner
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: ghcr.io/${{ github.repository }}:sha-${{ github.sha }}
severity: CRITICAL,HIGH
exit-code: "1"
ignore-unfixed: true
CRITICAL zaiflik bo'lsa — pipeline to'xtaydi, deploy bo'lmaydi (39-dars).
[!INFO]
sha-${{ github.sha }}— to'liq SHA;metadata-actionesa standart holatda qisqa SHA yasaydi. Skaner uchunsteps.meta.outputs.tagsdagi birinchi tegni ishlating yokimetadata-actiondatype=sha,format=longni qo'shing.
4-qadam: serverga deploy
deploy:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production # GitHub da qo'lda tasdiqlash qo'shish mumkin
steps:
- uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_HOST }}
username: deploy
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
cd /opt/dokon
export API_TAG=${{ needs.build.outputs.tag }}
docker compose pull api
docker compose up -d api
docker image prune -f
Serverdagi compose.yaml da:
services:
api:
image: ghcr.io/firdavsdev07/dokon-api:${API_TAG:-latest}
Repo Settings → Secrets and variables → Actions da: SERVER_HOST, SERVER_SSH_KEY (faqat deploy uchun alohida kalit, alohida cheklangan deploy foydalanuvchisi bilan).
Server tayyorlash va deploy tafsilotlari — 42-dars.
Butun oqim
git push main
│
▼
[ test ] dev image → npm test
│ ✓
▼
[ build ] amd64+arm64 → ghcr.io/...:sha-a3f9c2b, latest
│ ✓ └→ Trivy: CRITICAL yo'q
▼
[ deploy ] SSH → compose pull → up -d
│
▼
Production 🎉
PR da — faqat test. main da — hammasi. v* teg — versiyali image.
Nima uchun shunday?
Nima uchun avtomatlashtirish shunchalik muhim — qo'lda ehtiyotkorlik bilan qilsak bo'lmaydimi?
Chunki odamlar izchil emas: charchaydi, shoshiladi, qadamni unutadi, "kichik o'zgarish, test shart emas" deydi. CI/CD — jarayonni kodga aylantiradi: har bir deploy bir xil qadamlardan o'tadi, testdan o'tmagan kod production ga yetmaydi, har bir image qaysi commit dan yasalgani aniq (sha- teg), va jarayonning o'zi Git da — ko'rib chiqiladi va yaxshilanadi. Natija paradoksal: avtomatlashtirilgan deploy tez-tez va kam qo'rquv bilan qilinadi — kichik o'zgarishlar, kam xavf.
Xulosa
Eslab qoling:
.github/workflows/*.yml:on→jobs→stepsdocker/setup-buildx-action,login-action,metadata-action,build-push-action- Kesh:
cache-from/to: type=gha— build tezligi uchun muhim - GHCR:
GITHUB_TOKEN+permissions: packages: write - Teglar avtomatik:
sha-, semver,latest needs:— test → build → deploy zanjiri; PR da faqat test- Trivy — CRITICAL da to'xtatish
- Deploy — SSH +
compose pull+up -d; sirlar — GitHub Secrets da
Keyingi dars
42-dars: Serverga deploy — VPS da Compose bilan ishga tushirish