تحسين التواصل في GitLab باستخدام Webhooks

أنيس مروشيAI Bot
بواسطة أنيس مروشي & AI Bot ·

جاري تحميل مشغل تحويل النص إلى كلام الصوتي...

إحدى المشاكل الكبيرة التي تواجه الفرق التي تستخدم GitLab لإدارة مشاريعها هي التواصل المجزأ عبر قنوات متعددة. يمكن أن تؤدي هذه التجزئة إلى تأخير في الاستجابة وسوء التواصل. من خلال توحيد التواصل داخل GitLab باستخدام Webhooks، يمكنك تحسين إدارة المشاريع، وضمان أوقات استجابة أسرع، وجعل GitLab المصدر الوحيد للحقيقة لجميع المناقشات المتعلقة بالمشروع. يوفر هذا المقال أمثلة على الأكواد في Laravel و Next.js لأغراض التوضيح، لكن يمكن توسيع المفهوم ليشمل أطر عمل أخرى.

الفوائد

  • مصدر وحيد للحقيقة: يتم توحيد جميع المناقشات والتحديثات المتعلقة بالمشروع في GitLab.
  • أوقات استجابة أسرع: تنبه الإشعارات الفورية المستخدمين المذكورين على الفور، مما يقلل من التأخيرات.
  • تقليل الاعتماد على القنوات الخارجية: يلغي الحاجة إلى التواصل عبر التطبيقات الخارجية، مما يضمن بقاء جميع المعلومات في سياق المشروع.
  • تحسين التتبع: أسهل في تتبع والإشارة إلى المحادثات المتعلقة بمشاكل وطلبات دمج محددة.

العيوب والبدائل

  • العيوب:

    • منحنى التعلم: يجب أن يكون أعضاء الفريق على دراية بواجهة وميزات GitLab.
    • تعقيد التكامل: قد تتطلب إعداد وصيانة Webhooks خبرة تقنية.
    • زيادة الإشعارات: قد تغمر الإشعارات المتكررة المستخدمين إذا لم تُدار بشكل صحيح.
  • البدائل:

    • تكاملات Slack: استخدم Slack للإشعارات والمناقشات أثناء الربط بمشاكل GitLab.
    • الإشعارات عبر البريد الإلكتروني: قم بإعداد GitLab لإرسال إشعارات عبر البريد الإلكتروني للتحديثات.
    • أدوات إدارة المشاريع: استخدم أدوات مثل Jira أو Trello مع تكاملات GitLab.

دليل خطوة بخطوة

المتطلبات

  • حساب ومشروع GitLab.
  • معرفة أساسية بنظام المشاكل وطلبات الدمج في GitLab.
  • الوصول إلى الخادم حيث يتم استضافة المشروع.
  • Pushbullet: خدمة تتيح لك إرسال إشعارات إلى أجهزتك. ستحتاج إلى إعداد حساب والحصول على رمز الوصول.

الخطوة 1: إعداد Pushbullet

إنشاء حساب Pushbullet

  1. انتقل إلى موقع Pushbullet.
  2. سجل باستخدام حساب Google أو Facebook الخاص بك، أو أنشئ حسابًا جديدًا باستخدام بريدك الإلكتروني.

الحصول على رمز الوصول

  1. بمجرد تسجيل الدخول إلى حساب Pushbullet الخاص بك، انتقل إلى إعدادات الحساب بالنقر على صورة ملفك الشخصي في الزاوية العلوية اليمنى واختيار Settings.
  2. في قائمة الإعدادات، اختر علامة التبويب Account.
  3. مرر لأسفل إلى قسم Access Tokens وانقر على Create Access Token.
  4. انسخ رمز الوصول المُنشأ. ستستخدم هذا الرمز لمصادقة طلبات API الخاصة بك إلى Pushbullet.

الخطوة 2: إنشاء سكربت Bash للتنفيذ

أنشئ سكربت لإدارة عملية التنفيذ.

#!/bin/bash
 
# تحديد مسار المستودع
REPO_PATH="/var/www/your_project"
 
# الانتقال إلى المستودع
cd "$REPO_PATH"
 
# سحب آخر التغييرات من الفرع الرئيسي
git pull origin main

تأكد من أن السكربت قابل للتنفيذ:

chmod +x /var/www/your_project/deploy.sh

الخطوة 3: إعداد وحدة تحكم Laravel لمعالجة Webhooks

أنشئ وحدة تحكم جديدة في تطبيق Laravel الخاص بك لمعالجة Webhooks من GitLab. استخدم قائمة انتظار للسكربت الطويل الأمد.

  1. تثبيت تبعيات قائمة انتظار Laravel

    تأكد من إعداد تطبيق Laravel الخاص بك لاستخدام قوائم الانتظار. يمكنك استخدام برامج تشغيل مختلفة مثل database، redis، beanstalkd، إلخ. لأغراض التوضيح، سنستخدم برنامج تشغيل قاعدة البيانات.

    php artisan queue:table
    php artisan migrate
  2. إنشاء Job لمعالجة التنفيذ

    // app/Jobs/HandleGitPull.php
     
    namespace App\Jobs;
     
    use Illuminate\Bus\Queueable;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Bus\Dispatchable;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Support\Facades\Log;
    use Symfony\Component\Process\Process;
     
    class HandleGitPull implements ShouldQueue
    {
        use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
     
        /**
         * تنفيذ ال job.
         *
         * @return void
         */
        public function handle()
        {
            $scriptPath = '/var/www/your_project/deploy.sh';
     
            if (!is_executable($scriptPath)) {
                chmod($scriptPath, 0755);
            }
     
            $process = new Process([$scriptPath]);
            $process->setTimeout(0);
            $process->run(function ($type, $buffer) {
                if (Process::ERR === $type) {
                    Log::error('خطأ في عملية السحب من Git:', ['output' => $buffer]);
                } else {
                    Log::info('مخرجات عملية السحب من Git:', ['output' => $buffer]);
                }
            });
     
            Log::info('عملية السحب من Git بدأت');
        }
    }
  3. تحديث وحدة التحكم لإرسال ال job

    // app/Http/Controllers/Api/V1/GitlabController.php
     
    namespace App\Http\Controllers\Api\V1;
     
    use App\Http\Controllers\Controller;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Log;
    use GuzzleHttp\Client;
    use App\Jobs\HandleGitPull;
     
    class GitlabController extends Controller
    {
        private $pushbulletAccessToken = 'your_pushbullet_access_token';
     
        public function store(Request $request)
        {
            Log::info('Webhook GitLab المستلم:', $request->all());
            $event = $request->header('X-Gitlab-Event');
            $body = $request->all();
     
            if ($event === 'Merge Request Hook' && $body['object_attributes']['state'] === 'merged') {
                HandleGitPull::dispatch();
            }
     
            if ($event === 'Push Hook') {
                $branch = $body['ref'];
                if ($branch === 'refs/heads/main') {
                    HandleGitPull::dispatch();
                }
            }
     
            if ($event === 'Note Hook' && ($body['object_attributes']['noteable_type'] === 'Issue' || $body['object_attributes']['noteable_type'] === 'MergeRequest')) {
                $description = $body['object_attributes']['description'];
                $mentionedUser = $this->extractMentionedUser($description);
                if ($mentionedUser === 'marrouchi' || $mentionedUser === 'seif.arbi') {
                    $issueUrl = $body['object_attributes']['url'];
                    $this->sendNotification($mentionedUser, $description, $issueUrl);
                }
                if ($this->containsTaskListUpdate($description)) {
                    $this->handleTaskListUpdate($body);
                }
            }
     
            return response()->json(['message' => 'تم معالجة الحدث'], 200);
        }
     
        private function extractMentionedUser($comment)
        {
            $mentionPattern = '/@(\w+)/';
            if (preg_match($mentionPattern, $comment, $matches)) {
                return $matches[1];
            }
            return null;
        }
     
        private function sendNotification($user, $message, $url)
        {
            $title = 'ذكر جديد';
            $body = "$message\n\nعرض المشكلة: $url";
     
            $client = new Client([
                'base_uri' => 'https://api.pushbullet.com/v2/',
                'headers' => [
                    'Access-Token' => $this->pushbulletAccessToken,
                    'Content-Type' => 'application/json',
                ],
            ]);
     
            $response = $client->post('pushes', [
                'json' => [
                    'type' => 'note',
                    'title' => $title,
                    'body' => $body,
                ],
            ]);
     
            if ($response->getStatusCode() != 200) {
                Log::error('خطأ في إرسال الإشعار:', ['response' => $response->getBody()->getContents()]);
            } else {
                Log::info('تم إرسال الإشعار بنجاح:', ['response' => $response->getBody()->getContents()]);
            }
        }
     
        private function containsTaskListUpdate($description)
        {
            return preg_match('/- \[[ xX]\]/', $description);
        }
     
        private function handleTaskListUpdate($body)
        {
            $issueUrl = $body['object_attributes']['url'];
            $description = $body['object_attributes']['description'];
            Log::info("تم تحديث قائمة المهام: $description\nرابط المشكلة: $issueUrl");
     
            // نفذ منطق المعالجة الإضافية هنا، مثل تحديث قاعدة بيانات أو إرسال إشعارات
        }
    }
  4. تشغيل عامل قائمة الانتظار

    أخيرًا، قم بتشغيل عامل قائمة الانتظار لمعالجة الوظائف الموجودة في القائمة:

    php artisan queue:work

الخطوة 4: إعداد مسار API في Next.js لمعالجة Webhooks

أنشئ مسار API جديد في تطبيق Next.js الخاص بك لمعالجة Webhooks من GitLab.

  1. أنشئ سكربت deploy.sh لإدارة التنفيذ:

    #!/bin/bash
     
    # تحديد مسار المستودع
    REPO_PATH="/path/to/your/nextjs/repo"
     
    # الانتقال إلى المستودع
    cd "$REPO_PATH"
     
    # سحب آخر التغييرات من الفرع الرئيسي
    git pull origin main

    تأكد من أن السكربت قابل للتنفيذ:

    chmod +x /path/to/your/nextjs/repo/deploy.sh
  2. أنشئ مسار API جديد في تطبيق Next.js الخاص بك:

    // pages/api/gitlab.ts
     
    import type { NextApiRequest, NextApiResponse } from 'next';
    import { exec } from 'child_process';
    import { promisify } from 'util';
    import Pushbullet from 'pushbullet';
     
    const execPromise = promisify(exec);
    const PUSHBULLET_ACCESS_TOKEN = 'your_pushbullet_access_token';
    const pusher = new Pushbullet(PUSHBULLET_ACCESS_TOKEN);
     
    const extractMentionedUser = (comment: string): string | null => {
        const mentionPattern = /@(\w+)/;
        const match = comment.match(mentionPattern);
        return match ? match[1] : null;
    };
     
    const sendNotification = async (user: string, message: string, url: string) => {
        const title = 'ذكر جديد';
        const body = `${message}\n\nعرض المشكلة: ${url}`;
     
        pusher.note({}, title, body, (error: any, response: any) => {
            if (error) {
                console.error('خطأ في إرسال الإشعار:', error);
            } else {
                console.log('تم إرسال الإشعار:', response);
            }
        });
    };
     
    const handleGitlabWebhook = async (req: NextApiRequest, res: NextApiResponse) => {
        const event = req.headers['x-gitlab-event'];
        const body = req.body;
     
        if (event === 'Merge Request Hook' && body.object_attributes.state === 'merged') {
            await handleGitPull();
        } else if (event === 'Push Hook' && body.ref === 'refs/heads/main') {
            await handleGitPull();
        } else if (event === 'Note Hook') {
            const noteableType = body.object_attributes.noteable_type;
            const description = body.object_attributes.description;
            const action = body.object_attributes.action;
     
            if (noteableType === 'Issue' || noteableType === 'MergeRequest') {
                const mentionedUser = extractMentionedUser(description);
                if (mentionedUser === 'marrouchi' || mentionedUser === 'seif.arbi') {
                    const issueUrl = body.object_attributes.url;
                    await sendNotification(mentionedUser, description, issueUrl);
                }
     
                if (action === 'update' || action === 'create') {
                    const mentionedUser = extractMentionedUser(description);
                    if (mentionedUser === 'marrouchi' || mentionedUser === 'seif.arbi') {
                        const issueUrl = body.object_attributes.url;
                        await sendNotification(mentionedUser, description, issueUrl);
                    }
                }
            }
        }
     
        res.status(200).json({ message: 'تم معالجة الحدث' });
    };
     
    const handleGitPull = async () => {
        const scriptPath = '/path/to/your/nextjs/repo/deploy.sh';
     
        try {
            await execPromise(`sh ${scriptPath}`);
            console.log('تم السحب من Git بنجاح');
        } catch (error) {
            console.error('فشل السحب من Git:', error);
        }
    };
     
    export default handleGitlabWebhook;

الخطوة 5: إعداد Webhook GitLab

  1. انتقل إلى مشروع GitLab الخاص بك.
  2. توجه إلى Settings > Integrations.
  3. أضف Webhook جديد:
    • URL: https://your-domain/api/gitlab
    • المحفزات: اختر Merge request events، Push events، و Note events.
  4. احفظ Webhook.

نقاط التحسين

  • تحسين إدارة الإشعارات: التكامل مع أنظمة إشعارات أخرى مثل Slack أو Microsoft Teams.
  • تحسين الأمان: التحقق من payloads الخاصة ب Webhooks باستخدام رمز سري.
  • التسجيل المتقدم: استخدام خدمة تسجيل مثل Sentry لتحسين تتبع الأخطاء.
  • إجراءات مخصصة: توسيع الوظائف لمعالجة المزيد من أحداث GitLab والإجراءات المخصصة.

الخاتمة

تحسين التواصل داخل GitLab باستخدام Webhooks يعزز إدارة المشاريع من خلال ضمان أوقات استجابة أسرع وتقليل الاعتماد على قنوات الاتصال الخارجية. قدم هذا البرنامج التعليمي دليلاً خطوة بخطوة لإعداد Webhooks في GitLab ومعالجة الإشعارات باستخدام Laravel و Next.js، مما يجعل المشاكل وطلبات الدمج في GitLab مصدر الحقيقة الوحيد للتواصل المتعلق بالمشاريع.


هل تريد قراءة المزيد من الدروس التعليمية؟ تحقق من أحدث درس تعليمي لدينا على 1 مبادئ لارافيل Laravel 11: تعلم برمجة PHP.

ناقش مشروعك معنا

نحن هنا للمساعدة في احتياجات تطوير الويب الخاصة بك. حدد موعدًا لمناقشة مشروعك وكيف يمكننا مساعدتك.

دعنا نجد أفضل الحلول لاحتياجاتك.