تحديث عملية CI / CD: teamcity

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

اسمحوا لي أن أذكركم بجدول محتويات قائمة المقالات ، وكذلك النتائج الموجزة للجزء السابق.

الجزء 1: ما هو ، لماذا لا يبدو ، التخطيط ، القليل من باش. أود أن أسمي هذا الجزء شبه التقني.
الجزء 2: teamcity.
الجزء 3: نشر الأخطبوط.
الجزء الرابع: خلف الكواليس. لحظات غير سارة ، خطط للمستقبل ، ربما أسئلة متكررة. على الأرجح ، يمكن أن يطلق عليه أيضًا شبه تقني.

لقد زودنا العميل بإثبات مفهوم نظام تسليم التحديث الجديد ، وحددنا أوجه القصور في النظام الحالي ، واخترنا الأساس للنظام الجديد ، ووضعنا خطة انتقالية وحولنا مستودعنا الزئبقي إلى بوابة. أيضًا ، في الجزء السابق ، قمنا بوصف ميزات المشروع التي ستؤثر على العملية اللاحقة بأكملها. 

كما ذكرنا سابقًا ، فإن الحل الحالي لا يلبي المتطلبات الحديثة. في البداية ، على الأرجح ، تم تكوين بناء واحد في ccnet. أول بناء بدأ به كل شيء (مثل الانفجار الكبير ، نعم). ثم ، على ما يبدو ، الشخص الذي قام بإعداد كل شيء ، ضغط على ctrl + c ، ctrl + v ، قام بتصحيح سطرين ، وتلقى تكوينًا جديدًا. ولكل الوقت اللاحق ، تم القيام بذلك بعدد كافٍ من المرات بحيث استغرق كود المصدر على خادم البناء أكثر من 60 جيجا. وهذه ليست سوى المصدر! وهناك سجلات ، وبناء القطع الأثرية ، والملفات المؤقتة ، وهلم جرا. هذا فقط جعلني أفكر. بالنظر إلى النظام القديم ، يمكن للمرء أن يرى ما يلي: تم تنفيذ خطوة بناء لكل وحدة نمطية. في الواقع ، تم تجميع نفس النواة. وتم تخزين هذا التجميع لكل وحدة (مع المصدر) على الخادم.تم دفع نتائج البناء (90٪ متطابقة) إلى المستودعات المحلية (نشر البوابة) ، وبطبيعة الحال ، حلت محلها. كان من الممكن والضروري ترك هذا. 

الاعدادات العامة 


في هذه المرحلة ، من المفترض أن هناك بالفعل فريق مدينة وأخطبوط مهيأ. في مرحلة التثبيت والتكوين ، لا نتوقف بالتفصيل. من أجل الراحة ، نكتب عنوان url و api-token للأخطبوط في env teamcity ، والتي ، بالمناسبة ، يبدو المشروع الجذري على

صورة

النحو التالي : env.apiUserName و env.apiUserPassword هي وصولات api لمستخدم teamcity (ستتم الحاجة إليها لاحقًا) ، env.buildPath و env .sourcePath - المسار الافتراضي لملفات البناء والمصدر ، على التوالي ، env.octoApiKey و env.octoUrl - الرمز المميز وعنوان url للأخطبوط. وأضاف أنها لا تزال env.teamcityUrl . حسنًا ، env.tt.exe- المسار إلى أداة تحويل النص. تقوم هذه الأداة المساعدة بإنشاء كافة التكوينات.

من المكونات الإضافية للجهات الخارجية ، يتم تثبيت تكامل Octopus Deploy فقط. 

لكي لا تفرط في تحميل الكم الهائل من النص بالفعل ، سيتم فحص التفاصيل فقط تلك الخطوات التي يوجد فيها شيء يستحق الاهتمام بالتفصيل. من المفترض أن كل شيء آخر يمكن فهمه بناءً على البيانات المقدمة ومعرفة القارئ. على أي حال ، إذا كان لديك أي أسئلة ، يسعدني الرد عليها.

تفصيل المشروع ، الإصدار ، الأسماء


كانت النتيجة مخطط مشروع مثل (كصورة ، لأن هناك مشكلة في عرض قائمة متعددة المستويات):
صورة

سنقوم بإصدار الحزم على النحو التالي: major.minor.patch ، حيث الرائد حتى الآن 1 ، والصغير هو عداد البناء من تكوين البناء ، والتصحيح هو عداد البناء للتكوين النشر (غير مطلوب لتكوين البناء ، لذلك دائمًا 0).

ملاحظة: تم وصف النسخة القديمة هنا. نحن بصدد إعادة تصميمها بحيث تستند إلى علامة git.

صورة

على سبيل المثال ، هنا 1 رئيسي ، و 95 صغير ، و 1 صغير.

في العملية الجديدة للوحدات ، سيكون هناك بناء واحد سيتم نشره بعد ذلك لكل وحدة. أي أنه يتم تخزين شفرة المصدر في نسخة واحدة لكل بيئة ، وتكون نتيجة البناء أيضًا ، نظرًا لأنها شائعة لجميع الوحدات. يتم تجميع التكوينات والمكتبات الفريدة في حزمة فردية في مرحلة النشر. سيؤدي ذلك إلى استخدام مساحة القرص بشكل فعال وتقليل وقت التسليم لكل حزمة.

في مرحلة التحضير ، كان هناك اجتماع قصير منفصل حول اصطلاح تسمية ملفات التكوين. كان عليه (كان فقط) ، ولكن ليس دائمًا نفسه. بالإضافة إلى ذلك ، لا يحتوي اسم التكوين دائمًا على معلومات كافية. نتيجة لذلك ، كانت جميع أسماء التكوين كما يلي:
ConfigurationType.Environment.ModName.configحيث يمكن أن يكون ConfigurationType هو AppSettings ، أو الويب ، إلخ. البيئة - التطوير والاختبار والتدريج والإنتاج. ModName هو الاسم الفريد للوحدة النمطية.

الوحدات


تعمل جميع مشاريع الوحدات على نفس المبدأ. 

تحتوي كل بيئة على تكوين بناء:

  1. تنفيذ استعادة nuget (مثبت NuGet ، استعادة nuget)
  2. يولد تكوينات (سطر الأوامر ، تحويل النص)
  3. حل Buildit (Visual studio sln)
  4. يلتقط الملفات من env.buildPath بتنسيق zip ويدفعها إلى الأخطبوط (Octopus لنشر: حزم الدفع)
  5. إنشاء إصدار (بدون نشر) (نشر إنشاء Octopus لإصدار)
  6. إعادة تعيين إصدار التصحيح (بوويرشيل)

هناك أيضًا نشر التكوينات التي تعمل بناءً على القالب والقيام بما يلي:

  1. يلتقط التكوينات التي تم إنشاؤها في مرحلة البناء (الخطوة 2) (الأخطبوط نشر حزم الدفع)
  2. نشر الإصدار الأساسي (الذي تم إنشاؤه في الخطوة 6 من البنية) (نشر Octopus: نشر الإصدار)
  3. الإصدار الفردي للنشر (الذي تم إنشاؤه في الخطوة 1 من التكوين الحالي) (نشر Octopus: نشر الإصدار)
  4. يعرض قائمة بجميع المجالات لهذه الوحدة في السجل (خطوة لراحة المختبر والمطور). (باورشيل).

لكل تكوين نشر ، تتم إضافة تكوين البناء إلى التبعية. وهذا يجعل من الممكن تشغيل البنية تلقائيًا عند نشرها إذا لم تكن ذات صلة ، بالإضافة إلى القدرة على إعادة تعيين إصدار التصحيح.

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

يبدو الأمر مثل هذا:

صورة

دعنا نلقي نظرة على بعض الخطوات بمزيد من التفصيل.

الإعدادات العامة


صورة

من تنسيق رقم بناء غير عادي فقط. سيتم شرحه لاحقًا.

Build.env


صورة


من المهم هنا: env.coreProjectName - تم تعيينه للمشروع بأكمله. مطلوب لتحديد المشروع في الأخطبوط.
env.Environment - تم تعيينه للمشروع الفرعي الوحدات النمطية. من الضروري تحديد التكوينات الصحيحة اعتمادًا على البيئة.
env.octoChannel - القناة في الأخطبوط التي تقع فيها الرزمة. نفسه كما env.Environment .
env.serviceName هو اسم الحل. في الأساس ، يتم إضافة المتغير لسهولة التصور.
env.tenantRoleTag - علامة المستأجر في الأخطبوط. مزيد من التفاصيل في قسم الأخطبوط.

بناء 4


صورة

أضف إلى الأرشيف باسم ٪ env.serviceName٪.٪ Build.number٪ .zip ملفات من الدليل مع نتيجة البناء ، باستثناء جميع التكوينات ، و dll من مجلد bin / الأصلي. تمت إضافة آخرها يدويًا إلى خادم الويب مرة واحدة ولن يلمسها أحد مرة أخرى. إذا لزم الأمر ، سيتم أيضًا تحديثها يدويًا (لذلك من المقرر كتابة نص منفصل ، لكننا سنكون صادقين). ويرجع ذلك إلى حقيقة أن هذه المكتبات "تحتفظ بها" مجموعة IIS ، ومن أجل النشر الناجح يجب إيقافها ثم تشغيلها ، الأمر الذي يستغرق بعض الوقت. باستبعاد هذه المكتبات من النشر ، يمكننا تخطي خطوة إيقاف التجمع ، مما سيقلل من وقت النشر ، وبالتالي ، وقت التوقف.

بناء 5


صورة

أعتقد أن كل شيء واضح هنا ، باستثناء سبب كون حقل البيئة فارغًا. في ما تحصل عليه الحزمة ، يتخذ الأخطبوط قرارًا بناءً على علامة ما قبل الإصدار (المكونة في القنوات). هذه العلامة موجودة في ٪ build.number٪ (نفس المرحلة على الشاشة في Build.General). لذلك في هذه الحالة اتضح أنه أكثر ملاءمة. يجدر أيضًا الانتباه إلى مربع الاختيار "إظهار عملية النشر" . إذا لم يتم تثبيته ، يعتبر Timity أن البناء ناجح بمجرد أن يبدأ الأخطبوط (ولكن لم ينته!) العمل. بمعنى ، إذا لم يتم تثبيت مربع الاختيار وحدث خطأ أثناء مرحلة النشر - دون النظر إلى واجهة الأخطبوط ، فلن نعرف عنها.

بناء 6


لا يوجد شيء غير عادي ، مجرد برنامج نصي ومعلومات من وثائق فريق العمل.

$pair = "%env.apiUserName%:%env.apiUserPassword%"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
$basicAuthValue = "Basic $encodedCreds"
$depUri="%env.teamcityUrl%/app/rest/buildTypes?locator=snapshotDependency:(from:(build:(id:%teamcity.build.id%)),includeInitial:false)"
# Get all dependencies of main build
$result = (Invoke-RestMethod -Headers @{'Origin'='http://localhost:8090'; "Authorization"="$basicAuthValue"} -Uri $depUri)
foreach ($i in $result.buildTypes.buildType.Count) { $buildId += $result.buildTypes.buildType.id }
$buildId = $buildId | Where-Object { $_ -ne 'Module_DeployAll' }
# Reset all child build counters to 1. This build counters are patch versions in every build. (1.build.patch)
for ($i=0; $i -lt $buildId.Count; $i++) {
  $buildCounterUri = "%env.teamcityUrl%/httpAuth/app/rest/buildTypes/"+$buildId[$i]+"/settings/buildNumberCounter"
  Invoke-RestMethod -Method Put -Headers @{'accept'='text/plain'; 'Origin'='http://localhost:8090'; "Authorization"="$basicAuthValue"} -Uri $buildCounterUri -ContentType "text/plain" -Body 1
}

هنا نحتاج إلى مستخدم واجهة برمجة تطبيقات في teamcity (يتم إنشاء env له). نقوم بتسجيل الدخول ، ونأخذ جميع التكوينات التي تعتمد على تكوين البناء ، ونعيد تعيين عداد البناء الخاص بها إلى 1. هذا ، في الواقع ، لكل إصدار تصحيح ، يعد هذا مؤشرًا على عدد المرات التي تم فيها نشر نفس البناء لوحدة معينة. إذا لم يكن هناك 1 ، فهذا يعني أن هناك خطأ ما في عملية نشر أو تشغيل الوحدة النمطية على الإصدار الحالي ، ويتطلب الانتباه.

نشر عام


صورة

تنسيق الإصدار: 1.٪ dep.Module_Build.build.counter٪.٪ Build.counter٪ -staging ، حيث
٪ dep.Module_Build.build.counter٪ هو متغير نظام teamcity الذي تتوافق قيمته مع عداد البناء لتكوين البناء المقابل (يجب إضافته إلى التبعيات). في الواقع ، هنا 1 هو الإصدار الرئيسي ، ٪ dep.Module_Build.build.counter٪ ثانوي ، و ٪ build.counter٪ هو التصحيح. التدريج هو علامة ما قبل الإصدار.

نشر


صورة

عند إضافة وحدة نمطية جديدة ، تتم إضافة التكوين لنشرها فقط ويتم الإشارة إلى قيمة المتغير env.modName . جميع المتغيرات الأخرى موروثة من المشاريع الأم. يتم تشكيل المتغير env.tenantModTag للأخطبوط من env.modName .

نشر 2


صورة

نشر الحزمة الأساسية. 

رقم الإصدار الأخير - استخدم أحدث إصدار متوفر لهذه البيئة.
علامة المستأجر - علامة العميل / المؤسسة. مزيد من التفاصيل في قسم الأخطبوط.
معلمات cli إضافية. هنا نشير إلى القناة التي ستقع فيها مجموعتنا ، بالإضافة إلى معلمات إضافية. هذا سيتم مناقشته بشكل منفصل في قسم الأخطبوط.

نشر 3


مثل Deploy.2 ، يتم نشر حزمة وحدة فردية فقط.

نشر 4


سيتم أيضًا وصف هذه الخطوة بالتفصيل أدناه ، لأنها تتلقى بيانات من الأخطبوط.

يتم بناء تكوينات موقع الشركة والوحدة الخاصة على نفس المبدأ ، والنقاط الرئيسية فيها هي نفسها ، لذلك لا أرى نقطة وصفها بنفس التفاصيل. إنها واحدة ، لا تحتاج إلى نشرها عدة مرات ، وفي الواقع هناك استعادة للأجزاء ، تحويل النص ، msbuild ، دفع الأخطبوط ، الأخطبوط إنشاء الإصدار + النشر.

تعرف على المزيد حول التكوينات الفريدة. بالنسبة لبعض التعديلات ، قد لا يكون هناك أي بيئات (على سبيل المثال ، التدريج) ، يجب نشرها على خوادم أخرى ، أو يجب عليك تعيين معرف العميل يدويًا (خذ التكوين الأساسي وقم بتغيير بعض الحقول فيه باستخدام powershell). أي أنها تعمل على نفس مبدأ الوحدات الرئيسية. يكمن تفردها في حقيقة أنه تم إضافة / تغيير الخطوات بالنسبة لهم ، أو تغيير خادم النشر ولا تتناسب مع القالب ، لذلك يستغرق الأمر وقتًا أطول قليلاً لإنشائها. لحسن الحظ ، هناك القليل منهم.

Teamcity: ملخص


سمح تطبيق teamcity باتباع نهج أمثل لعملية تجميع التطبيقات. الآن يستغرق الأمر وقتًا أقل بكثير: بدلاً من إنشاء نفس الرمز في كل مرة ، نقوم ببنائه مرة واحدة. نستخدم أيضًا مساحة القرص وحركة مرور الشبكة ووقت الحوسبة بشكل أفضل. في السابق ، كان عدد الحزم للنشر (مستودعات تحتوي على قطع أثرية) يساوي عدد الوحدات. تزن كل عبوة حوالي 100 متر في شكل مضغوط. الآن لدينا عدد من الحزم أكثر من عدد الوحدات ، مع حزمة واحدة تزن حوالي 100M نفسها ، والباقي حوالي 500K. بالإضافة إلى واجهة أكثر سهولة في الاستخدام ، وسجلات مريحة ، والأهم من ذلك - تقليل الوقت اللازم للحفاظ على نظام البناء وإضافة التكوينات. تستغرق الآن إضافة وحدة نمطية جديدة من 15 دقيقة إلى نصف ساعة.

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

بطبيعة الحال ، كانت عملية إعداد teamcity تسير جنبًا إلى جنب مع إعداد الأخطبوط. من المستحيل ببساطة أن يصف بالتوازي في النص ، لأن هناك فرصة كبيرة للارتباك. لذلك ، تمت مشاركة الوصف ، وفي هذا الجزء فقط تم وصف خطوات توفير CI. سيتم وصف عملية إعداد الأخطبوط في ما يلي.

All Articles