18-bo‘lim

Hooks va GitHub Actions

Git hooks bilan lokal tekshiruvlar va GitHub Actions bilan CI/CD quvurini qurish.

🕑 14 daqiqa o‘qish 📄 652 so‘z 👁 5 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Git hooks
  2. pre-commit - kommitdan oldin tekshirish
  3. commit-msg - xabar formatini tekshirish
  4. pre-push - push dan oldin testlar
  5. Jamoa uchun hooks
  6. 1. core.hooksPath
  7. 2. Tayyor vositalar
  8. CI/CD nima?
  9. GitHub Actions
  10. Asosiy tushunchalar
  11. Ishga tushirish sabablari
  12. Baza bilan test
  13. Matritsa - bir necha versiyada sinash
  14. Deploy
  15. Foydali amallar
  16. Nishonlar (badges)
  17. Dependabot
  18. Bepul limitlar
  19. Xulosa

Qo'lda bajariladigan har bir tekshiruv - unutilishi mumkin bo'lgan qadam. Avtomatlashtirish buni hal qiladi.

Git hooks #

Hook - ma'lum voqea sodir bo'lganda avtomatik ishga tushadigan skript.

Terminal
ls .git/hooks/
Natija
applypatch-msg.sample     pre-commit.sample
commit-msg.sample         pre-push.sample
post-update.sample        pre-rebase.sample
prepare-commit-msg.sample update.sample

.sample qo'shimchasini olib tashlasangiz, hook faollashadi.

HookQachon ishlaydi
pre-commitKommitdan oldin
prepare-commit-msgXabar muharriri ochilishidan oldin
commit-msgXabar yozilgandan keyin
post-commitKommitdan keyin
pre-pushPush dan oldin
pre-rebaseRebase dan oldin
post-mergeMerge dan keyin
Hook nolga teng bo'lmagan kod qaytarsa

Amal bekor qilinadi. Bu asosiy mexanizm: tekshiruv o'tmasa, kommit yoki push bo'lmaydi.

pre-commit - kommitdan oldin tekshirish #

Terminal
nano .git/hooks/pre-commit
Terminal
#!/bin/bash

# Sahnadagi PHP fayllar
FAYLLAR=$(git diff --cached --name-only --diff-filter=ACM | grep '\.php$')

if [ -z "$FAYLLAR" ]; then
    exit 0
fi

XATO=0

for FAYL in $FAYLLAR; do
    # Sintaksis tekshiruvi
    php -l "$FAYL" > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo "Sintaksis xatosi: $FAYL"
        php -l "$FAYL"
        XATO=1
    fi

    # Konflikt belgilari qolib ketmadimi?
    if grep -q "^<<<<<<< " "$FAYL"; then
        echo "Konflikt belgisi topildi: $FAYL"
        XATO=1
    fi

    # Nosozlik tuzatish qoldiqlari
    if grep -qE "var_dump\(|dd\(|die\(" "$FAYL"; then
        echo "Nosozlik tuzatish kodi qoldi: $FAYL"
        XATO=1
    fi
done

if [ $XATO -ne 0 ]; then
    echo ""
    echo "Kommit bekor qilindi. Xatolarni tuzating."
    exit 1
fi

exit 0
Terminal
chmod +x .git/hooks/pre-commit

Endi sinab ko'ring:

Terminal
echo "<?php var_dump(\$x);" > test.php
git add test.php
git commit -m "test"
Natija
Nosozlik tuzatish kodi qoldi: test.php

Kommit bekor qilindi. Xatolarni tuzating.
Hook ni chetlab o'tish

Shoshilinch holatda:

Terminal
git commit --no-verify -m "shoshilinch tuzatish"

Lekin buni odat qilmang - hook ni yozishning ma'nosi yo'qoladi.

commit-msg - xabar formatini tekshirish #

Terminal
#!/bin/bash
# .git/hooks/commit-msg

XABAR=$(cat "$1")
NAQSH="^(feat|fix|docs|style|refactor|perf|test|chore)(\(.+\))?: .{10,}"

if ! echo "$XABAR" | grep -qE "$NAQSH"; then
    echo "Kommit xabari formati noto'g'ri."
    echo ""
    echo "To'g'ri format:  tur(soha): kamida 10 belgi tavsif"
    echo "Turlar: feat, fix, docs, style, refactor, perf, test, chore"
    echo ""
    echo "Misol: feat(savat): mahsulot sonini o'zgartirish qo'shildi"
    exit 1
fi

exit 0

pre-push - push dan oldin testlar #

Terminal
#!/bin/bash
# .git/hooks/pre-push

echo "Testlar ishga tushirilmoqda..."

php vendor/bin/phpunit --quiet

if [ $? -ne 0 ]; then
    echo "Testlar muvaffaqiyatsiz. Push bekor qilindi."
    exit 1
fi

echo "Barcha testlar o'tdi."
exit 0
Hook lar repozitoriyga kirmaydi

.git/hooks/ papkasi kommit qilinmaydi. Ya'ni sizning hook laringiz faqat sizda ishlaydi.

Jamoa uchun ikki yechim bor - quyida.

Jamoa uchun hooks #

1. core.hooksPath #

Terminal
mkdir -p .githooks
mv .git/hooks/pre-commit .githooks/
chmod +x .githooks/pre-commit

git config core.hooksPath .githooks
git add .githooks
git commit -m "chore: umumiy hook lar qo'shildi"

Har bir dasturchi bir marta shu buyruqni bajarishi kerak:

Terminal
git config core.hooksPath .githooks

Yoki composer.json ga qo'shing:

JSON
{
    "scripts": {
        "post-install-cmd": [
            "git config core.hooksPath .githooks"
        ]
    }
}

2. Tayyor vositalar #

Terminal
# PHP uchun
composer require --dev brainmaestro/composer-git-hooks

# JavaScript uchun
npm install --save-dev husky
npx husky init

CI/CD nima? #

Push dan ishlab chiqarishgacha Push kod yuborildi Qurish bog'liqliklar Testlar avtomatik sinov Tekshiruv lint, xavfsizlik Deploy serverga chiqarish Xato bo'lsa - jarayon to'xtaydi va dasturchi xabardor qilinadi CI - Continuous Integration · CD - Continuous Deployment
CI/CD - har bir push da avtomatik ishga tushadigan quvur

GitHub Actions #

Ish oqimlari .github/workflows/ papkasida YAML fayllar sifatida saqlanadi.

YAML
# .github/workflows/testlar.yml
name: Testlar

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  sinov:
    runs-on: ubuntu-latest

    steps:
      - name: Kodni olish
        uses: actions/checkout@v4

      - name: PHP o'rnatish
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
          extensions: mbstring, pdo_mysql
          coverage: none

      - name: Bog'liqliklarni o'rnatish
        run: composer install --prefer-dist --no-progress

      - name: Sintaksisni tekshirish
        run: find . -name "*.php" -not -path "./vendor/*" -exec php -l {} \;

      - name: Testlarni ishga tushirish
        run: vendor/bin/phpunit

Push qilganingizdan keyin Actions bo'limida natijani ko'rasiz.

Asosiy tushunchalar #

ElementMa'nosi
nameIsh oqimi nomi
onQachon ishga tushadi
jobsVazifalar (parallel bajariladi)
runs-onQaysi operatsion tizimda
stepsKetma-ket qadamlar
usesTayyor amal ishlatish
runBuyruq bajarish

Ishga tushirish sabablari #

YAML
on:
  push:                          # har qanday push
    branches: [main]
    paths: ['manba/**']          # faqat shu papka o'zgarsa

  pull_request:                  # PR ochilganda va yangilanganda
    types: [opened, synchronize]

  schedule:                      # jadval bo'yicha
    - cron: '0 3 * * *'          # har kuni 03:00 (UTC)

  workflow_dispatch:             # qo'lda ishga tushirish tugmasi

  release:
    types: [published]           # reliz chiqarilganda

Baza bilan test #

YAML
jobs:
  sinov:
    runs-on: ubuntu-latest

    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: sinov
          MYSQL_DATABASE: sinov_baza
        ports: ['3306:3306']
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=5

    steps:
      - uses: actions/checkout@v4

      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'

      - run: composer install

      - name: Migratsiyalar
        run: php tools/migrate.php
        env:
          DB_HOST: 127.0.0.1
          DB_DATABASE: sinov_baza
          DB_PASSWORD: sinov

      - name: Testlar
        run: vendor/bin/phpunit

Matritsa - bir necha versiyada sinash #

YAML
jobs:
  sinov:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        php: ['8.1', '8.2', '8.3']

    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
      - run: composer install
      - run: vendor/bin/phpunit

Bu 6 ta kombinatsiyani parallel sinaydi.

Deploy #

YAML
# .github/workflows/deploy.yml
name: Ishlab chiqarishga chiqarish

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'

    steps:
      - uses: actions/checkout@v4

      - name: Serverga yuborish
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_KALIT }}
          script: |
            cd /var/www/loyiha
            git pull origin main
            composer install --no-dev --optimize-autoloader
            php tools/migrate.php
            sudo systemctl reload php8.2-fpm
Maxfiy ma'lumotlarni YAML ga yozmang

Settings → Secrets and variables → Actions → New repository secret

YAML
password: ${{ secrets.DB_PASSWORD }}    # to'g'ri
password: "MeningParolim123"            # xato

GitHub sirlarni jurnal chiqishida avtomatik *** bilan yashiradi.

Foydali amallar #

YAML
# Kesh - qurish tezligini oshiradi
- name: Composer keshi
  uses: actions/cache@v4
  with:
    path: vendor
    key: ${{ runner.os }}-composer-${{ hashFiles('composer.lock') }}

# Fayllarni saqlash
- name: Hisobotni saqlash
  uses: actions/upload-artifact@v4
  with:
    name: test-hisoboti
    path: hisobotlar/

# PR ga izoh yozish
- name: Natijani yozish
  uses: actions/github-script@v7
  with:
    script: |
      github.rest.issues.createComment({
        issue_number: context.issue.number,
        owner: context.repo.owner,
        repo: context.repo.repo,
        body: 'Testlar muvaffaqiyatli o\'tdi.'
      })

Nishonlar (badges) #

README ga holat nishonini qo'shing:

MARKDOWN
![Testlar](https://github.com/husanboy/loyiha/actions/workflows/testlar.yml/badge.svg)

Bu jonli rasm - testlar buzilsa qizil bo'ladi.

Dependabot #

.github/dependabot.yml:

YAML
version: 2
updates:
  - package-ecosystem: "composer"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 5

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "monthly"

Dependabot eskirgan bog'liqliklar uchun avtomatik PR ochadi va xavfsizlik zaifliklari haqida ogohlantiradi.

Kichik loyihada nimadan boshlash kerak?

Bitta fayl yetarli:

  1. Sintaksis tekshiruvi
  2. Testlar (agar bo'lsa)
  3. Nishon README da

Bu allaqachon buzuq kodni main ga tushishdan saqlaydi. Deploy avtomatlashtirishni keyinroq qo'shasiz.

Bepul limitlar #

RepozitoriyLimit
Ochiq (public)Cheksiz
Yopiq (private)Oyiga 2000 daqiqa (bepul reja)

Windows va macOS runner lari Linux ga qaraganda ko'proq daqiqa "yeydi".

Amaliy topshiriq
  1. .git/hooks/pre-commit yarating: konflikt belgilarini tekshirsin.
  2. Uni chmod +x bilan bajariladigan qiling va sinang.
  3. commit-msg hook yozing: xabar kamida 10 belgi bo'lsin.
  4. Hook larni .githooks/ ga ko'chirib, core.hooksPath ni sozlang.
  5. .github/workflows/testlar.yml yarating.
  6. Unda kodni olish va sintaksis tekshiruvi bo'lsin.
  7. Push qiling va Actions bo'limida natijani ko'ring.
  8. Ataylab sintaksis xatosi bilan push qiling - qizil belgi paydo bo'lishini ko'ring.
  9. README ga holat nishonini qo'shing.
  10. Matritsa bilan ikki PHP versiyasida sinang.

Xulosa #

  • Git hooks - ma'lum voqeada avtomatik ishga tushadigan skriptlar.
  • Hook nolga teng bo'lmagan kod qaytarsa, amal bekor qilinadi.
  • pre-commit - sintaksis, konflikt belgilari, nosozlik tuzatish qoldiqlari.
  • .git/hooks/ kommit qilinmaydi - jamoa uchun core.hooksPath ishlating.
  • --no-verify hook ni chetlab o'tadi, lekin buni odat qilmang.
  • GitHub Actions - .github/workflows/ dagi YAML fayllar.
  • on ishga tushirish sababini, jobs vazifalarni belgilaydi.
  • Matritsa bir necha versiya va tizimda parallel sinash imkonini beradi.
  • Parollarni secrets da saqlang, YAML da emas.
  • Dependabot bog'liqliklarni avtomatik yangilaydi.

Keyingi bo'limda jamoaviy ish qoidalari va yaxshi amaliyotlarni ko'ramiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.