2025-01-19

GitHub CI/CD bilan ishlash

CI/CD (Continuous Integration va Continuous Deployment) CI - kod o'zgarishlarini avtomatik tekshirish va birlashtirish, CD esa tekshirilgan kodni avtomatik tarqatish jarayoni. GitHub Actions orqali bu jarayonlarni to'liq avtomatlashtirish mumkin. Bu nafaqat vaqtni tejaydi, balki xatoliklarni ham kamaytiradi va ishlab chiqish jarayonini tezlashtiradi. Bunda sizga Github sizga VM (virtual machine) beradi, huddi o'zingizni kompyutertizdagi kabi steplarni yozasiz u shu ketma ketlikda bajaradi, bu orqali siz, Mobile, web, desktop va yana boshqa turli sohalarda qo'lda qiladigan ishizni automate qilib ishlatishiz mumkin. Github sizni o'rnizga Playmarket yoki AppStorega app release qilishi mumkin :) Lekin biz hozir Node misolida ko'ramiz.

CI/CD workflow

CI va CD nima va ularning farqi

Continuous Integration (CI) - kod o'zgarishlarini avtomatik tekshirish, build qilish va test qilish jarayoni. Har safar yangi kod push qilinganda, tizim avtomatik ravishda:

  • Kodni lint qiladi (sintaksis tekshiruvi)
  • Testlarni ishga tushiradi
  • Build qiladi (production uchun tayyorlaydi)
  • Xavfsizlik tekshiruvlarini o'tkazadi

Continuous Deployment (CD) - tekshirilgan va tayyor kodni avtomatik ravishda production serverga joylashtirish jarayoni. CD quyidagi ishlarni bajaradi:

  • CI muvaffaqiyatli tugaganidan keyin ishga tushadi
  • Kodni production serverga deploy qiladi
  • Database migration'larni ishga tushiradi
  • Serverlarni restart qiladi
  • Health check'lar o'tkazadi

GitHub Actions asoslari

GitHub Actions - GitHub'da workflow'lar yaratish va avtomatik ishlarni bajarish uchun platforma. Workflow'lar YAML formatida yoziladi va .github/workflows/ papkasida saqlanadi.

Asosiy tushunchalar:

  • Workflow - avtomatik jarayon (fayl)
  • Job - workflow ichidagi ish birligi
  • Step - job ichidagi har bir qadam
  • Action - tayyor ish birligi (reusable)
  • Runner - workflow'ni ishga tushiradigan server

Birinchi workflow yaratish

GitHub Actions workflow yaratish uchun .github/workflows/ papkasida YAML fayl yaratamiz. Quyidagi misol Node.js loyihasi uchun asosiy CI workflow:

# .github/workflows/ci.yml
name: CI
 
on:
  push:
    branches: [ dev ] # qaysi branchga push qilinsa ishlashi
  pull_request:
    branches: [ pre-release ] # qaysi branchdan pull request olishi
 
jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      
    - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"
        
    - name: Install dependencies
      run: npm ci  # dependency larni o'rnatish npm i --force agar majburiy bo'lsa
      
    - name: Run linter
      run: npm run lint # build qilishdan oldin, linting qilib tekshirish
      
    - name: Run tests
      run: npm test # test yozilgan bo'lsa ularni run qilish
      
    - name: Build project
      run: npm run build

Workflow trigger'lar

Workflow'lar turli hodisalar bilan ishga tushishi mumkin:

on:
  # Push hodisalari
  push:
    branches: [ main, develop ]
    paths: [ 'src/**', 'package.json' ]
    
  # Pull request hodisalari
  pull_request:
    branches: [ main ]
    types: [ opened, synchronize, reopened ]
    
  # Manual ishga tushirish
  workflow_dispatch:
    inputs:
      environment:
        description: 'Deploy environment'
        required: true
        default: 'staging'
        type: choice
        options:
        - staging
        - production
        
  # Vaqt asosida (cron)
  schedule:
    - cron: '0 2 * * 1'  # har dushanba 02:00 da
    
  # Boshqa workflow tugaganidan keyin
  workflow_run:
    workflows: ["CI"]
    types: [completed]

Environment va Secret'lar

Xavfsiz ma'lumotlarni saqlash va boshqarish:

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production  # GitHub'da environment yaratish kerak
    
    steps:
    - name: Deploy to production
      env:
        API_KEY: ${{ secrets.API_KEY }}
        DATABASE_URL: ${{ secrets.DATABASE_URL }}
      run: |
        echo "Deploying with API key: $API_KEY"
        # Deploy logic here

Secret'lar GitHub repository settings > Secrets and variables > Actions da qo'shiladi.

Matrix strategy va parallel jobs

Bir nechta versiya yoki platformada parallel test qilish (odatda cross-platform ishlar qilish kerak bo'lsa):

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [18.x, 20.x]
        include:
          - os: ubuntu-latest
            node-version: 21.x
            experimental: true
            
    steps:
    - name: Test on ${{ matrix.os }} with Node ${{ matrix.node-version }}
      run: |
        echo "OS: ${{ matrix.os }}"
        echo "Node: ${{ matrix.node-version }}"
        if [ "${{ matrix.experimental }}" == "true" ]; then
          echo "Running experimental tests"
        fi

Deployment workflow

Production'ga avtomatik deploy qilish (vercel yo'li):

name: Deploy to Production
 
on:
  push:
    branches: [ main ]
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    needs: [test, build]  # boshqa job'lar tugaganidan keyin
    
    steps:
    - name: Checkout
      uses: actions/checkout@v4
      
    - name: Deploy to Vercel
      uses: amondnet/vercel-action@v25
      with:
        vercel-token: ${{ secrets.VERCEL_TOKEN }}
        vercel-org-id: ${{ secrets.ORG_ID }}
        vercel-project-id: ${{ secrets.PROJECT_ID }}
        working-directory: ./
        
    - name: Notify deployment
      uses: 8398a7/action-slack@v3
      with:
        status: ${{ job.status }}
        channel: '#deployments'
        webhook_url: ${{ secrets.SLACK_WEBHOOK }}

Real-world deployment misollari

Quyidagi misollar haqiqiy loyihalarda ishlatiladigan deployment workflow'lar:

DEV server'ga avtomatik deploy

Bu workflow dev-for-test branch'ga push qilinganda DEV server'ga avtomatik deploy qiladi:

name: 🚀 Deploy to DEV Server (dev-for-test)
 
on:
  push:
    branches:
      - dev-for-test
 
jobs:
  deploy-dev:
    runs-on: ubuntu-latest
 
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
 
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
 
      - name: Install dependencies
        run: npm install --force
 
      - name: Build project
        run: npm run build:dev
 
      - name: Create ZIP archive
        run: zip -r build.zip build
 
      - name: Upload ZIP to server
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.DEV_SERVER_HOST }}
          username: ${{ secrets.DEV_SERVER_USER }}
          key: ${{ secrets.DEV_SSH_KEY }}
          port: 22
          source: "build.zip"
          target: "/var/www/project-name"
 
      - name: Unzip and deploy on server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.DEV_SERVER_HOST }}
          username: ${{ secrets.DEV_SERVER_USER }}
          key: ${{ secrets.DEV_SSH_KEY }}
          port: 22
          script: |
            unzip -o /var/www/project-name/build.zip -d /var/www/project-name
            echo "✅ Deployed from dev-for-test branch to DEV server"
            
      - name: Send Telegram message
        run: |
          curl -s -X POST https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage \
            -d chat_id=${{ secrets.TELEGRAM_CHAT_ID }} \
            -d message_thread_id=${{ secrets.TELEGRAM_DEPLOYMENTS_THREAD_ID }} \
            -d text="✅ *Deployment to DEV complete!*%0ARepo: ${{ github.repository }}%0ABranch: ${{ github.ref_name }}%0ACommit: ${{ github.sha }}" \
            -d parse_mode=Markdown

Har bir commit'ni kuzatish

Bu workflow har bir push'da commit ma'lumotlarini Telegram'ga yuboradi:

name: 📝 Log Every Commit
 
on:
  push:
 
jobs:
  log-commit:
    runs-on: ubuntu-latest
 
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
 
      - name: Send Telegram commit log
        run: |
          COMMIT_MESSAGE=$(git log -1 --pretty=%s)
          MESSAGE="📦 New Commit to *${{ github.repository }}*
          Branch: \`${{ github.ref_name }}\`
          By: \`${{ github.actor }}\`
          Message: _${COMMIT_MESSAGE}_
          [View Commit](https://github.com/${{ github.repository }}/commit/${{ github.sha }})"
 
          curl -s -X POST https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage \
            -d chat_id=${{ secrets.TELEGRAM_CHAT_ID }} \
            -d message_thread_id=${{ secrets.TELEGRAM_COMMITS_THREAD_ID }} \
            -d text="$MESSAGE" \
            -d parse_mode=Markdown

Bu misollarda quyidagi xususiyatlar ko'rsatilgan:

  • SSH orqali server'ga fayl yuklash (SCP action)
  • Server'da buyruqlar bajarish (SSH action)
  • Telegram bot orqali xabardor qilish
  • ZIP arxiv yaratish va yuklash
  • Git ma'lumotlarini olish va ishlatish
  • Thread ID orqali xabarlarni guruhlash

Conditional steps va error handling

Shartli ishlar va xatoliklarni boshqarish:

steps:
- name: Run tests
  id: test
  run: npm test
  continue-on-error: true
  
- name: Upload test results
  if: always()  # har doim ishlaydi
  uses: actions/upload-artifact@v4
  with:
    name: test-results
    path: test-results/
    
- name: Notify on failure
  if: failure()  # faqat xatolik bo'lsa
  run: |
    echo "Tests failed!"
    # Slack notification yoki boshqa action
    
- name: Deploy only if tests pass
  if: steps.test.outcome == 'success'
  run: npm run deploy

Caching va performance

Workflow'lar tezroq ishlashi uchun cache'lar:

steps:
- name: Cache dependencies
  uses: actions/cache@v3
  with:
    path: |
      ~/.npm
      node_modules
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-
      
- name: Cache build artifacts
  uses: actions/cache@v3
  with:
    path: |
      .next/cache
      dist
    key: ${{ runner.os }}-build-${{ github.sha }}
    restore-keys: |
      ${{ runner.os }}-build-

Self-hosted runners

O'z serverlaringizda runner'lar ishlatish:

jobs:
  deploy:
    runs-on: self-hosted  # GitHub runner o'rniga
    environment: production
    
    steps:
    - name: Deploy to custom server
      run: |
        # O'z serveringizda deploy logic
        docker-compose up -d
        systemctl restart myapp

Self-hosted runner'lar maxsus serverlarda, GPU'li mashinalarda yoki maxfiy ma'lumotlar bilan ishlash uchun foydali.

Monitoring va notification'lar

Workflow'lar holatini kuzatish va xabardor qilish:

- name: Notify Slack
  if: always()
  uses: 8398a7/action-slack@v3
  with:
    status: ${{ job.status }}
    channel: '#ci-cd'
    webhook_url: ${{ secrets.SLACK_WEBHOOK }}
    fields: repo,message,commit,author,action,eventName,ref,workflow
    
- name: Create GitHub issue on failure
  if: failure()
  uses: actions/github-script@v7
  with:
    script: |
      github.rest.issues.create({
        owner: context.repo.owner,
        repo: context.repo.repo,
        title: `CI Failed: ${context.workflow}`,
        body: `Workflow failed on commit ${context.sha}`
      })

Foydali GitHub Actions

Ko'p ishlatiladigan va foydali action'lar:

# Asosiy action'lar
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/setup-python@v4
- uses: actions/cache@v3
 
# Deploy uchun
- uses: peaceiris/actions-gh-pages@v3  # GitHub Pages
- uses: amondnet/vercel-action@v25     # Vercel
- uses: appleboy/ssh-action@v1.0.3     # SSH orqali deploy
 
# Notification'lar
- uses: 8398a7/action-slack@v3         # Slack
- uses: actions/github-script@v7       # GitHub API
 
# Testing va quality
- uses: codecov/codecov-action@v3      # Code coverage
- uses: sonarqube-quality-gate-action@v1.0.1  # SonarQube

Best practices

GitHub Actions bilan ishlashda quyidagi qoidalarga rioya qiling:

  • Workflow'lar qisqa va aniq bo'lsin (30 daqiqadan kam)
  • Matrix strategy'dan parallel testlar uchun foydalaning
  • Cache'lar ishlatib performance'ni oshiring
  • Secret'larni to'g'ri boshqaring va environment'lar ishlating
  • Workflow'lar o'rtasida dependency'lar aniq belgilang
  • Artifact'lar va log'lar to'g'ri saqlang
  • Security scanning va dependency check'lar qo'shing
  • Workflow'lar versiyalarini yangilab turing

GitHub Actions orqali CI/CD jarayonlarini to'liq avtomatlashtirish mumkin. Bu nafaqat vaqtni tejaydi, balki xatoliklarni ham kamaytiradi va ishlab chiqish jarayonini ancha tezlashtiradi. Kichik loyihalardan boshlab, katta korporativ tizimlargacha barcha darajada foydalanish mumkin.

Yanada ko'proq o'rganing

2025 · nnolan