Semantic Versioning، یک قرارداد رسمی برای تعیین تعداد نسخه انتشار جدید نرم‌افزار است. این استاندارد به کاربران نرم افزار کمک می‌کند تا میزان تغییرات در هر توزیع جدید را درک نمایند.

پروژه‌ای که از Semantic Versioning استفاده می‌کند، اعداد Major ،Minor و Patch را برای هر نسخه دریافت می‌کند. به عنوان مثال در رشته نسخه 1.2.3، عدد 1 نسخه اصلی، عدد 2 نسخه فرعی و عدد 3 تعداد patch را نشان می‌دهد.

شماره‌های نسخه‌هایی که از این فرمت استفاده می‌نمایند، به طور گسترده توسط بسته‌های نرم‌افزاری و فایل‌های اجرایی end-user مانند برنامه‌ها و بازی‌ها استفاده می‌شوند. هر پروژه دقیقاً از استاندارد تعیین شده توسط semver.org پیروی نمی‌کند.

 

این مشخصات برای رفع مشکلات ناشی از شیوه‌هایی با نسخه‌سازی متناقض در میان بسته‌های نرم‌افزاری که به عنوان وابستگی استفاده می‌شوند، ایجاد شده است. منظور از «بسته» و «وابستگی» به کتابخانه‌ای از کد اشاره می‌کند که قرار است در پروژه نرم‌افزاری دیگری استفاده شود و توسط یک ابزار مدیریت بسته مانند npm ،composer یا nuget توزیع می‌شود. این کاربرد Semantic Versioning است که در این مقاله به شرح آن پرداخته‌ایم.

 

Major ،Minor و Patch چیست؟

Major ،Minor و Patch سه جزء مهم در ترسیم مسیر توسعه یک پروژه هستند که تأثیر end-user هر نسخه جدید را به هم مرتبط می‌کنند.

شماره اصلی (Major number): شماره اصلی، نسخه فعلی رابط عمومی بسته را نشان می‌دهد. این عدد هر بار که تغییری ایجاد می‌کنید افزایش می‌یابد و کاربران فعلی بسته شما باید برنامه خود را پس از تغییر این عدد به‌روزرسانی نمایند.

شماره فرعی (Minor number): شماره فرعی، نسخه کاربردی فعلی نرم افزار شما را توصیف می‌کند. هر زمان که یک ویژگی جدید اضافه می‌کنید، این شماره افزایش می‌یابد. در چنین حالتی، رابط بسته شما تغییر نمی‌یابد و به کاربران اطلاع داده می‌شود که تغییر قابل توجهی ایجاد شده است؛ اما بسته کاملاً با شماره فرعی قبلی سازگار است.

شماره Patch: هر بار که تغییر جزئی ایجاد می‌کنید که بر رابط عمومی یا عملکرد کلی بسته شما تأثیر نمی‌گذارد، شماره Patch افزایش می‌یابد. این عنصر، بیشتر برای رفع اشکال استفاده می‌شود. مصرف کنندگان باید همیشه بتوانند، برنامه خود را بدون هیچ مشکلی به آخرین نسخه patch به روز رسانی نمایند.

ساختار انتشار semantic versioning به بهترین شکل به صورت درختی مدل‌سازی می‌شود. در بالا، شما تغییرات رابط عمومی خود را دارید، که هر کدام منجر به یک عدد اصلی جدید می‌شود. هر سری اصلی، مجموعه‌ای از نسخه‌های فرعی خود را دارد که در آن عملکردهای جدید به شیوه‌ای سازگار با عملکرد قبلی اضافه می‌شوند. در نهایت، نسخه‌های فرعی ممکن است هر از گاهی patch‌های رفع اشکال دریافت کنند.

 

از کجا شروع کنیم؟

اکثر پروژه‌ها باید از 1.0.0 به عنوان نسخه اولیه خود استفاده نمایند. این نشان می‌دهد که در حال انتشار اولین رابط عمومی و یک مجموعه اولیه از عملکردهای بدون تغییر هستید. از آنجایی که در ابتدای کار هنوز هیچ patchای ارائه نشده است، بنابراین نسخه آن 0 خواهد بود.

حال بیایید ببینیم که با ایجاد تغییرات در بسته خود چه اتفاقی می‌افتد. پس از انتشار اولیه، فرض کنید که یک گزارش باگ از یک کاربر دریافت می‌کنید. در این صورت، وقتی آن را رفع کرده و منتشر نمایید، شماره نسخه صحیح 1.0.1 خواهد بود. به همین ترتیب اگر نسخه دیگری برای رفع اشکال برنامه ایجاد نمایید، شماره patch باید به 1.0.2 افزایش یابد.

از طرفی ممکن است روی یک ویژگی جدید و هیجان انگیز کار کرده و آن را روی برنامه خود اضافه نمایید. از آنجایی که این ویژگی کاملا اختیاری است؛ بنابراین کاربران نیازی به انجام کاری برای ارتقا ندارند. در این صورت، شما باید نسخه را به‌صورت 1.1.0 منتشر کنید. با توجه به اینکه گزارش‌های اشکال زیاد رخ می‌دهد، ممکن است در همان ابتدای این نسخه، مجبور به انتشار نسخه 1.1.1 به کاربران شوید.

فرض کنید چند ماه بعد، شما تصمیم گرفتید کل پروژه را بازسازی نمایید. بدین معنی که برخی از عملکردهایی که قبلا ارائه می‌کردید، حذف شده است یا اکنون از طریق یک رابط تلفیقی قابل دسترسی است. پس از اینکه این اثر را منتشر کردید، افرادی که از نسخه فعلی بسته شما استفاده می‌کنند، باید تغییرات عمده‌ای در پروژه خود ایجاد کنند. بنابراین، وقت آن است که نسخه 2.0.0 را در مخزن بسته خود منتشر نمایید.

 

نگهداری از branchهای قدیمی

جالب است بدانید که تغییر نسخه شما منجر به ایجاد یک نقطه بدون بازگشت نمی‌شود. به عنوان مثال، فرض کنید که پس از انتشار نسخه 1.1.1، باگی را پیدا کنید که در 1.0.2 نیز وجود داشته است. با استفاده از branchهای ایجاد شده از نسخه‌ها در سیستم کنترل منبع خود، می‌توانید patch را در هر دو سری نسخه اعمال نمایید. بنابراین، در نهایت نسخه 1.1.2 و 1.0.3 را منتشر خواهید کرد.

به طور مشابه، ممکن است بخواهید با وجود انتشار نسخه 2.0.0، شاخه 1.x پروژه خود را حفظ کنید. اگرچه ممکن است انتشار 1.1.2 بعد از 2.0.1 عجیب باشد؛ اما این عمل کاملاً قابل قبول است. Semantic Versioning، یک شماره نسخه‌ای ایجاد نمی‌کند که همواره بصورت خطی افزایش می‌یابد؛ بلکه، به عنوان بخشی از یک مدل توسعه انشعاب استفاده می‌شود که از سهولت patch ارائه شده توسط سیستم‌های کنترل منبع مانند Git استفاده می‌کند.

دقت کنید که نسخه‌های منتشر شده باید تغییر ناپذیر باشند. هنگامی‌که نسخه‌ای مانند نسخه 2.4.3 را ایجاد کردید، شما نمی‌توانید آن را با اضافه کردن یک کد در زیر همان رشته نسخه "به روز" کنید؛ بلکه شما باید به هر نسخه یک شماره نسخه جدید اختصاص دهید؛ تا کاربران همیشه بتوانند به هر نسخه خاص از بسته شما دسترسی داشته باشند.

 

مدیریت بسته‌های پیش از انتشار

معمولاً، هر زمان که یک تغییر ناسازگار با نسخه‌های قبلی ارائه می‌شود، شما همواره باید نسخه اصلی پروژه خود را تغییر دهید. هنگامی‌که در وضعیت پیش از راه‌اندازی هستید، پایگاه کد شما ممکن است خیلی سریع تغییر یابد و در نتیجه تعداد زیادی نسخه اصلی منتشر شود.

بدین منظور برای جلوگیری از این مشکل می‌توانید، با ارائه پروژه خود به صورت 0.y.z شروع کنید. عدد 0 به عنوان نسخه اصلی نشان می‌دهد که بسته شما ناپایدار است و قوانین عادی در مورد تغییرات ناسازگار با نسخه‌های قبلی دیگر اعمال نمی‌شود؛ بنابراین می‌توانید نسخه‌های جدید را فقط با افزایش اعداد فرعی و patch منتشر نمایید. این بدان معناست که شما همچنان می‌توانید از 1.0.0 به منظور برچسب گذاری اولین نسخه "تمام و کامل" نرم افزار خود استفاده کنید.

علاوه‌براین، شما می‌توانید از «شناسه‌های» اضافی به همراه خط فاصله به‌عنوان جداکننده در انتهای رشته نسخه استفاده نمایید. به عنوان مثال، 1.0.0-alpha.1 برای نشان دادن انواع نسخه‌های آلفا و بتا استفاده کنید. به طور مشابه، شما می‌توانید metadata ساخت را با ضمیمه کردن کاراکتر + نیز اضافه نمایید. نمونه‌ای از این موارد می‌تواند نسخه 1.1.0-alpha.1+linux_x86 باشد.

 

 

 

منبع:

cloudsavvyit