GitHub Actions — CI/CD asoslari, workflow fayli tuzilishi

~20 daq · Git · GitHub Imkoniyatlari

Muammodan boshlaylik

PR ochildi. Reviewer kodni o'qidi, yaxshi ko'rindi — merge. 10 daqiqadan keyin main buzilgan: testlar o'tmaydi. Hech kim ularni ishga tushirmagan edi — muallif "kichik o'zgarish" deb o'ylagan, reviewer esa testlarni lokalda ishga tushirishni xayoliga ham keltirmagan.

Kerak — har bir push va PR da testlarni avtomatik ishga tushiradigan, natijani PR sahifasida ko'rsatadigan va testlar o'tmasa merge ni bloklaydigan tizim. Bu — CI (Continuous Integration). GitHub da u o'rnatilgan: GitHub Actions.


CI/CD nima?

  • CI (Continuous Integration — uzluksiz integratsiya) — har bir o'zgarish avtomatik tekshiriladi: build, testlar, lint
  • CD (Continuous Delivery/Deployment — uzluksiz yetkazish) — tekshirilgan kod avtomatik deploy qilinadi (39-dars)
 git push ──→ GitHub ──→ Actions runner (bulutdagi virtual mashina)
                              │
                              ├─ kodni olish
                              ├─ npm install
                              ├─ lint
                              ├─ test
                              └─ ✅ yoki ❌ → PR sahifasida

Ommaviy repozitoriylar uchun — bepul; yopiq repozitoriylar uchun — oyiga 2000 daqiqa bepul.


Birinchi workflow

Workflow — .github/workflows/ papkasidagi YAML fayl:

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Kodni olish
        uses: actions/checkout@v4

      - name: Node.js o'rnatish
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm

      - name: Bog'liqliklar
        run: npm ci

      - name: Lint
        run: npm run lint

      - name: Testlar
        run: npm test
git add .github/workflows/ci.yml
git commit -m "ci: testlar uchun GitHub Actions"
git push

Repozitoriy → Actions tabi — workflow ishlayotganini va har bir qadamning jonli logini ko'rasiz.


Tuzilma

Workflow (ci.yml)
 ├── on:          QACHON ishga tushadi (trigger)
 └── jobs:        NIMA qilinadi
      ├── test:   job — alohida virtual mashinada
      │    ├── runs-on:  qaysi OS da
      │    └── steps:    ketma-ket qadamlar
      │         ├── uses:  tayyor action
      │         └── run:   shell buyruq
      └── build:  boshqa job (parallel yoki ketma-ket)

on — trigger lar

on:
  push:
    branches: [main]              # main ga push
    paths: ["src/**"]             # faqat src o'zgarsa (37-dars)
  pull_request:                   # har qanday PR
    branches: [main]              # main ga qaratilgan
  schedule:
    - cron: "0 3 * * *"           # har kuni 03:00 UTC (Linux kursi, 40-dars)
  workflow_dispatch:              # Actions tabida qo'lda "Run workflow" tugmasi
  release:
    types: [published]            # GitHub Release chiqqanda

jobs va steps

  • job — alohida, toza virtual mashina. Job lar standart holatda parallel ishlaydi
  • step — job ichidagi ketma-ket qadam. Bitta qadam xato bersa — job to'xtaydi (❌)
  • uses: — tayyor action (boshqalar yozgan qayta ishlatiladigan qadam) — GitHub Marketplace da minglab
  • run: — oddiy shell buyruq(lar)
      - name: Bir nechta buyruq
        run: |
          npm ci
          npm run build
          ls -la dist/

runs-on

Qiymat OS
ubuntu-latest Linux — eng tez va eng ko'p ishlatiladigan
windows-latest Windows
macos-latest macOS (iOS build lar uchun)

Bir nechta job

jobs:
  lint:
    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 run lint

  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

  build:
    needs: [lint, test]            # lint VA test muvaffaqiyatli bo'lgandan keyin
    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 run build

lint va test — parallel, build — ikkalasidan keyin (needs).

Matrix — bir nechta versiyada

  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: [20, 22, 24]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci && npm test

Uchta parallel job — har bir Node versiyasi uchun. Kutubxonalar uchun foydali.


Xizmatlar — testlar uchun baza

  test:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8.4
        env:
          MYSQL_ROOT_PASSWORD: test
          MYSQL_DATABASE: dokon_test
        ports: ["3306:3306"]
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=5s
          --health-retries=10
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test
        env:
          DATABASE_URL: mysql://root:test@127.0.0.1:3306/dokon_test

Haqiqiy MySQL — Docker konteynerda (Docker kursi), har bir test uchun toza.


PR va branch protection

PR sahifasida:

✅ CI / lint (pull_request)     Successful in 32s
✅ CI / test (pull_request)     Successful in 1m 14s
❌ CI / build (pull_request)    Failing after 45s   Details

Details — to'liq log. Repozitoriy Settings → Branches → main → Require status checks to pass → lint, test, build ni tanlang (23-dars). Endi qizil PR ni merge qilib bo'lmaydi.

README badge

![CI](https://github.com/otabek/dokon/actions/workflows/ci.yml/badge.svg)

README da yashil "CI: passing" belgisi.


Debug va maslahatlar

  • Lokalda avval ishlating: CI dagi npm test — lokal npm test bilan bir xil bo'lishi kerak
  • npm ci, npm install emas — package-lock.json bo'yicha aniq versiyalar
  • cache: npm — node_modules keshlash, har safar noldan yuklamaslik: 2 daqiqa → 20 soniya
  • Action versiyalarini qotiring: @v4, @main emas
  • YAML chekinishi — bo'shliqlar muhim; xatoda workflow umuman ishga tushmaydi. VS Code ning "GitHub Actions" kengaytmasi xatolarni ko'rsatadi
  • Lokalda workflow sinash — act vositasi (Docker orqali)

[!WARNING] Ommaviy repozitoriyda begona PR (fork dan) ham workflow ni ishga tushiradi. GitHub fork PR lariga sirlarni (44-dars) bermaydi — bu himoya. pull_request_target trigger ini esa nima qilayotganingizni aniq bilmasangiz ishlatmang: u fork kodiga sirlarga kirish huquqini berishi mumkin.


Nima uchun shunday?

Nima uchun testlarni dasturchining kompyuterida emas, alohida serverda ishga tushirish kerak?

Uch sabab. Unutish: odam testlarni ishga tushirishni unutadi, CI — hech qachon. Toza muhit: lokal kompyuterda testlar "ishlaydi", chunki u yerda tasodifan global o'rnatilgan paket yoki eski .env bor; CI har safar noldan boshlaydi — u "faqat mening kompyuterimda ishlaydi" muammolarini darhol ushlaydi. Shaffoflik: natija PR da hammaga ko'rinadi — reviewer kodni o'qishdan oldin uning ishlashini biladi. Natijada main doimo "yashil" bo'ladi — va bu GitHub Flow (33-dars) ning "main doim deploy ga tayyor" va'dasini amalga oshiradi.


Xulosa

Eslab qoling:

  • CI — har bir o'zgarishni avtomatik tekshirish; CD — avtomatik deploy
  • Workflow — .github/workflows/*.yml
  • on: — push, pull_request, schedule, workflow_dispatch
  • jobs: — alohida mashinalar, parallel; needs: — ketma-ketlik
  • steps: — uses: (tayyor action) yoki run: (buyruq)
  • actions/checkout, actions/setup-node + cache: npm, npm ci
  • matrix — bir nechta versiya; services: — testlar uchun baza
  • Branch protection — "Require status checks" — qizil PR merge bo'lmaydi

Keyingi dars

39-dars: GitHub Actions — avtomatik test va deploy