feat(forge): pluggable forge abstraction + GitLab and Gitea/Forgejo/Codeberg (#1913)
* refactor(forge): forge-neutral foundation (GitHub-only) Decouple git-hosting from GitHub behind a neutral abstraction (issue #1616), GitHub-only for now; existing GitHub behaviour is unchanged. - Forge manifest, neutral ForgeService contract, forge registry + resolver, and a client forge-module registry. - GitHub code renamed to the neutral shape; PR/Issue attachment wording preserved. - forge.search.response enums parse tolerantly (unknown kind/auth state degrade instead of breaking the client). - createPullRequest reports typed CLI/auth errors instead of a generic message. - forge-resolver host/remote caches are LRU-bounded. - Forge host trust is explicit: only a known cloud host or a CLI-authenticated host is ever talked to; an unauthenticated GitHub Enterprise host fails resolution instead of routing to github.com. - Docs: forge-providers guide, glossary and i18n forge-copy conventions, architecture and rpc-namespacing terminology. - Vitest React Native mocks (unistyles, svg, linking, lucide) consolidated into shared aliased test-stubs. * feat(forge): GitLab adapter, forge-aware UI, pipelines and approvals GitLab adapter over the glab CLI on the neutral contracts: MR status, forge-aware UI, pipeline tree, and N-of-M approvals. - threadIsResolved is part of the neutral timeline item. - Pipeline load failures show an error instead of an empty section. - Manual pipeline jobs render as pending. - Fork/detached MR head pipelines are fetched by MR iid (glab ci get --merge-request). * feat(forge): Gitea family adapter (Gitea, Forgejo, Codeberg) One adapter over the tea CLI serving Gitea, Forgejo, and Codeberg on the neutral contracts. - CI status aggregates commit statuses and Actions runs together. - Gitea's terminal "warning" state maps to failure on server and client. - Gitea Actions check details are reachable from the PR pane by workflowRunId. * refactor(forge): localize compatibility handling * test(forge): expect normalized GitLab facts --------- Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
This commit is contained in:
co-authored by
Mohamed Boudra
parent
04d1ebdce0
commit
a8ebd390fa
@@ -102,6 +102,7 @@ export const ar: TranslationResources = {
|
||||
addImage: "أضف صورة",
|
||||
addFile: "Upload file",
|
||||
addIssueOrPr: "أضف مشكلة أو PR",
|
||||
addIssueOrPr_mr: "أضف مشكلة أو MR",
|
||||
dropImagesHere: "إسقاط الصور هنا",
|
||||
dropFilesHere: "Drop files here",
|
||||
editQueuedMessage: "تحرير الرسالة في قائمة الانتظار",
|
||||
@@ -109,8 +110,8 @@ export const ar: TranslationResources = {
|
||||
openImage: "فتح مرفق الصورة",
|
||||
removeImage: "إزالة مرفق الصورة",
|
||||
removeFile: "Remove file attachment",
|
||||
openGithub: "افتح{{kind}}#{{number}}",
|
||||
removeGithub: "إزالة{{kind}}#{{number}}",
|
||||
openGithub: "افتح {{kind}} {{number}}",
|
||||
removeGithub: "إزالة {{kind}} {{number}}",
|
||||
element: "عنصر",
|
||||
openBrowserElement: "افتح مرفق عنصر المتصفح",
|
||||
removeBrowserElement: "إزالة مرفق عنصر المتصفح",
|
||||
@@ -134,7 +135,9 @@ export const ar: TranslationResources = {
|
||||
searching: "جارٍ البحث...",
|
||||
noResults: "لم يتم العثور على نتائج.",
|
||||
searchPlaceholder: "بحث القضايا والعلاقات العامة...",
|
||||
searchPlaceholder_mr: "بحث القضايا و MR...",
|
||||
title: "إرفاق المشكلة أو PR",
|
||||
title_mr: "إرفاق المشكلة أو MR",
|
||||
},
|
||||
},
|
||||
agentControls: {
|
||||
@@ -618,6 +621,9 @@ export const ar: TranslationResources = {
|
||||
label: "إنشاء PR",
|
||||
pending: "إنشاء PR...",
|
||||
success: "تم إنشاء PR",
|
||||
label_mr: "إنشاء MR",
|
||||
pending_mr: "إنشاء MR...",
|
||||
success_mr: "تم إنشاء MR",
|
||||
},
|
||||
mergeBranch: {
|
||||
label: "دمج محليا",
|
||||
@@ -640,7 +646,13 @@ export const ar: TranslationResources = {
|
||||
rebase: "دمج PR (rebase)",
|
||||
pending: "دمج PR...",
|
||||
success: "تم دمج PR",
|
||||
squash_mr: "دمج MR (squash)",
|
||||
merge_mr: "دمج MR (merge)",
|
||||
rebase_mr: "دمج MR (rebase)",
|
||||
pending_mr: "دمج MR...",
|
||||
success_mr: "تم دمج MR",
|
||||
},
|
||||
viewPr_mr: "عرض MR",
|
||||
autoMerge: {
|
||||
enableSquash: "دمج تلقائي (squash)",
|
||||
enableMerge: "دمج تلقائي (merge)",
|
||||
@@ -651,7 +663,7 @@ export const ar: TranslationResources = {
|
||||
disabled: "تم تعطيل الدمج التلقائي",
|
||||
},
|
||||
unavailable: {
|
||||
viewPrNoGithub: "عرض PR غير متاح الآن لأن GitHub غير متصل",
|
||||
viewPrNoForge: "عرض {{noun}} غير متاح الآن لأن {{brand}} غير متصل",
|
||||
pullNoRemote: "السحب غير متاح هنا لأن هذا الفرع غير متصل بجهاز التحكم عن بعد بعد",
|
||||
pullDirty: "السحب غير متاح أثناء وجود تغييرات محلية، لذا قم بتنفيذها أو تخزينها أولاً",
|
||||
pullUpToDate: "السحب غير متاح لأن هذا الفرع محدث بالفعل",
|
||||
@@ -662,8 +674,10 @@ export const ar: TranslationResources = {
|
||||
"السحب والدفع غير متاح هنا لأن هذا الفرع غير متصل بجهاز التحكم عن بعد بعد",
|
||||
pullAndPushDirty:
|
||||
"لا يتوفر السحب والدفع أثناء وجود تغييرات محلية، لذا قم بتنفيذها أو تخزينها أولاً",
|
||||
pullAndPushNoIncoming: "السحب والدفع غير متاحين لأنه لا توجد تغييرات واردة للسحب أولاً",
|
||||
pullAndPushInSync: "السحب والدفع غير متاح لأن هذا الفرع متزامن بالفعل",
|
||||
createPrNoGithub: "إنشاء PR غير متاح حاليًا لأن GitHub غير متصل",
|
||||
pullAndPushNothingToPush: "السحب والدفع غير متاحين لأنه لا يوجد شيء جديد لإرساله بعد السحب",
|
||||
createPrNoForge: "إنشاء {{noun}} غير متاح حاليًا لأن {{brand}} غير متصل",
|
||||
createPrNoCommits: "إنشاء PR غير متاح لأن هذا الفرع ليس لديه أي التزامات جديدة حتى الآن",
|
||||
mergeNoBase: "الدمج غير متاح لأننا لم نتمكن من تحديد الفرع الأساسي",
|
||||
mergeDirty:
|
||||
@@ -673,13 +687,16 @@ export const ar: TranslationResources = {
|
||||
updateDirty: "التحديث غير متاح أثناء وجود تغييرات محلية، لذا قم بتنفيذها أو تخزينها أولاً",
|
||||
updateCurrent: "التحديث غير متاح لأن هذا الفرع محدث بالفعل باستخدام{{baseRef}}",
|
||||
mergePrNoGithub: "دمج PR غير متاح الآن لأن GitHub غير متصل",
|
||||
archiveNotWorktree:
|
||||
"الأرشيف غير متاح هنا لأنه لم يتم إنشاء مساحة العمل هذه كشجرة عمل Paseo",
|
||||
mergePrNoForge: "دمج {{noun}} غير متاح الآن لأن {{brand}} غير متصل",
|
||||
mergePrMissing: "دمج PR غير متاح لأنه لا يوجد طلب سحب حتى الآن",
|
||||
mergePrDraft: "دمج PR غير متاح لأن طلب السحب لا يزال مسودة",
|
||||
mergePrMerged: "دمج PR غير متاح لأن طلب السحب مدمج بالفعل",
|
||||
mergePrClosed: "دمج PR غير متاح لأن طلب السحب مغلق",
|
||||
mergePrConflicts: "دمج PR غير متاح لأن طلب السحب به تعارضات",
|
||||
mergePrQueue: "دمج PR غير متاح هنا لأن هذا المستودع يستخدم قائمة انتظار دمج",
|
||||
mergePrNotReady: "دمج PR غير متاح حتى يبلغ GitHub أن طلب السحب جاهز للدمج",
|
||||
mergePrNotReady: "دمج {{noun}} غير متاح حتى يبلغ {{brand}} أن {{noun}} جاهز للدمج",
|
||||
autoMergeCannotDisable: "تم تمكين الدمج التلقائي، ولكن لا يمكن لهذا الحساب تعطيله",
|
||||
},
|
||||
toasts: {
|
||||
@@ -729,7 +746,7 @@ export const ar: TranslationResources = {
|
||||
expandAllFolders: "توسيع كافة المجلدات",
|
||||
refreshing: "منعش",
|
||||
refresh: "ينعش",
|
||||
refreshState: "تحديث بوابة وحالة GitHub",
|
||||
refreshState: "تحديث حالة git و{{brand}}",
|
||||
failedRefresh: "فشل تحديث حالة git.",
|
||||
emptyHiddenWhitespace: "لا توجد تغييرات مرئية بعد إخفاء المسافة البيضاء",
|
||||
emptyUncommitted: "لا توجد تغييرات غير ملتزم بها",
|
||||
@@ -765,13 +782,23 @@ export const ar: TranslationResources = {
|
||||
pr: {
|
||||
actions: {
|
||||
viewPullRequest: "عرض",
|
||||
openOn: "فتح على {{brand}}",
|
||||
},
|
||||
sections: {
|
||||
checks: "الشيكات",
|
||||
pipeline: "خط المعالجة",
|
||||
reviews: "التعليقات",
|
||||
},
|
||||
empty: {
|
||||
noJobs: "لا توجد مهام",
|
||||
loadingPipeline: "جارٍ تحميل خط المعالجة...",
|
||||
pipelineJobsLoadFailed: "تعذر تحميل مهام خط المعالجة",
|
||||
allowedToFail: "مسموح بالفشل",
|
||||
},
|
||||
approvals: "{{given}} من {{required}} موافقات",
|
||||
accessibility: {
|
||||
pullRequest: "سحب الطلب #{{number}}",
|
||||
pullRequest_mr: "طلب دمج !{{number}}",
|
||||
},
|
||||
states: {
|
||||
draft: "مسودة",
|
||||
@@ -788,11 +815,19 @@ export const ar: TranslationResources = {
|
||||
time: {
|
||||
justNow: "الآن",
|
||||
},
|
||||
thread: {
|
||||
discussion: "سلسلة المناقشة",
|
||||
},
|
||||
errors: {
|
||||
statusLoadFailed: "غير قادر على تحميل حالة طلب السحب",
|
||||
activityLoadFailed: "غير قادر على تحميل نشاط طلب السحب",
|
||||
},
|
||||
},
|
||||
forgeSetup: {
|
||||
installCli: "ثبّت واجهة سطر الأوامر {{cli}} لاستخدام ميزات {{brand}}.",
|
||||
signIn: "نفّذ {{command}} لاستخدام ميزات {{brand}}.",
|
||||
generic: "قم بإعداد {{brand}} على هذا المضيف لاستخدام ميزاته.",
|
||||
},
|
||||
},
|
||||
},
|
||||
sidebar: {
|
||||
@@ -924,10 +959,10 @@ export const ar: TranslationResources = {
|
||||
refPicker: {
|
||||
startingRef: "بدء المرجع",
|
||||
chooseStart: "اختر من أين تبدأ",
|
||||
checkoutHint: "تحقق من PR#{{number}}؟",
|
||||
checkoutPr: "تحقق من PR#{{number}}",
|
||||
dismissCheckoutHint: "تجاهل تلميح الخروج PR#{{number}}",
|
||||
intoBase: "إلى{{baseRef}}",
|
||||
checkoutHint: "تحقق من {{noun}} {{numberPrefix}}{{number}}؟",
|
||||
checkoutPr: "تحقق من {{noun}} {{numberPrefix}}{{number}}",
|
||||
dismissCheckoutHint: "تجاهل تلميح الخروج {{noun}} {{numberPrefix}}{{number}}",
|
||||
intoBase: "إلى {{baseRef}}",
|
||||
searching: "جارٍ البحث...",
|
||||
noMatchingRefs: "لا توجد مراجع مطابقة.",
|
||||
searchPlaceholder: "بحث الفروع والعلاقات العامة",
|
||||
|
||||
Reference in New Issue
Block a user