Author: امین مصباحی
Site: امین مصباحی
Source: https://mesbahi.net/fa/blog/1405/02/06/versioning-strategy-1
⚠️ Article content is partial (Telegram Instant View delivered in segments).
💡 **فرهنگ و ساختار نسخهدهی در تیمهای نرمافزاری
**
انتخاب Gitflow یا Trunk-Based Development؟
انتخاب Monorepo یا Multirepo؟
انتخاب GitHub Flow یا GitLab Flow؟
به نظرم سؤال اصلی این نیست که «کدوم بهتره؟»
سؤال بهتر اینه که «هر کدوم برای حل چه مسئلهای ساخته شده؟»
خیلی از تیمها مدلهایی رو از شرکتهای بزرگ کپی میکنن، بدون اینکه همون سطح از CI/CD، تست، ownership، feature flag، release management و tooling رو داشته باشن. نتیجهاش هم معمولاً شلختگی، merge conflict، releaseهای پراسترس و کیفیت ناپایداره.
طی این دو پست، که پاسخی به سوال یکی از دوستان کانال است؛ به فرهنگ و ساختار نسخهدهی رو از چند زاویه بررسی کردم:
ساختار repository: شامل Monorepo، Multirepo، Microrepo
**مدلهای branching: **شامل: Gitflow، GitHub Flow، GitLab Flow، Trunk-Based Development
و بعد ترکیب اینها در سناریوهای واقعی: مثل monolith، microservice، تیم کوچیک، چند تیم، SemVer، CalVer و چکلیست تصمیمگیری.
هدفم نسخه پیچیدن نیست؛ بیشتر اینه که انتخابمون از روی شناخت باشه، نه تقلید.
**
🔗 بخش اول
🔗 **بخش دوم
3
*مقدمه:
فرهنگ و ساختار نسخهدهی توی تیمهای نرمافزاری، با اینکه پیشینه طولانی داره و نسل اولش به دهههای ۶۰ و ۷۰ و میلادی برمیگرده و حتی ابزارهای مدرنترش مثل git توی بیستسالگیشون به سر میبرن؛ ولی کماکان موضوعی مهم و اثرگذار روی تیمهاست. و البته کم نیستن تیمهایی که با انتخاب روش اشتباه یا نپرداختن به فرهنگی که بهینه نیست؛ کارآمدی لازم رو ندارن؛ دائما با شلختگی زمانی، یا نارضایتی از کیفیت و… دستوپنجه نرم میکنن.
این مطلب در مورد انتخاب ساختار، فرایند و چرخهی نسخهدهی و ریلیز نرم افزار است. قرار هم نیست نسخهی واحد صادر کنیم؛ اینکه گوگل از مونوریپو پیروی میکنه؛ دلیل نمیشه مونوریپو گزینه مناسبی برای همه است. توی این پست قراره ببینیم «چی» در پاسخ به «چه» نیازی به وجود اومده و اینکه گزینه مناسب تیم و شرکت شما چیه؛ یک انتخاب مبتنی بر شناخت و بلوغ فنی خواهد بود.این مطلب به بهانه سوال یه دوست کانال شروع شد: فرهنگ و ساختار نسخهدهی توی تیمهای بزرگ چطوره؟ مخصوصاً وقتی سیستم monolithic یا microservice داری؟
این نکته هم مهمه که قبل از شروع، منظورمون از چند مفهوم رو با هم مرور کنیم، چون یکی از سوءتفاهمهای رایج اینه که merge، deploy و release رو یکی میگیریم. در تیمهای بالغ، این سه میتونن جدا باشن: کد merge میشه، artifact deploy میشه، اما feature با flag یا rollout policy بعداً برای کاربران release میشه. پس:
– branching strategy یعنی مسیر تغییر کد
– release strategy یعنی تصمیم اینکه چه چیزی، کی، برای چه کسی فعال بشه
– deployment strategy یعنی رسوندن artifact به محیط
versioning strategy یعنی نامگذاری و compatibility نسخهها*
اینکه فرهنگ و ساختار نسخهدهی توی تیمهای موفق چطوره؟ سوال سادهای به نظر میرسه؛ ولی وقتی عمیقتر نگاه کنیم، میبینیم که زیرلایههای متعددی داره. چون «نسخهدهی» صرفاً یه تصمیم ابزاری نیست؛ ساختار repository، مدل branching، سیاست merge، چرخهی deploy و حتی فرهنگ تیم، همه با هم در تعاملاند و اثرشون رو روی هم میذارن.
توی این مطلب، ابتدا از ساختار repository شروع میکنیم؛ یعنی مونوریپو، مالتیریپو و میکروریپو. و میبینیم که هر کدوم از کجا اومدن و چه مسئلهای رو حل میکنن. بعد به مدلهای branching میرسیم؛ یعنی Gitflow، GitHub Flow، GitLab Flow، Trunk-Based Development و اینکه کدوم برای چه زمینهای طراحی شده. در نهایت میبینیم که این دو دسته تصمیم چطور باید با هم همراستا بشن؛ چون یه مونوریپو با Gitflow میتونه نتیجهای کاملاً متفاوت داشته باشه نسبت به مونوریپو با Trunk-Based.
هدفم از این مطلب اینه که بعد از خوندنش؛ انتخابتون از روی تشخیص؛ یا حداقل متشکل از پرسشهای دقیقتری باشه، نه تقلید.
ساختار Repository؛ از کجا اومدیم، کجا هستیم
قبل از اینکه بپرسیم «کدوم بهتره»، باید بپرسیم «هر کدوم برای حل چه مسئلهای به وجود اومد». این سوال رو جدی بگیریم؛ چون اکثر اختلافنظرها در این حوزه از اینجا ناشی میشه که آدمها جواب رو مقایسه میکنن، بدون اینکه سوالهاشون یکی باشه.
۱: Monorepo: یه خونه، همه چیز زیر یه سقف
خیلی از سازمانهای بزرگ در گذشته، بخش بزرگی از کدهاشون رو در یک source tree یا depot مرکزی نگهداری میکردن، اما monorepo به معنای مدرن امروزی، مخصوصاً با build graph، ownership tooling، affected testing و CI هوشمند، یک انتخاب مهندسیشدهتر است. در نتیجه، مدلی رایج بود که شباهتهایی به مونوریپو داشت. وقتی توی دهههای ۷۰ و ۸۰ میلادی شرکتهای بزرگ مثل IBM شروع به نوشتن نرمافزار کردن، طبیعیترین کار این بود که همه کد توی یه مخزن واحد باشه. چیزی به اسم «سرویس جداگانه» یا «تیم مستقل» هنوز مفهوم رایجی نبود.
اما جالبه که گوگل، بخشهایی از Microsoft و Meta/Facebook historically از مدلهای نزدیک به monorepo یا large-scale repository استفاده کردهاند، اما هر کدوم tooling و فرهنگ متفاوتی دارند.گاهاً با وجود اینکه به خوبی میتونستن سوئیچ کنن؛ همچنان به مونوریپو یا پیادهسازیهای مشابهش، در برخی بخشها وفادار موندن. دلیلش نه اینرسی، بلکه یه مزیت واقعی بود که با بزرگشدن تیم بیشتر احساس میشه: visibility. وقتی همه کد یه جاست، تغییر در یه کامپوننت بلافاصله در همهجا قابل ردیابیه. refactoring سراسری امکانپذیره. dependency مخفی وجود نداره.
البته گوگل برای اینکه مونوریپو با این ابعاد کار کنه، مجبور شد ابزار بسازه؛ Blaze که بعداً به شکل Bazel open-source شد. این خودش یه نکته مهمه: **مونوریپو در مقیاس بزرگ، هزینه ابزارسازی داره؛ گوگل صدها ابزار ساخته تا بتونه از پس حجم عظیم کدهاش بربیاد و توی مقیاس بزرگ دچار مشکل نشه. یا مایکروسافت برای نگهداری کدبیس عظیم ویندوز؛ یعنی حدود ۳.۵ میلیون فایل و تقریباً ۳۵۰ گیگابایت سورسکد، و ۴۰۰۰ مهندس، روی git فایلسیستم خودش به نام VFSForGit **رو نوشت تا بتونه مشکلات کار روی یک کدبیس عظیم رو حل کنه؛ و…
مزایا:
- یه جای واحد برای همه کد، تست و پیکربندی
- امکان refactoring اتمیک: میتونی یه interface رو در همه مصرفکنندهها یکجا عوض کنی
- امکان versioning ضمنی: همه چیز روی یه commit واحده، دردسر dependency hell کمتره
- مزیت onboarding سادهتر؛ در monorepoهای کوچک و متوسط، onboarding میتونه سادهتر باشه. اما در مقیاس enterprise، onboarding فقط وقتی ساده میمونه که sparse checkout، virtual file system، build graph و مستندات خوب داشته باشین.
معایب: