CI/CD لـ C#: كيف تتوقف عن النشر يدويًا وتبدأ بالعيش
\n\nإذا كنت لا تزال تجمع مشروع C# محليًا، وترفع الملفات عبر FTP، وتدعو الله ألا يحدث عطل — لدي أخبار لك. في 2025، هذا أمر محرج. حتى لمشروع صغير شخصي.
\n\nCI/CD ليس سحرًا خاصًا بكبار المطورين، بل مجرد مجموعة من السكريبتات التي تؤدي المهام الروتينية نيابة عنك. اليوم سنقوم بإعداد CI/CD pipeline كامل لمشاريع C# من الصفر. بدون حشو، مع أمثلة حقيقية وتحليل للأخطاء.
\n\nبالمناسبة، إذا كنت تكتب بلغة Python — لدينا على pythonlib.ru أدلة حول الأتمتة أيضًا. لكن اليوم سنعمل مع C#.
\n\nما هو CI/CD ولماذا يحتاجه مطور C#
\n\nCI (Continuous Integration) — هو عندما يتم بناء واختبار كل commit تقوم به في Git تلقائيًا. لا مزيد من "لكنه يعمل لدي".
\n\nCD (Continuous Delivery/Deployment) — هو عندما ينتقل الكود تلقائيًا إلى الخادم (أو السحابة) بعد البناء الناجح.
\n\nبالنسبة لـ C#، هذا مهم بشكل خاص: بناء المشروع باستخدام dotnet build قد يختلف من جهاز لآخر، والاختبارات ينساها الجميع تقريبًا. CI/CD يحل كلتا المشكلتين.
اختيار الأداة: GitHub Actions vs GitLab CI vs Jenkins
\n\nللمبتدئين، أوصي بـ GitHub Actions. لماذا؟
\n\n- \n
- مجاني للمستودعات العامة (نعم، لـ C# أيضًا) \n
- لا حاجة لتثبيت خادم \n
- إجراءات جاهزة لـ .NET \n
- YAML — سهل القراءة \n
إذا كنت تستخدم GitLab — المبدأ نفسه، بناء الجملة مشابه. سنترك Jenkins للجحيم المؤسسي.
\n\nكتابة أول pipeline لمشروع C#
\n\nأنشئ ملفًا في جذر المستودع باسم .github/workflows/dotnet.yml. نعم، يجب أن يكون الملف في هذا المجلد تحديدًا.
إليك الحد الأدنى من pipeline الذي يعمل، ويبني المشروع ويجري الاختبارات:
\n\nname: .NET CI\n\non:\n push:\n branches: [ main, develop ]\n pull_request:\n branches: [ main ]\n\njobs:\n build-and-test:\n runs-on: ubuntu-latest\n\n steps:\n - uses: actions/checkout@v4\n\n - name: Setup .NET\n uses: actions/setup-dotnet@v4\n with:\n dotnet-version: '8.0.x'\n\n - name: Restore dependencies\n run: dotnet restore\n\n - name: Build\n run: dotnet build --no-restore --configuration Release\n\n - name: Run tests\n run: dotnet test --no-build --configuration Release --verbosity normal\n\nشرح الخطوات:
\n\n- \n
on: push— يتم تشغيل pipeline عند الدفع إلى main أو develop \n runs-on: ubuntu-latest— نبني على Linux (C# مع .NET Core/8+ يعمل في كل مكان) \n setup-dotnet— يثبت الإصدار المطلوب من .NET SDK \n dotnet restore— يستعيد حزم NuGet \n dotnet build— يجمّع الإصدار النهائي (Release) \n dotnet test— يشغل جميع الاختبارات من المشروع \n
بعد الدفع، انتقل إلى تبويب Actions في مستودعك — سترى pipeline قيد التنفيذ. إذا فشلت الاختبارات، ستحصل على حالة حمراء ورسالة بريد إلكتروني.
\n\nإضافة تغطية الكود (لأن الاختبارات بدون تغطية وهمية)
\n\nيجب أن يُظهر pipeline الجميل مقدار الكود المغطى بالاختبارات. لـ C#، نستخدم coverlet مع ReportGenerator.
\n\nأولاً، أضف حزم NuGet إلى مشروع الاختبار:
\n\ndotnet add YourTestProject.csproj package coverlet.collector\ndotnet add YourTestProject.csproj package coverlet.msbuild\n\nالآن، قم بتحديث خطوة الاختبارات في pipeline:
\n\n - name: Run tests with coverage\n run: |\n dotnet test --no-build --configuration Release \\\n /p:CollectCoverage=true \\\n /p:CoverletOutputFormat=opencover \\\n /p:CoverletOutput=./TestResults/coverage.xml\n\n - name: Install ReportGenerator\n run: dotnet t