مستودع واحد مع Go: تنظيم الكود للمشاريع القابلة للتوسع
في تطوير البرمجيات الحديث، يثار السؤال بشكل متزايد: كيف ننظم الكود بحيث يظل قابلاً للإدارة وإعادة الاستخدام والتوسع؟ أحد الحلول الشائعة هو استخدام المستودع الواحد (monorepo) — وهو مستودع واحد يحتوي على عدة مشاريع أو خدمات. في هذه المقالة، سنشرح كيفية تنظيم مستودع واحد بشكل فعال بلغة Go (Golang)، وسنستعرض أفضل الممارسات وهيكل الدلائل والعمل مع الوحدات وإعداد CI/CD.
ما هو المستودع الواحد ولماذا هو ضروري في Go؟
المستودع الواحد هو نهج يتم فيه تخزين جميع أكواد الشركة أو المشروع الكبير في مستودع واحد. يمكن أن يشمل ذلك:
- عدة خدمات مصغرة
- مكتبات وأدوات مساعدة
- إعدادات ونصوص برمجية
- توثيق
مزايا المستودع الواحد لـ Go:
- إصدار موحد للتبعيات — يلغي تعارضات الإصدارات بين الخدمات.
- تبسيط إعادة الهيكلة — التغييرات في المكتبة المشتركة تظهر فوراً لجميع المستهلكين.
- إعادة استخدام الكود بسهولة — لا حاجة لنشر الحزم في السجل.
- تاريخ موحد للالتزامات — يبسط التصحيح والتدقيق.
ومع ذلك، يتطلب المستودع الواحد انضباطاً: بدون هيكل واضح، يتحول بسرعة إلى "مزبلة". توفر Go مع نظام الوحدات الصارم (Go Modules) أدوات ممتازة لتنظيم مثل هذا المستودع.
هيكل الدلائل في المستودع الواحد لـ Go
الهيكل الصحيح هو أساس النجاح. دعنا نستعرض التنظيم الموصى به للمستودع الواحد بلغة Go:
my-monorepo/├── apps/ # التطبيقات (الخدمات، أدوات CLI)│ ├── api-gateway/│ │ ├── cmd/│ │ │ └── main.go│ │ ├── internal/│ │ ├── go.mod│ │ └── go.sum│ ├── auth-service/│ │ └── ...│ └── user-service/│ └── ...├── libs/ # المكتبات المشتركة│ ├── common/│ │ ├── logger.go│ │ ├── config.go│ │ ├── go.mod│ │ └── go.sum│ └── models/│ ├── user.go│ ├── go.mod│ └── go.sum├── scripts/ # نصوص البناء والنشر│ ├── build.sh│ └── deploy.sh├── docs/ # التوثيق├── .github/ # إعدادات CI/CD│ └── workflows/│ └── ci.yml├── go.work # ملف Workspace (Go 1.18+)├── Makefile # الأوامر المشتركة├── README.md└── .gitignoreالعناصر الأساسية للهيكل:
- apps/ — يحتوي على التطبيقات القابلة للتنفيذ (الخدمات، الأدوات). كل تطبيق هو وحدة Go منفصلة مع
go.modخاص به. - libs/ — المكتبات المشتركة التي يعاد استخدامها بين التطبيقات.
- go.work — ملف workspace، يسمح بالعمل مع جميع الوحدات محلياً دون نشر التغييرات.
العمل مع Go Modules في المستودع الواحد
بدءاً من Go 1.18، تم إضافة دعم workspaces (go.work). هذا يحل مشكلة التطوير المحلي عندما تعتمد الوحدات على بعضها البعض. دعنا نستعرض مثالاً على الإعداد.
لننشئ ملف go.work في جذر المستودع الواحد:
go 1.21
use ( ./apps/api-gateway ./apps/auth-service ./libs/common ./libs/models)الآن، عند التطوير المحلي، ستستخدم Go الإصدارات المحلية من الوحدات بدلاً من المنشورة. هذا أمر بالغ الأهمية للتكرار السريع.
مثال على التبعية في apps/auth-service/go.mod:
module github.com/company/auth-service
go 1.21
require ( github.com/company/libs/common v0.0.0 github.com/company/libs/model