ثبت‌نام

راهنمای جامع انتشار پروژه متن‌باز (از صفر تا صد)

✍️ محمد پارسا قاسمی 📅 1405/05/18 👁️ 84 بازدید
راهنمای جامع انتشار پروژه متن‌باز (از صفر تا صد)

انتشار یک پروژه متن‌باز، فراتر از قرار دادن کد در یک مخزن عمومی مانند GitHub یا GitLab است. این یک فرایند چندلایه و پیچیده است که نیازمند برنامه‌ریزی دقیق، رعایت اصول حقوقی، ایجاد ساختار مناسب برای جذب و نگهداری جامعه کاربران و توسعه‌دهندگان، تضمین امنیت و کیفیت کد، و در نهایت، تضمین پایداری بلندمدت پروژه است.

بسیاری از پروژه‌های متن‌باز موفق، سال‌ها زمان صرف کردند تا به بلوغ فعلی برسند و این موفقیت حاصل پیروی از یک مسیر مشخص و اصولی بوده است. در این راهنمای جامع، قصد داریم تمامی مراحل انتشار یک پروژه متن‌باز موفق را از صفر تا صد، با ذکر جزئیات، مثال‌های عملی، و بهترین شیوه‌های صنعت نرم‌افزار بررسی کنیم. این راهنما بر اساس تجربیات پروژه‌های بزرگ و مستندات رسمی مؤسسه ابتکارات متن‌باز (OSI) و بنیاد لینوکس تهیه شده است.

📑 فهرست مطالب

  1. بخش اول: آماده‌سازی اولیه و امنیت
  2. بخش دوم: انتخاب مجوز متن‌باز
  3. بخش سوم: مستندسازی پروژه
  4. بخش چهارم: ساختار مخزن و فایل‌های ضروری
  5. بخش پنجم: حکمرانی و جامعه‌سازی
  6. بخش ششم: زیرساخت و ابزارها
  7. بخش هفتم: فرایند انتشار رسمی
  8. بخش هشتم: پایداری، تأمین مالی و مدل‌های کسب‌وکار
  9. بخش نهم: معیارهای سنجش موفقیت و سلامت پروژه
  10. بخش دهم: چک‌لیست نهایی انتشار
  11. بخش یازدهم: نکات پیشرفته و سناریوهای خاص
  12. بخش دوازدهم: مطالعه موردی یک پروژه فرضی
  13. بخش سیزدهم: سوالات متداول
  14. بخش چهاردهم: جمع‌بندی و پیام به جامعه

بخش اول: آماده‌سازی اولیه و امنیت

۱-۱. پاکسازی تاریخچه گیت (Git History Cleanup)

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

متأسفانه، هر ساله شاهد انتشار پروژه‌های متن‌بازی هستیم که پس از چند روز، متوجه می‌شوند کلیدهای API، رمزهای عبور، یا اطلاعات داخلی در تاریخچه commitهای قدیمی باقی مانده است. حذف این اطلاعات پس از انتشار عمومی تقریباً غیرممکن است، زیرا مخزن توسط افراد زیادی فورک (Fork) شده و کپی‌هایی از تاریخچه در سیستم‌های مختلف وجود دارد.

مواردی که باید به دقت پاکسازی شوند

  • کلیدهای API و توکن‌های دسترسی به سرویس‌های ابری مانند AWS، Google Cloud و Azure
  • فایل‌های .env و سایر فایل‌های حاوی متغیرهای محیطی با اعتبارنامه‌ها
  • نام کاربری و رمزهای عبور (حتی در کامنت‌های کد یا فایل‌های متنی)
  • آدرس‌های ایمیل داخلی سازمان و نام‌های کامل کارکنان (مگر با اجازه صریح آن‌ها)
  • نام‌های کد داخلی پروژه‌ها، مسیرهای فایل‌های سیستمی، و نام میزبان‌های داخلی شبکه
  • فایل‌های باینری حجیم مانند فایل‌های JAR، DLL، یا تصاویر Docker
  • گواهی‌های SSL/TLS و کلیدهای خصوصی SSH

ابزارهای متعددی برای پاکسازی تاریخچه گیت وجود دارد که از جمله معروف‌ترین آن‌ها می‌توان به BFG Repo-Cleaner و ابزار رسمی git filter-repo اشاره کرد. این ابزارها می‌توانند کل تاریخچه مخزن را اسکن کرده و اطلاعات حساس را با استفاده از عبارات منظم (Regex) یا لیست‌های سیاه، شناسایی و حذف کنند. توجه داشته باشید که این عملیات، تاریخچه commitها را بازنویسی می‌کند و تمام اعضای تیم باید پس از آن، مخزن محلی خود را با مخزن جدید هماهنگ کنند.

دستورات مفید برای جستجوی دستی اطلاعات محرمانه

برای جستجوی نام‌های کاربری خاص در کامنت‌های TODO داخل کد، می‌توانید از دستور زیر استفاده کنید:

egrep -r 'TODO\(([^b]|b[^/])[^)]*\)' <path-to-source-directory>

برای جستجوی نام میزبان‌های دامنه داخلی، آدرس‌های ایمیل سازمانی، یا آدرس‌های IP ثابت:

grep -rP '\.google\.com|@google\.com|([0-9]+\.){3}[0-9]+' <path-to-source-directory>

۱-۲. تعریف اهداف و موقعیت‌یابی پروژه

پیش از هر اقدامی برای انتشار، باید به روشنی مشخص کنید که پروژه شما چه مسئله‌ای را حل می‌کند، کاربران هدف چه کسانی هستند، و چه مزیت‌های رقابتی نسبت به پروژه‌های مشابه دارد. این مرحله که به آن «پروپوزیشن و ارزش پیشنهادی» (Value Proposition) می‌گویند، به شما کمک می‌کند تا پیام پروژه را به درستی منتقل کرده و جامعه مناسب را جذب کنید. بدون یک موقعیت‌یابی مشخص، پروژه شما در میان انبوه پروژه‌های متن‌باز گم خواهد شد.

سوالات کلیدی که باید به آن‌ها پاسخ دهید

  • پروژه من چه کار جدید و منحصربه‌فردی را ممکن می‌سازد که قبلاً ممکن نبود؟
  • کاربر هدف من دقیقاً چه نقشی در سازمان خود دارد و با چه چالش‌های روزمره‌ای روبروست؟
  • چرا یک کاربر باید زحمت یادگیری و استفاده از پروژه من را به جای پروژه‌های مشابه و تثبیت‌شده به جان بخرد؟
  • چرا یک توسعه‌دهنده باید وقت آزاد خود را صرف مشارکت در پروژه من کند، نه پروژه‌های بزرگ‌تر و شناخته‌شده‌تر؟

همچنین، تهیه یک نقشه راه (Roadmap) اولیه با نقاط عطف مشخص برای ۶ تا ۱۲ ماه آینده، به شدت توصیه می‌شود. این نقشه راه نشان می‌دهد که پروژه زنده است، جهت‌گیری مشخصی دارد، و توسعه‌دهندگان جدید می‌توانند بر اساس آن، برنامه‌ریزی کنند.


بخش دوم: انتخاب مجوز متن‌باز

۲-۱. اهمیت انتخاب مجوز مناسب

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

۲-۲. توصیه‌های کلی و هشدارها

هرگز، تحت هیچ شرایطی، مجوز اختصاصی خود را طراحی نکنید. در حال حاضر بیش از ۸۰ مجوز تأییدشده توسط مؤسسه ابتکارات متن‌باز (OSI) وجود دارد که تقریباً تمام سناریوهای ممکن را پوشش می‌دهند. طراحی مجوز جدید نه تنها غیرضروری است، بلکه به دلیل ناآشنایی جامعه با آن، باعث ایجاد ابهام، سردرگمی، و در نهایت، کاهش مشارکت و استفاده می‌شود.

۲-۳. دسته‌بندی اصلی مجوزها

مجوزهای متن‌باز به دو دسته کلی تقسیم می‌شوند: مجوزهای Permissive (با حداقل محدودیت) و مجوزهای Copyleft (با الزام به اشتراک‌گذاری تغییرات).

دسته اول: مجوزهای Permissive

این مجوزها حداکثر آزادی را برای کاربران فراهم می‌کنند و اجازه می‌دهند که کد منبع، حتی در نرم‌افزارهای اختصاصی (Proprietary) و بسته، بدون نیاز به انتشار کد تغییرات، مورد استفاده قرار گیرد.

مجوز MIT: این مجوز، ساده‌ترین و در عین حال محبوب‌ترین مجوز متن‌باز در جهان است. طبق آمارهای عمومی، بخش بزرگی از مخازن عمومی از این مجوز استفاده می‌کنند. تنها شرط آن، حفظ اطلاعیه کپی‌رایت و متن مجوز در تمام کپی‌ها و توزیع‌ها است. مزیت اصلی MIT، حداکثر پذیرش در اکوسیستم‌های مختلف است.

مجوز Apache License 2.0: این مجوز که توسط بنیاد نرم‌افزار آپاچی مدیریت می‌شود، مشابه MIT است اما با چند تفاوت کلیدی. مهم‌ترین تفاوت، حمایت صریح از حق ثبت اختراع (Patent Grant) است؛ یعنی مشارکت‌کنندگان در پروژه، به‌طور خودکار به کاربران اجازه استفاده از هرگونه ثبت اختراع مرتبط با کد خود را می‌دهند. همچنین، این مجوز نیاز به مستندسازی تغییرات ایجاد شده در فایل‌های کد دارد. این مجوز برای پروژه‌های شرکتی و پروژه‌هایی که نگران مسائل ثبت اختراع هستند، گزینه ایده‌آلی است.

مجوزهای BSD: مجوز BSD در دو نسخه اصلی وجود دارد. BSD 2-Clause که عملاً مشابه MIT است و فقط نیاز به حفظ کپی‌رایت دارد. BSD 3-Clause که یک محدودیت اضافی دارد و اجازه نمی‌دهد از نام پروژه یا نام مشارکت‌کنندگان برای تأیید محصولات مشتق‌شده بدون اجازه کتبی استفاده شود.

دسته دوم: مجوزهای Copyleft

این مجوزها که به آن‌ها مجوزهای «ویروسی» یا «بازتابنده» نیز گفته می‌شود، تضمین می‌کنند که تغییرات ایجاد شده در کد و همچنین هرگونه مشتق از آن، نیز باید تحت همان مجوز (یا مجوزی سازگار) منتشر شوند.

مجوز GNU General Public License (GPL): این مجوز که توسط بنیاد نرم‌افزار آزاد (FSF) منتشر شده، معروف‌ترین مجوز Copyleft است. نسخه دوم (GPL v2) در پروژه‌های عظیمی مانند لینوکس کرنل و گیت استفاده می‌شود. نسخه سوم (GPL v3) که جدیدتر است، حمایت صریح‌تری از حق ثبت اختراع ارائه می‌دهد و همچنین شامل بندی برای جلوگیری از Tivoization است.

مجوز GNU Affero General Public License (AGPL): این مجوز، نسخه توسعه‌یافته GPL برای عصر محاسبات ابری و نرم‌افزارهای SaaS است. طبق AGPL، اگر نرم‌افزار را به عنوان یک سرویس شبکه‌ای میزبانی کنید و کاربران از طریق شبکه به آن دسترسی داشته باشند، حتی اگر کد را توزیع نکنید، باید کد منبع کامل را در دسترس کاربران خود قرار دهید.

۲-۴. راهنمای عملی انتخاب مجوز

  • حداکثر پذیرش در نرم‌افزارهای اختصاصی: مجوز MIT یا BSD
  • پذیرش گسترده با حمایت قانونی از حق ثبت اختراع: مجوز Apache 2.0
  • متن‌باز ماندن کتابخانه اما اجازه استفاده در نرم‌افزارهای اختصاصی: مجوز LGPL یا MPL 2.0
  • متن‌باز ماندن تمام مشتقات توزیع‌شده: مجوز GPL
  • متن‌باز ماندن مشتقات حتی در حالت SaaS: مجوز AGPL

۲-۵. نکات حقوقی مهم

توجه داشته باشید که مجوز MIT حمایت صریحی از حق ثبت اختراع ارائه نمی‌دهد. مجوز Apache 2.0 شامل بندی به نام «بازپس‌گیری دفاعی» (Defensive Termination) است. از نظر سازگاری مجوزها، GPL v3 با Apache 2.0 کاملاً سازگار است، اما GPL v2 با Apache 2.0 سازگار نیست. تجربه نشان داده است که پروژه‌های متن‌بازی که مجوز مشخص و استانداردی ندارند، به طور قابل‌توجهی طول عمر کوتاه‌تری دارند و مشارکت‌کنندگان کمتری جذب می‌کنند.


بخش سوم: مستندسازی پروژه

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

۳-۱. README.md - صفحه اصلی پروژه

فایل README اولین چیزی است که بازدیدکنندگان مخزن شما می‌بینند. این فایل باید در بالای صفحه نمایش داده شود و باید به روشنی بیان کند که پروژه چیست، چه کاری انجام می‌دهد، چگونه شروع به کار کنند، و کجا می‌توانند اطلاعات بیشتری پیدا کنند.

عناصر ضروری و غیرقابل‌حذف در README

  • نام و لوگوی پروژه (در صورت وجود)
  • یک خط شعار (Tagline) که به اختصار کاربرد پروژه را بیان کند
  • توضیح مختصر و غیرفنی درباره مسئله‌ای که پروژه حل می‌کند
  • حداقل یک مثال عملی و واقعی از استفاده از پروژه با خروجی نمونه
  • راهنمای گام‌به‌گام نصب و شروع سریع (Quick Start) که در کمتر از ۵ دقیقه قابل انجام باشد
  • لینک به مستندات کامل‌تر (اگر پروژه بزرگ است، یک سایت مستندات جداگانه داشته باشد)
  • نشان‌های وضعیت (Badge) مانند وضعیت Build، پوشش تست، و آخرین نسخه منتشرشده

۳-۲. CONTRIBUTING.md - راهنمای مشارکت

این فایل، نقشه راه مشارکت‌کنندگان جدید است و به آن‌ها نشان می‌دهد که چگونه می‌توانند در پروژه مشارکت کنند. یک CONTRIBUTING.md خوب، نه تنها مشارکت را تشویق می‌کند، بلکه کیفیت مشارکت‌ها را نیز تضمین می‌کند. این فایل باید شامل موارد زیر باشد:

  • فرایند کامل ارسال Pull Request از فورک کردن مخزن تا ارسال درخواست
  • استانداردهای کدنویسی (نحوه نام‌گذاری، ساختار فایل‌ها، و قالب‌بندی کد)
  • نحوه اجرای تست‌ها به صورت محلی قبل از ارسال کد
  • نحوه گزارش باگ‌ها و درخواست ویژگی‌های جدید از طریق Issue tracker
  • انتظارات اخلاقی از مشارکت‌کنندگان و ارجاع به کد رفتار

۳-۳. SECURITY.md - گزارش آسیب‌پذیری‌ها

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

۳-۴. فایل‌های الگو (Templates)

  • Issue templates: الگوهای استانداردی که هنگام ایجاد Issue جدید به کاربران نمایش داده می‌شوند. الگوهای رایج شامل «گزارش باگ» و «درخواست ویژگی جدید» هستند.
  • Pull Request template: یک چک‌لیست که هنگام ارسال Pull Request به مشارکت‌کننده نمایش داده می‌شود.
  • برچسب‌گذاری (Labeling): استفاده از برچسب‌هایی مانند good first issue برای معرفی مسائل مناسب برای مبتدیان، و help wanted برای مسائلی که نیاز به کمک دارند.

بخش چهارم: ساختار مخزن و فایل‌های ضروری

۴-۱. فایل LICENSE

هر مخزن متن‌باز، بدون استثنا، باید شامل یک فایل LICENSE در ریشه اصلی پروژه باشد. نام فایل باید دقیقاً LICENSE یا LICENSE.md باشد تا توسط پلتفرم‌هایی مانند GitHub شناسایی شود. علاوه بر این، بهترین شیوه صنعت این است که یک هدر مجوز (کپی‌رایت و اعلامیه مجوز) در بالای تمام فایل‌های کد منبع قرار گیرد.

نمونه کامل هدر مجوز Apache 2:

Copyright [سال انتشار] [نام صاحب کپی‌رایت]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

۴-۲. فایل‌های ضروری دیگر

  • .gitignore: این فایل مشخص می‌کند که کدام فایل‌ها و پوشه‌ها نباید به مخزن گیت commit شوند. مثال‌های رایج شامل پوشه node_modules، فایل‌های log، فایل‌های .env، و فایل‌های موقت سیستمی هستند.
  • CHANGELOG.md: این فایل، یک تاریخچه زمانی از تغییرات بین نسخه‌های مختلف پروژه است. هر نسخه باید شامل بخش‌های «ویژگی‌های جدید»، «بهبودها»، «رفع باگ‌ها»، و «تغییرات مخرب» باشد.
  • CODEOWNERS: این فایل در پوشه .github قرار می‌گیرد و مشخص می‌کند که هر بخش از کد توسط چه کسی یا چه تیمی باید بررسی شود.
  • پوشه .github: این پوشه حاوی فایل‌های پیکربندی مربوط به GitHub Community Health است.

بخش پنجم: حکمرانی و جامعه‌سازی

حکمرانی (Governance) به مجموعه قوانین، رویه‌ها، و ساختارهای تصمیم‌گیری در پروژه اشاره دارد که مشخص می‌کند چگونه تصمیمات گرفته می‌شود، چه کسانی مسئول چه بخش‌هایی هستند، و چگونه تعارضات حل می‌شود. حکمرانی شفاف، اعتماد جامعه را جلب می‌کند و از ایجاد هرج‌ومرج در پروژه جلوگیری می‌کند.

۵-۱. کد رفتار (Code of Conduct)

کد رفتار، سندی است که هنجارها، ارزش‌ها، و انتظارات از مشارکت‌کنندگان در پروژه و جامعه را مشخص می‌کند و باید عواقب نقض آن را نیز شرح دهد. استفاده از استانداردهای شناخته‌شده و آماده مانند Contributor Covenant به شدت توصیه می‌شود.

۵-۲. نقش‌ها و مسئولیت‌ها

  • Maintainer (نگهدارنده اصلی): این افراد مسئول مدیریت کلی پروژه، بررسی و ادغام Pull Requestها، انتشار نسخه‌های جدید، و تعیین جهت‌گیری استراتژیک پروژه هستند.
  • Committer: این افراد دسترسی مستقیم (Write Access) به مخزن اصلی برای اعمال تغییرات دارند.
  • Contributor: مشارکت‌کنندگانی که از طریق Pull Request در پروژه مشارکت می‌کنند اما دسترسی مستقیم به مخزن ندارند.
  • Community Member: کاربرانی که در بحث‌های پروژه شرکت می‌کنند، باگ گزارش می‌دهند، یا درخواست ویژگی مطرح می‌کنند.

۵-۳. فرایندهای کلیدی عملیاتی

Triage Issues: به‌طور منظم (مثلاً هفته‌ای یکبار) Issueهای جدید را بررسی کنید، اولویت‌بندی کنید، و آن‌ها را به اعضای تیم یا برچسب help wanted اختصاص دهید.

Merge Reviews: یک سیستم نوبتی برای بررسی Pull Requestها ایجاد کنید تا هیچ درخواستی بدون پاسخ نماند. تعیین کنید که هر Pull Request حداقل به تأیید ۲ نفر نیاز دارد تا کیفیت کد تضمین شود.

ارتباط با جامعه: از ابزارهای مختلفی مانند GitHub Discussions برای سوالات عمومی، انجمن‌های تخصصی، و کانال‌های پیام‌رسان مانند Discord یا Slack برای تعامل سریع استفاده کنید.


بخش ششم: زیرساخت و ابزارها

۶-۱. ابزارهای رایگان و متن‌باز برای کیفیت و امنیت

  • OWASP Dependency-Check: ابزاری برای اسکن خودکار وابستگی‌های پروژه و شناسایی آسیب‌پذیری‌های شناخته‌شده در آن‌ها.
  • SonarQube (نسخه Community): یک پلتفرم جامع برای تحلیل کیفیت کد، شناسایی باگ‌های بالقوه، و نشت‌های امنیتی.
  • CodeQL: یک موتور تحلیل ایستای کد که توسط GitHub توسعه یافته و به‌طور پیش‌فرض در مخازن عمومی GitHub فعال است.
  • Prettier و Checkstyle: ابزارهای فرمت‌کننده خودکار کد که تضمین می‌کنند تمام کدهای پروژه از یک سبک یکسان پیروی کنند.
  • Jest، JUnit، و Cypress: فریمورک‌های تست خودکار برای زبان‌های مختلف.
  • Release-Drafter: یک ابزار GitHub Actions که به‌طور خودکار یادداشت‌های انتشار را تولید می‌کند.
  • Docusaurus: یک ابزار محبوب برای ایجاد و میزبانی سایت‌های مستندات پروژه.

۶-۲. یکپارچه‌سازی مداوم (CI/CD)

راه‌اندازی یک خط لوله یکپارچه‌سازی مداوم (CI/CD) برای اجرای خودکار تست‌ها، تحلیل کد، و بررسی کیفیت در هر Pull Request، یک ضرورت غیرقابل‌انکار است. ابزارهایی مانند GitHub Actions، GitLab CI، و Jenkins می‌توانند این کار را انجام دهند.

۶-۳. بررسی مستقل وابستگی‌ها

به‌طور منظم (مثلاً ماهانه)، تمام وابستگی‌های پروژه را برای یافتن آسیب‌پذیری‌های شناخته‌شده اسکن کنید. ابزارهایی مانند npm audit، OWASP Dependency-Check، و Snyk می‌توانند در این زمینه کمک کنند. همچنین، فعال‌سازی Dependabot در GitHub می‌تواند به‌طور خودکار درخواست‌های به‌روزرسانی ایجاد کند.


بخش هفتم: فرایند انتشار رسمی

۷-۱. مرحله ۱: آماده‌سازی نهایی پروژه

  • نام‌گذاری نهایی پروژه: یک نام منحصربه‌فرد و مرتبط با کاربرد پروژه انتخاب کنید.
  • پاکسازی نهایی: یک بار دیگر کل مخزن را برای یافتن اطلاعات محرمانه احتمالی بررسی کنید.
  • تکمیل مستندات: اطمینان حاصل کنید که فایل‌های README، CONTRIBUTING، LICENSE، و هدر مجوز در تمام فایل‌های کد کامل هستند.
  • تست نهایی: تمام لینترها، تست‌های واحد، تست‌های یکپارچه، و تست‌های End-to-End را اجرا کنید.

۷-۲. مرحله ۲: دریافت تأییدیه (در سازمان‌های بزرگ)

در سازمان‌های بزرگ و شرکت‌های نرم‌افزاری، معمولاً فرایند تأیید داخلی برای انتشار کد به صورت متن‌باز وجود دارد. نهادهای درگیر در فرایند تأیید:

  • تیم حقوقی: مجوز انتخابی شما را بررسی می‌کند تا اطمینان حاصل کند که با سیاست‌های کلی سازمان سازگار است.
  • تیم امنیت: یک اسکن امنیتی کامل روی کد شما انجام می‌دهد.
  • تیم مدیریت محصول یا مدیر فنی: بررسی می‌کند که آیا پروژه از نظر فنی به اندازه کافی بالغ است.
  • دفتر مدیریت پروژه یا تیم ارتباطات: برنامه‌ریزی می‌کند که چگونه و چه زمانی پروژه به جامعه معرفی شود.

۷-۳. مرحله ۳: انتشار نهایی و عمومی

  • مخزن عمومی را در پلتفرم مورد نظر ایجاد کنید.
📘 گزینه‌های میزبانی داخلی: اگر به دلیل محدودیت‌های دسترسی، نمی‌توانید از GitHub یا GitLab استفاده کنید، سرویس‌های میزبانی داخلی نیز وجود دارند. برای نمونه، پایاگیت (بر پایه Gitea، در حال حاضر در مرحله آزمایشی) یکی از این گزینه‌هاست. برای آشنایی بیشتر با این سرویس، مقاله معرفی پایاگیت را ببینید.
  • کد را از مخزن داخلی به مخزن عمومی push کنید.
  • پروژه را در دیتابیس یا فهرست پروژه‌های متن‌باز سازمان خود ثبت کنید.
  • پروژه را به جامعه معرفی کنید (وبلاگ، شبکه‌های اجتماعی، انجمن‌های تخصصی).
  • نسخه اولیه (v1.0.0 یا v0.1.0) را در GitHub Releases ایجاد کنید.

۷-۴. انتشار نسخه‌های جدید

پس از انتشار نسخه اولیه، فرایند انتشار نسخه‌های بعدی باید به صورت منظم و ساختاریافته انجام شود. توصیه می‌شود که از یک روش استاندارد مانند Semantic Versioning (SemVer) برای شماره‌گذاری نسخه‌ها استفاده کنید که شامل سه بخش است: MAJOR.MINOR.PATCH. افزایش MAJOR برای تغییرات ناسازگار، افزایش MINOR برای افزودن ویژگی‌های جدید به صورت سازگار، و افزایش PATCH برای رفع باگ‌ها.

۷-۵. به‌روزرسانی متادیتا

برای هر نسخه جدید، متادیتای پروژه باید به‌روزرسانی شود: شماره نسخه، وضعیت پروژه، تاریخ به‌روزرسانی، و لینک‌های دانلود.


بخش هشتم: پایداری، تأمین مالی و مدل‌های کسب‌وکار

۸-۱. چالش پایداری طولانی‌مدت

یکی از بزرگ‌ترین چالش‌های پروژه‌های متن‌باز، پایداری طولانی‌مدت است. تجربه نشان می‌دهد که بخش قابل‌توجهی از پروژه‌های متن‌باز در چند سال اول عمر خود، به دلیل کاهش فعالیت نگهدارندگان یا نبود منابع کافی، دچار رکود می‌شوند. دلایل اصلی این رکود عبارتند از: فرسودگی و خستگی نگهدارنده‌ها، کمبود مشارکت‌کنندگان جدید، تغییر اولویت‌های تیم توسعه‌دهنده اصلی، و نبود منابع مالی برای ادامه توسعه و نگهداری.

۸-۲. تعیین انتظارات واقع‌بینانه برای نگهدارنده‌ها

  • نقش‌ها و مسئولیت‌ها را به‌روشنی تعریف کنید.
  • سطح خدمات (SLA) مشخصی برای پاسخ به Issueها و Pull Requestها تعیین کنید.
  • به نگهدارنده‌ها این قدرت را بدهید که به درخواست‌ها «نه» بگویند و اولویت‌بندی کنند.
  • فرایندهای تصمیم‌گیری را شفاف کنید.

۸-۳. گزینه‌های تأمین مالی پروژه

  • GitHub Sponsors: این برنامه به افراد و سازمان‌ها اجازه می‌دهد که به‌صورت ماهیانه از پروژه‌های متن‌باز حمایت مالی کنند.
  • Open Collective: یک پلتفرم مشابه که مدیریت شفاف هزینه‌ها و کمک‌های مالی را فراهم می‌کند.
  • مدل Dual-Licensing (مجوز دوگانه): پروژه تحت یک مجوز قوی Copyleft منتشر می‌شود، اما شرکت‌ها می‌توانند یک مجوز تجاری از شما خریداری کنند.
  • حمایت شرکتی: بسیاری از شرکت‌های بزرگ از پروژه‌های متن‌بازی که به آن‌ها وابسته هستند، حمایت مالی می‌کنند.
  • بنیادهای نرم‌افزاری: پیوستن به یک بنیاد نرم‌افزاری مانند بنیاد لینوکس، بنیاد آپاچی، یا بنیاد اکلیپس.

۸-۴. مسئله سواری رایگان (Free-Rider Problem)

نرم‌افزارهای متن‌باز به طور ذاتی از مشکل «سواری رایگان» رنج می‌برند. با این حال، دیدگاه مثبت‌تری نیز وجود دارد: حضور کاربران بیشتر (حتی سواری‌گیرندگان) احتمال مشارکت دیگران را افزایش می‌دهد، زیرا پروژه دیده‌تر و پرکاربردتر می‌شود.


بخش نهم: معیارهای سنجش موفقیت و سلامت پروژه

۹-۱. معیارهای جامعه (Community Metrics)

  • تعداد ستاره‌ها و فورک‌ها: نشان‌دهنده محبوبیت و دسترسی اولیه پروژه هستند.
  • تعداد Issueهای باز و بسته: نسبت Issueهای بسته‌شده به باز، نشان‌دهنده پاسخ‌گویی و کارایی تیم است.
  • تعداد Pull Requestهای باز و ادغام‌شده: نشان‌دهنده فعالیت و پاسخ‌گویی تیم به مشارکت‌کنندگان است.
  • تعداد مشارکت‌کنندگان جدید: نشان‌دهنده توانایی پروژه در جذب تازه‌واردان است.
  • نرخ حفظ مشارکت‌کنندگان: نشان می‌دهد که چه درصدی از مشارکت‌کنندگان دوباره بازمی‌گردند.

۹-۲. معیارهای فنی (Technical Metrics)

  • پوشش تست (Test Coverage): برای پروژه‌های جدی، هدف‌گذاری روی پوشش تست بالا (معمولاً بالای ۷۰٪ برای بخش‌های حیاتی) توصیه می‌شود.
  • تعداد آسیب‌پذیری‌های امنیتی کشف و برطرف‌شده: نشان‌دهنده بلوغ امنیتی پروژه است.
  • امتیاز کیفیت کد: ابزارهایی مانند SonarQube یک امتیاز عددی به کیفیت کد اختصاص می‌دهند.
  • تعداد وابستگی‌های مستقیم و غیرمستقیم: تعداد زیاد وابستگی‌ها می‌تواند یک ریسک بزرگ باشد.

۹-۳. معیارهای عملیاتی (Operational Metrics)

  • میانگین زمان پاسخ به Issue: باید کمتر از ۴۸ ساعت باشد.
  • میانگین زمان بررسی Pull Request: باید کمتر از ۷۲ ساعت باشد.
  • درصد پروژه‌های متن‌بازشده نسبت به کل پروژه‌ها: نشان‌دهنده تعهد سازمان به متن‌باز بودن است.

۹-۴. معیارهای ترکیبی سلامت پروژه

  • افراد جدید بتوانند در عرض ۳۰ دقیقه محیط توسعه را راه‌اندازی کنند.
  • مشارکت‌کنندگان بدانند چگونه یک Pull Request ارسال کنند بدون نیاز به پرسش.
  • به Issueها در چارچوب SLA پاسخ داده شود.
  • نقشه راه پروژه به صورت عمومی قابل مشاهده باشد.
  • یک فرایند خصوصی و امن برای گزارش مسائل امنیتی وجود داشته باشد.
  • نگهداری آن پایدار باشد و نگهدارنده‌ها احساس فرسودگی نکنند.

بخش دهم: چک‌لیست نهایی انتشار

۱۰-۱. چک‌لیست پیش از انتشار

  • پاکسازی کامل تاریخچه گیت از اطلاعات محرمانه، کلیدهای API، و اعتبارنامه‌ها
  • انتخاب مجوز مناسب و اطمینان از سازگاری با وابستگی‌های پروژه
  • نوشتن و تکمیل فایل‌های README.md، CONTRIBUTING.md، SECURITY.md، و CHANGELOG.md
  • افزودن هدر مجوز به تمام فایل‌های کد منبع
  • راه‌اندازی و تست کامل CI/CD
  • تعیین نقش‌ها و ساختار حکمرانی
  • ایجاد الگوهای Issue و Pull Request
  • اسکن نهایی وابستگی‌ها از نظر آسیب‌پذیری‌های امنیتی
  • دریافت تأییدیه‌های لازم از تیم‌های حقوقی، امنیت، و مدیریت

۱۰-۲. چک‌لیست حین انتشار

  • دریافت تأییدیه نهایی از تمام نهادهای ذی‌صلاح
  • ایجاد مخزن عمومی و پیکربندی تنظیمات اولیه
  • انتقال کد به مخزن عمومی
  • ثبت پروژه در دیتابیس یا فهرست پروژه‌های متن‌باز سازمان
  • ایجاد نسخه اولیه در GitHub Releases
  • معرفی پروژه به جامعه
  • ارسال پروژه به فهرست‌های معروف پروژه‌های متن‌باز

۱۰-۳. چک‌لیست پس از انتشار

  • تعیین فرایند Triage برای Issueها
  • راه‌اندازی کانال‌های ارتباطی رسمی با جامعه
  • نظارت بر معیارهای موفقیت و ثبت آن‌ها
  • برنامه‌ریزی برای انتشار نسخه‌های بعدی
  • بررسی گزینه‌های تأمین مالی
  • پاسخگویی فعال به سوالات و بازخوردهای جامعه
  • برگزاری یک جلسه آنلاین برای معرفی پروژه
  • نظارت بر بحث‌های مربوط به پروژه در فضای مجازی

۱۰-۴. جمع‌بندی نهایی و توصیه‌های کلیدی

  • شفافیت کلید اعتماد: همیشه فرایندهای تصمیم‌گیری، نقشه راه، و وضعیت پروژه را شفاف اعلام کنید.
  • جامعه مهم‌ترین دارایی شماست: روی ایجاد یک جامعه مثبت و حمایت‌گر سرمایه‌گذاری کنید.
  • کیفیت بر کمیت اولویت دارد: یک پروژه با کیفیت بهتر از پروژه‌ای با ویژگی‌های زیاد اما بی‌کیفیت است.
  • انتظارات را واقع‌بینانه تنظیم کنید: تعیین مرزهای مشخص، از فرسودگی جلوگیری می‌کند.
  • از بازخورد منفی نترسید: انتقاد سازنده، بهترین فرصت برای بهبود است.
  • مستندات را همواره به‌روز نگه دارید: مستندات قدیمی، بدتر از بدون مستندات است.
  • جشن بگیرید و موفقیت‌ها را به رسمیت بشناسید: قدردانی از تلاش‌ها، انگیزه را افزایش می‌دهد.

۱۰-۵. کلام پایانی

دنیای نرم‌افزارهای متن‌باز، یکی از بزرگ‌ترین دستاوردهای بشری در حوزه فناوری است. با انتشار پروژه خود به صورت متن‌باز، شما نه تنها به این اکوسیستم ارزشمند کمک می‌کنید، بلکه فرصتی بی‌نظیر برای یادگیری، شبکه‌سازی، و رشد حرفه‌ای خود فراهم می‌کنید. با پیروی از این راهنمای جامع و گام‌به‌گام، شما تمام ابزارها و دانش لازم برای انتشار یک پروژه متن‌باز موفق را در اختیار دارید.


بخش یازدهم: نکات پیشرفته و سناریوهای خاص

۱۱-۱. مدیریت پروژه‌های چندزبانه (Multi-Language Projects)

اگر پروژه شما از چندین زبان برنامه‌نویسی استفاده می‌کند، مدیریت آن پیچیده‌تر می‌شود. در این حالت، باید ساختار مخزن را به گونه‌ای طراحی کنید که هر زیرپروژه به صورت مستقل قابل مدیریت باشد. پیشنهاد می‌شود از ساختار Monorepo با پوشه‌های جداگانه برای هر زبان استفاده کنید و برای هر پوشه، فایل‌های پیکربندی، تست، و مستندات جداگانه داشته باشید.

۱۱-۲. مهاجرت از پروژه داخلی به متن‌باز

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

۱۱-۳. پروژه‌های با وابستگی‌های سنگین به سرویس‌های ابری

برخی پروژه‌ها به شدت به سرویس‌های ابری خاصی مانند AWS، Google Cloud، یا Azure وابسته هستند. بهترین راهکار این است که یک لایه انتزاعی (Abstraction Layer) برای سرویس‌های ابری طراحی کنید تا کاربران بتوانند از هر سرویس‌دهنده‌ای استفاده کنند.

۱۱-۴. مدیریت نسخه‌های متعدد و پشتیبانی از نسخه‌های قدیمی (LTS)

پروژه‌های بزرگ معمولاً چندین نسخه را به‌طور همزمان پشتیبانی می‌کنند. برای مدیریت این وضعیت، باید یک سیاست مشخص برای پشتیبانی از نسخه‌ها تعیین کنید. به عنوان مثال، اعلام کنید که هر نسخه به مدت ۲ سال پس از انتشار، پشتیبانی امنیتی دریافت می‌کند.

۱۱-۵. پروژه‌های با داده‌های حساس یا مدل‌های یادگیری ماشین

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

۱۱-۶. مدیریت بحث‌ها و اختلافات در جامعه

در هر جامعه متن‌بازی، ممکن است اختلافات و بحث‌های داغی بین اعضا ایجاد شود. مدیریت صحیح این اختلافات، برای حفظ سلامت جامعه حیاتی است. اولین قدم، داشتن یک کد رفتار (Code of Conduct) قوی و شفاف است.

۱۱-۷. استفاده از تحلیل‌گرهای آماری برای بهبود پروژه

ابزارهای تحلیل آماری مخزن مانند GrimoireLab، Augur، و Cauldron می‌توانند داده‌های جامعی درباره فعالیت مخزن، مشارکت‌کنندگان، و روندها به شما ارائه دهند.

۱۱-۸. پروژه‌های با مستندات تعاملی و آموزشی

اگر پروژه شما یک کتابخانه، فریمورک، یا ابزار آموزشی است، ایجاد مستندات تعاملی می‌تواند تجربه کاربری را به شدت بهبود بخشد. مستندات تعاملی شامل مثال‌های زنده (Live Examples) است که کاربران بتوانند کد را در مرورگر اجرا و نتیجه را ببینند.

۱۱-۹. یکپارچه‌سازی با ابزارهای تحلیل کد و بازخورد خودکار

برای افزایش کیفیت کد به صورت خودکار، می‌توانید از ربات‌های تحلیل کد مانند Dependabot، Stale Bot، و Welcome Bot استفاده کنید. این ربات‌ها می‌توانند بار مدیریتی تیم را کاهش دهند و به پاسخ‌گویی سریع‌تر کمک کنند.

۱۱-۱۰. مهاجرت از یک پلتفرم به پلتفرم دیگر

اگر پروژه شما در ابتدا روی GitLab میزبانی می‌شد و تصمیم به مهاجرت به GitHub دارید، باید این مهاجرت را با دقت برنامه‌ریزی کنید تا تاریخچه، Issueها، و Pull Requestها از بین نروند.


بخش دوازدهم: مطالعه موردی یک پروژه فرضی

برای درک بهتر تمام مراحل گفته‌شده، بیایید یک پروژه فرضی به نام DataFlow را بررسی کنیم. DataFlow یک کتابخانه پایتون برای پردازش جریان داده‌ها (Stream Processing) است که توسط یک تیم ۵ نفره در یک شرکت فناوری متوسط توسعه داده شده است.

مرحله ۱ - آماده‌سازی (۳ هفته قبل از انتشار)

تیم ابتدا تاریخچه مخزن را با استفاده از BFG Repo-Cleaner پاکسازی می‌کند و ۳ مورد کلید API و ۵ مورد آدرس ایمیل داخلی را حذف می‌کند. آن‌ها یک جلسه برگزار می‌کنند و پاسخ سوالات کلیدی موقعیت‌یابی را می‌نویسند.

مرحله ۲ - انتخاب مجوز (۲ هفته قبل از انتشار)

تیم با مشورت تیم حقوقی شرکت، مجوز Apache 2.0 را انتخاب می‌کند. آن‌ها فایل LICENSE را در ریشه مخزن ایجاد می‌کنند و هدر مجوز را به تمام ۱۲۰ فایل پایتون پروژه اضافه می‌کنند.

مرحله ۳ - مستندسازی (۲ هفته قبل از انتشار)

تیم README.md را می‌نویسند و یک مثال عملی از پردازش لاگ‌های وب‌سایت در آن قرار می‌دهند. آن‌ها CONTRIBUTING.md را با استانداردهای کدنویسی پایتون (PEP 8)، نحوه اجرای تست‌ها با pytest، و فرایند ارسال Pull Request تکمیل می‌کنند.

مرحله ۴ - زیرساخت (۱ هفته قبل از انتشار)

تیم یک GitHub Actions Pipeline راه‌اندازی می‌کند که در هر Pull Request، تست‌ها را اجرا کرده، پوشش تست را با Codecov محاسبه می‌کند، و وابستگی‌ها را با OWASP Dependency-Check اسکن می‌کند.

مرحله ۵ - دریافت تأییدیه (۴ روز قبل از انتشار)

تیم درخواست انتشار خود را به تیم حقوقی، تیم امنیت، و مدیر فنی شرکت ارسال می‌کند. تیم حقوقی پس از ۲ روز تأیید می‌کند که مجوز Apache 2.0 با سیاست‌های شرکت سازگار است.

مرحله ۶ - انتشار (روز انتشار)

تیم مخزن عمومی را در GitHub ایجاد می‌کند و کد را انتقال می‌دهد. آن‌ها نسخه v0.1.0 را در GitHub Releases ایجاد می‌کنند و بسته pip را به PyPI منتشر می‌کنند. در عرض ۲۴ ساعت، پروژه ۲۰۰ ستاره و ۱۵ فورک دریافت می‌کند.

مرحله ۷ - پس از انتشار (هفته اول)

تیم به ۱۰ Issue اولیه پاسخ می‌دهد و ۳ Pull Request از مشارکت‌کنندگان جدید را بررسی و ادغام می‌کند. آن‌ها یک کانال Discord برای جامعه ایجاد می‌کنند و ۵۰ عضو در روز اول به آن می‌پیوندند.

مرحله ۸ - پایداری (ماه‌های بعد)

پس از ۶ ماه، DataFlow به ۲,۵۰۰ ستاره، ۴۵۰ فورک، و ۳۵ مشارکت‌کننده فعال رسیده است. تیم با کمک حمایت‌های مالی GitHub Sponsors، توانسته است یک توسعه‌دهنده جدید را به‌صورت پاره‌وقت استخدام کند.


بخش سیزدهم: سوالات متداول (FAQ)

سوال ۱: آیا می‌توانم پروژه خود را تحت چندین مجوز همزمان منتشر کنم؟

بله، این امکان وجود دارد و به آن «مجوز چندگانه» (Multi-Licensing) می‌گویند. در این حالت، کاربران می‌توانند یکی از مجوزهای ارائه‌شده را انتخاب کنند که با نیازهای آن‌ها سازگار است.

سوال ۲: اگر پروژه من شامل کدهای شخص ثالث با مجوزهای مختلف باشد، چه باید بکنم؟

باید مجوز هر یک از کتابخانه‌ها یا قطعه‌کدهای شخص ثالث را به‌دقت بررسی کنید و آن‌ها را در یک فایل NOTICE یا در انتهای فایل LICENSE خود فهرست کنید. همچنین، باید اطمینان حاصل کنید که مجوزهای انتخابی شما با یکدیگر سازگار هستند.

سوال ۳: چگونه می‌توانم مشارکت‌کنندگان را تشویق به ادامه مشارکت کنم؟

بهترین راه‌ها شامل قدردانی عمومی از مشارکت‌کنندگان، پاسخ سریع و مثبت به Pull Requestها، ارائه بازخورد سازنده، و ایجاد یک محیط دوستانه و حمایت‌گر است. اختصاص برچسب‌های good first issue به مسائل ساده نیز کمک‌کننده است.

سوال ۴: آیا باید پروژه خود را در چندین پلتفرم میزبانی کنم؟

معمولاً نیازی به این کار نیست و میزبانی در یک پلتفرم اصلی کافی است. تمرکز بر روی یک پلتفرم، مدیریت را ساده‌تر می‌کند و جامعه را در یک مکان متمرکز نگه می‌دارد.

سوال ۵: چگونه می‌توانم از پروژه خود در برابر سوءاستفاده‌های تجاری محافظت کنم؟

اگر نگران سوءاستفاده تجاری هستید، می‌توانید از مجوزهای Copyleft مانند GPL یا AGPL استفاده کنید. راه دیگر، استفاده از مدل Dual-Licensing است.

سوال ۶: چه زمانی باید نسخه ۱.۰.۰ را منتشر کنم؟

نسخه ۱.۰.۰ زمانی منتشر می‌شود که پروژه شما به اندازه کافی بالغ باشد، API آن پایدار باشد، مستندات کامل باشد، پوشش تست بالایی داشته باشد، و چندین کاربر در محیط تولید از آن استفاده کرده و بازخورد مثبت داده باشند.

سوال ۷: آیا پروژه‌های متن‌باز می‌توانند درآمدزایی داشته باشند؟

بله، کاملاً ممکن است. روش‌های متعددی مانند حمایت‌های مالی، فروش مجوزهای تجاری، ارائه خدمات پشتیبانی و مشاوره پولی، میزبانی نسخه‌های ابری (SaaS) با امکانات اضافی، و دریافت کمک‌های مالی از بنیادها وجود دارد.

سوال ۸: اگر پروژه من محبوب نشود، چه باید بکنم؟

محبوب نشدن یک پروژه، کاملاً طبیعی است و نباید آن را شکست تلقی کنید. می‌توانید از آن به عنوان یک نمونه کار (Portfolio) استفاده کنید، از آن در پروژه‌های شخصی خود بهره ببرید، و از فرایند یادگیری و تجربه‌ای که به دست آورده‌اید، قدردانی کنید.


بخش چهاردهم: جمع‌بندی و پیام به جامعه

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

به یاد داشته باشید که متن‌باز کردن یک پروژه، یک تعهد بلندمدت است. جامعه به شما اعتماد می‌کند و انتظار دارد که پروژه را زنده نگه دارید. بنابراین، قبل از انتشار، مطمئن شوید که آمادگی لازم برای این تعهد را دارید.

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

دسته‌بندی‌های مرتبط با این مطلب
آزمایشی

گفتگو درباره این پست

هنوز پیامی ثبت نشده است.



×
تصویر پروفایل
⏳ در حال بارگذاری...