→ المدونة
شروحات15 د قراءةThe Taskfolk team8 مشاهدةحُدِّث في

طريقة ربط GitHub بأداة إدارة مشاريعك

XLinkedIn

دفعت للتو إصلاحًا للمهمة WEB-42، وتريد أن يظهر ذلك الـ commit على التذكرة نفسها. لا في Slack. لا مدفونًا في فرع لا يتذكر أحد أن يفتحه. بل هناك مباشرةً على المهمة، حتى يستطيع من يقرؤها بعدك أن ينتقل إلى الكود فورًا دون أن يراسلك ليسأل أين هو. هذا هو السبب الوحيد لربط GitHub بأداة إدارة المشاريع، أن تحوّل «ثق بي، لقد أُصلح» إلى رابط يستطيع أحدهم أن ينقر عليه فعلًا.

يشرح هذا الدليل كيف تفعل ذلك بالضبط في Taskfolk. بنهايته سيكون لديك مستودع GitHub مربوط بمشروع، ورسائل commit تربط نفسها تلقائيًا بالمهام الصحيحة، وقائمة commits مرتبطة تقرؤها من صفحة المهمة أو تسحبها عبر REST API. وستعرف أيضًا بالضبط ما لا يرتبط، حتى لا تضيّع فترة ظهيرة كاملة في فتح تذكرة خطأ لسلوك لم يُبنَ أصلًا.

ما الذي يفعله ربط GitHub بأداة إدارة المشاريع فعلًا

اضبط النموذج الذهني الصحيح قبل أن تنقر أي شيء. هذا يجنّبك توقّع الشيء الخطأ لاحقًا.

حين تربط GitHub بأداة إدارة المشاريع في Taskfolk، فأنت تُعدّ ربط commit وارد فقط، لكل مشروع على حدة. هذه هي الميزة بكاملها، وضِيقها مقصود.

إليك سير العمل. تدفع إلى GitHub. يرسل GitHub إلى Taskfolk عبر webhook. لكل commit في تلك الدفعة، يقرأ Taskfolk رسالة الـ commit، ويجد أي مفاتيح مهام فيها، ويضيف مدخل commit مرتبط إلى المهمة المطابقة في المشروع الواحد الذي ربطته. انتهى.

sequenceDiagram
  participant Dev as You
  participant GH as GitHub
  participant UT as Taskfolk
  Dev->>GH: git push
  GH->>UT: POST webhook with push payload
  UT->>UT: verify HMAC signature
  UT->>UT: scan commit messages for issue keys
  UT->>UT: link commits to matching issues

لا يدفع Taskfolk الحالة عائدةً إلى GitHub. ولا يعلّق على الـ commits أو على pull requests. ولا يُنشئ فروعًا، ولا يستدعي GitHub API ليجلب أي شيء عن مستودعك.

لماذا يهمّك أنه يتدفق باتجاه واحد فقط؟ لأن ذلك يعني أنك تحصل على أثر في الاتجاهين (من المهمة إلى الكود، ومن الكود إلى المهمة) دون أن تمنح Taskfolk أي صلاحية كتابة على مصدرك. لا GitHub App عبر OAuth لتثبيته. لا منح صلاحيات واسع. لا حساب bot يستطيع الدفع إلى main. إنه مجرد webhook للمستودع تضبطه يدويًا، وTaskfolk لا يستقبل ويتحقق ويقرأ سوى نصوص. إن بدا ذلك غير مبهر، فهذا جيد. غير المبهر هو ما تريده يمسك خيطًا إلى قاعدة كودك.

احفظ حقيقة أخرى الآن، الربط لكل مشروع على حدة، ومستودع واحد يمكن أن يرتبط بعدة مشاريع. تدير مستودعًا أحاديًا (monorepo)؟ اربطه بمشروع WEB، ومشروع API، ومشروع MOBILE كلٌّ على حدة. كلٌّ منها يحصل على سجل تكامل خاص به ومفتاح webhook سري خاص به. لا يصل أي commit إلى مهمة إلا إذا كانت تلك المهمة تعيش في المشروع الذي استقبل تكامله الدفعة.

افتح تبويب Integrations في إعدادات المشروع

كل شيء يبدأ في مكان واحد. اذهب إلى المشروع الذي تريد ربطه (سنستخدم مشروع WEB التجريبي طوال الشرح)، افتح Settings، وانقر تبويب Integrations. المسار المباشر هو /w/[ws]/p/[proj]/settings?tab=integrations.

سترى بطاقة GitHub بعنوان "Auto-link commits to this project's issues". تحتها، سطر واحد يشرح الآلية، ادفع commits تحمل #KEY-NUM في الرسالة وستظهر على صفحة المهمة. تحت ذلك يقع حقل Repository بعنصر نائب owner/name وتلميح "Format: owner/name"، إضافةً إلى زر Register repository.

‏تبويب Integrations في إعدادات المشروع يعرض بطاقة GitHub بعنوان 'Auto-link commits to this project's issues'، وحقل Repository بعنصر نائب owner/name، وزر Register repository. هنا يبدأ ربط GitHub بأداة إدارة المشاريع.

أمران يستحقان التشديد قبل أن تكتب أي شيء. أولًا، هذا لكل مشروع على حدة بالتصميم. تسجيل المستودع على هذه البطاقة يربط الـ commits بمهام WEB فقط. لا يربط المستودع بمساحة العمل بأكملها، ويترك مشاريعك الأخرى دون مساس. تريد المستودع نفسه يغذّي مشروعًا آخر؟ سجّله هناك أيضًا، على حدة.

ثانيًا، تحتاج إلى الصلاحية project.edit_settings لتفعل هذا. عضو المشروع الذي لا يملك حقوق الإعدادات لن يرى زر التسجيل أصلًا. والتسجيل ليس صامتًا، فهو يكتب مدخل audit_log، فيبقى سجلٌّ لمن ربط ماذا ومتى. والإلغاء لاحقًا يفعل الشيء نفسه. ذلك الأثر يهمّ أكثر مما يبدو، لأن الـ webhook باب يقبل دفعات من الخارج، وتريد أن تعرف من فتحه.

سجّل المستودع والتقط المفتاح السري لمرة واحدة

اكتب مستودعك بصيغة owner/name. للنسخة التجريبية، شيء مثل your-org/web. انقر Register repository. يتحول الزر إلى "Registering..." للحظة، ثم تتغير الشاشة.

يولّد Taskfolk مفتاح webhook سريًا جديدًا ويعرضه لك في لوحة بعنوان "Save this secret in GitHub now". كل قيمة أنت على وشك لصقها في GitHub موجودة هنا:

Field in GitHub Value from Taskfolk
Payload URL https://taskfolk.ai/api/integrations/github/webhook
Content type application/json
Secret the generated secret (copy button next to it)
Events "Just the push event."

انسخ ذلك المفتاح السري الآن. أعني الآن، قبل أن تنتقل بعيدًا أو يسرق تنبيه Slack انتباهك.

إليك الجزء الذي يوقع الناس. يُعرض المفتاح السري مرة واحدة بالضبط. يخزّنه Taskfolk مشفّرًا في حالة السكون بخوارزمية AES-256-GCM ولا يستطيع أبدًا أن يقرأه لك ثانيةً. لا يوجد زر "reveal secret". لا يوجد زر "rotate". تقول اللوحة ذلك صراحةً: "This secret is shown once. If you lose it, revoke this repository and register it again". هذا ليس مجرد تنبيه، بل هو مسار الاسترداد الوحيد. أضعت المفتاح السري قبل أن يصل إلى GitHub، وإصلاحك هو أن تلغي المستودع وتسجّله من جديد، ما يسكّ مفتاحًا سريًا جديدًا تمامًا ويعني إعادة الجانب الخاص بـ GitHub.

فالانضباط بسيط. سجّل، انسخ المفتاح السري، أبقِ هذا التبويب مفتوحًا، واذهب لتُعدّ جانب GitHub في تبويب آخر قبل أن تلمس أي شيء هنا. لا تغلق اللوحة حتى ينتهي GitHub ويومض بالأخضر.

الصق الـ webhook في GitHub (لا يستطيع Taskfolk فعلها نيابةً عنك)

هذا النصف يدوي، ولا مفرّ منه. Taskfolk ليس له مسار تثبيت GitHub App، فلا يستطيع أن يمدّ يده إلى مستودعك ويُنشئ الـ webhook بنفسه. أنت تلصق القيم يدويًا. هذه هي المقايضة الأمنية نفسها بثوب مختلف، ثمن ألا يملك Taskfolk أبدًا صلاحية كتابة على مستودعك هو أن تتولى أنت السباكة.

في GitHub، افتح المستودع، اذهب إلى Settings، ثم Webhooks، ثم Add webhook. املأه:

  1. Payload URL: الصق قيمة https://taskfolk.ai/api/integrations/github/webhook من Taskfolk.
  2. Content type: اضبطه على application/json. لا الخيار الافتراضي المُرمَّز على هيئة نموذج. بل خيار JSON.
  3. Secret: الصق المفتاح السري الذي نسخته.
  4. Which events would you like to trigger this webhook?: اختر "Just the push event."

احفظه.

ما يحدث في جانب Taskfolk حين تصل رسالة هو سبب وجود ذلك المفتاح السري من الأساس. كل webhook يرسله GitHub يحمل ترويسة X-Hub-Signature-256، وهي HMAC-SHA256 للحمولة موقّعة بمفتاحك السري. يعيد Taskfolk حساب ذلك التوقيع باستخدام المفتاح السري المخزّن ويقارن الاثنين. إن لم يتطابقا، أو غابت الترويسة، فلا يفعل Taskfolk شيئًا. لا commit مرتبط، ولا أثر مرئي في التطبيق. فإن أخطأت في كتابة المفتاح السري، فالعرَض ليس فشلًا صاخبًا داخل Taskfolk، بل هو أن الـ commits لا تظهر بهدوء. ذلك أول ما تعيد فحصه حين يبدو الربط ميتًا، وسجل التسليم الخاص بـ GitHub (المزيد عنه أدناه) هو حيث يظهر عدم التطابق كردٍّ غير أخضر.

تأكيدان مفيدان. يطلق GitHub حدث ping لحظة إضافتك الـ webhook، ويردّ Taskfolk عليه بـ pong، فعلامة الصح الخضراء على ذلك التسليم الأول في واجهة GitHub تعني أن نقطة النهاية قابلة للوصول ومستجيبة. وأي حدث غير push أو release يعيد ببساطة HTTP 202 ويُتجاهل، فلا يمكنك أن تكسر أي شيء بترك أحداث إضافية محددة. إنها ببساطة لا تفعل شيئًا.

إن كانت webhooks عمومًا جديدة عليك، فإن شرح webhooks يغطي ما هي وكيف يحميك التحقق من التوقيع.

اكتب رسائل commit تربط (قواعد ‎#KEY-NUM)

السباكة انتهت. الآن المهارة اليومية، كتابة رسائل commit تربط فعلًا. أكثر القيمة تعيش هنا، والقواعد محددة، فتعلّمها مرة واحدة وتصير ذاكرة عضلية.

هناك صيغتان مقبولتان بالضبط.

الصيغة الأولى: #KEY-NUM في أي موضع من الرسالة. ضع علامة hash أمام مفتاح المهمة فيرتبط أينما وقع.

الصيغة الثانية: KEY-NUM عارٍ، لكن في بداية الرسالة تمامًا فقط. لا حاجة إلى hash، ما دام المفتاح أول شيء في الرسالة، متبوعًا بـ : أو - أو مسافة بيضاء أو نهاية السطر.

في commits حقيقية، تبدو الصيغتان هكذا:

git commit -m "Fix summary tab crash #WEB-42"
git commit -m "#WEB-42 fix the summary tab crash"
git commit -m "WEB-12: add Timeline + Summary tab"
git commit -m "WEB-42 wire up backlog ranking"

يجب أن تكون المفاتيح نفسها بأحرف كبيرة، من 2 إلى 6 محارف، مطابقةً للنمط [A-Z][A-Z0-9]{1,5}. الحالة غير متسامحة، والموضع يهمّ في الصيغة العارية. إليك ما يعنيه ذلك عمليًا:

Commit message Links? Why
WEB-12 wire up backlog ranking Yes Bare key, at the start
web-12 wire up backlog ranking No Lowercase, ignored
refactored web-12 handler No Mid-message bare key, and lowercase on top
refactored #WEB-12 handler Yes The hash rescues a mid-message reference

ذلك الزوج الأخير يوقع الناس باستمرار. المفاتيح العارية لا تعمل إلا في البداية. لحظة أن يقع مرجعك في وسط جملة، تحتاج إلى #. القرار كله يتّسع في صورة واحدة:

flowchart TD
  A[Issue key in a commit message] --> B{Starts with a hash?}
  B -- yes --> C[Links anywhere in the message]
  B -- no --> D{Very first thing in the message?}
  D -- yes --> E[Links]
  D -- no --> F[Ignored]

عند الشك، اكتب دائمًا #WEB-12. تعمل في كل مكان، ولا سلبية لها.

كما يجب أن يتحلّل المرجع إلى مهمة حقيقية موجودة في المشروع المربوط. الـ #WEB-9999 الذي لا وجود له يُتجاوز بهدوء، بلا خطأ. وcommit واحد يمكن أن يشير إلى عدة مهام دفعةً واحدة: Fix shared date parser #WEB-12 #WEB-42 يصل إلى التذكرتين كلتيهما. مفيد حقًا حين يغلق تغيير واحد أمرين.

إن كانت مفاتيح المهام وكيفية تكوينها لا تزال غامضة، فإن كيفية إنشاء مهمة يغطي بنية KEY-NUM من الأساس.

اطّلع على الـ commits المرتبطة على المهمة

إليك الثمرة. ادفع commit يشير إلى WEB-12، ثم افتح تلك المهمة.

على صفحة تفاصيل المهمة يوجد قسم Linked commits. يعرض كل صف:

  • الـ SHA القصير من 7 محارف كزر. انقره فتنتقل بعمق مباشرةً إلى ذلك الـ commit على GitHub، وهو السبب الكامل الذي فعلت من أجله كل هذا.
  • رسالة الـ commit (السطر الأول، مقتطعة عند 1000 محرف إن كنت تكتب مقالات في commits).
  • اسم المؤلف من حمولة الدفع، أو "unknown" إن لم تحمل الحمولة اسمًا.
  • تاريخ الـ commit.
  • اسم المستودع (الـ owner/name كاملًا).

الحدث نفسه يصل أيضًا إلى الجدول الزمني لـ النشاط في المهمة كمدخل "linked a commit"، يحمل الرابط العميق نفسه لـ SHA من 7 محارف واسم المستودع. فتحصل عليه في مكانين، قسم Linked commits للحالة الراهنة، وتغذية النشاط للحكاية الزمنية للمهمة.

تفصيلان صادقان. المؤلف هو اسم مؤلف الـ commit وبريده الإلكتروني كما هما من حمولة دفع GitHub. وهو ليس مربوطًا بعضو في مساحة العمل، فلا تتوقع صورة Taskfolk رمزية أو ملفًا شخصيًا قابلًا للنقر هناك، حتى حين يكون صاحب الـ commit في مساحة عملك. إنه نص للعرض، لا أكثر. والقسم يتوقف عند 50 صفًا على صفحة المهمة. إن تراكم على مهمة ما أكثر من خمسين commit مرتبطًا لسبب ما، فأنت تنظر إلى أول خمسين، وعند تلك النقطة يكون REST API (أدناه) الأداة الأفضل.

أمر واحد لا داعي لأن تقلق بشأنه، التكرار. الربط عديم الأثر التراكمي (idempotent). فهرس فريد على تركيبة المهمة والمستودع وSHA يعني أنه إذا أعاد GitHub تسليم webhook (وهو يفعل أحيانًا، حين يظن أن تسليمًا فشل)، فلن تحصل على الـ commit نفسه مرتين. ادفع الـ commit نفسه مرتين وستظل ترى صفًا واحدًا.

أدِر مستودعًا مربوطًا أو افصله

تحت نموذج التسجيل تقع قائمة المستودعات المربوطة بهذا المشروع بالفعل. كل صف بسيط: المستودع بخط أحادي المسافة، و"Registered {date}"، وزر Revoke. حين لا يكون شيء مربوطًا بعد، تقرأ القائمة "No repositories registered yet".

الإلغاء هو كيف تفصل. انقر Revoke فتحصل على تأكيد: "Stop accepting webhooks from {repo}?". أكّده فيحذف Taskfolk التكامل. الدفعات من ذلك المستودع تتوقف عن ربط الـ commits من تلك اللحظة.

الـ commits المربوطة سلفًا تبقى في مكانها على مهامها. الإلغاء لا يمسح التاريخ، بل يوقف فقط تكوّن روابط جديدة. مثل التسجيل، يكتب الإلغاء مدخل audit_log ويحتاج إلى project.edit_settings. تستطيع تسجيل المستودع من جديد لاحقًا، وتحصل على مفتاح سري جديد حين تفعل، فستعيد إدخال المفتاح السري في جانب GitHub (يمكنك إعادة استخدام webhook الخاص بـ GitHub نفسه وتحديث حقل المفتاح السري فيه فقط).

الآن الحدّ الصادق. لا يوجد مؤشر لآخر تسليم أو لنشاط الـ webhook في هذه الواجهة. القائمة تعرض اسم المستودع وتاريخ التسجيل، وهذا كل شيء. عُدّ عمود last_webhook_at وأُجّل، فلا تستطيع أن تلقي نظرة هنا لترى "آخر دفعة استُقبلت قبل 3 دقائق". لتؤكد أن التسليمات تصل فعلًا وتتحقق، افحص سجل تسليم webhook الخاص بـ GitHub (Settings، ثم Webhooks، ثم الـ webhook لديك، ثم Recent Deliveries)، حيث يعرض كل تسليم رمز ردّه. الأخضر هناك، مع commit مرتبط على المهمة، هو برهانك على أن الحلقة أُغلقت.

اسحب الـ commits المرتبطة عبر REST API

صفحة المهمة للبشر. حين تريد الـ commits المرتبطة لأجل سكربت (مولّد ملاحظات إصدار، لوحة حالة خارجية، لوحة تحكم)، اسحبها عبر REST API العام بدلًا من ذلك.

نقطة النهاية هي:

GET /v1/workspaces/{slug}/projects/{key}/issues/{KEY-N}/commits

تحتاج إلى النطاق issues:read على مفتاح API لديك، الذي تسكّه في وحدة تحكم المطوّر. تعود النتائج مرتبةً حسب تاريخ الـ commit، الأحدث أولًا، بترقيم صفحات keyset للمهام التي تحمل تاريخ commit طويلًا.

‏تبويب Overview في وحدة تحكم المطوّر مع بطل 'Build on Taskfolk'، وزر 'Create an API key'، وبطاقات بداية سريعة لـ REST API وNode SDK وMCP server وSkills. هنا يأتي المفتاح لقراءة الـ commits المرتبطة.

نداء أدنى على WEB-12 في مساحة عمل taskfolk يبدو هكذا. عنوان الأساس هو https://taskfolk.ai/api:

curl "https://taskfolk.ai/api/v1/workspaces/taskfolk/projects/WEB/issues/WEB-12/commits" \
  -H "Authorization: Bearer tfk_live_your_api_key"
const res = await fetch(
  "https://taskfolk.ai/api/v1/workspaces/taskfolk/projects/WEB/issues/WEB-12/commits",
  { headers: { Authorization: "Bearer tfk_live_your_api_key" } },
);
const { data } = await res.json();
for (const c of data) {
  console.log(`${c.sha.slice(0, 7)} ${c.message} (${c.repo})`);
}
import requests

res = requests.get(
    "https://taskfolk.ai/api/v1/workspaces/taskfolk/projects/WEB/issues/WEB-12/commits",
    headers={"Authorization": "Bearer tfk_live_your_api_key"},
)
for c in res.json()["data"]:
    print(c["sha"][:7], c["message"], c["repo"])

الرد هو المغلّف القياسي، data إضافةً إلى pagination:

{
  "data": [
    {
      "id": "01890a5c-...",
      "repo": "your-org/web",
      "sha": "abc1234def5678...",
      "message": "Fix summary tab crash #WEB-42",
      "url": "https://github.com/your-org/web/commit/abc1234...",
      "author": "Sara",
      "committed_at": "2026-07-14T09:12:00.000Z"
    }
  ],
  "pagination": { "next_cursor": null }
}

تستعيد البيانات نفسها التي يعرضها قسم Linked commits: SHA، والرسالة، والمؤلف، وتاريخ الـ commit، والمستودع، ورابط الـ commit. ذلك الحقل الأخير يعني أن سكربتك يستطيع أن يبني أسطرًا مثل "WEB-12 was fixed in abc1234, here is the diff" لسجل تغييرات دون أن يفتح أحد التطبيق، أو أن يغذّي صفحة حالة عامة تربط الـ commits بالتذاكر المغلقة. ولأنها البيانات الكامنة ذاتها بالضبط، فهي لا تنحرف أبدًا عمّا يراه زميل على المهمة. حين يعود next_cursor غير فارغ، مرّره كمؤشر (cursor) في طلبك التالي لتمشي بقية التاريخ.

للصورة الكاملة عن المصادقة والنطاقات والترقيم، فإن كيفية استخدام REST API هو المرجع.

ما لا يرتبط (اقرأ هذا قبل أن تفتح تذكرة خطأ)

هذا هو القسم الذي ينقذ فترة ظهيرتك. كل بند أدناه حدٌّ حقيقي للميزة، مذكور صراحةً، حتى تكفّ عن توقّع سلوك لم يُبنَ أصلًا.

مراجع pull request لا تُحلَّل. لا يوجد معالج pull_request في مستقبِل الـ webhook، نهاية الأمر. الإشارة إلى #WEB-42 في عنوان pull request أو في وصفه لا تفعل شيئًا بذاتها. الربط يأتي فقط من نص رسالة الـ commit. الآن، ذلك النص غالبًا يصل عبر pull request (ادمج فرعًا أو ادفع إليه، وتلك الـ commits تحمل رسائلها)، فعمليًا ترتبط الـ commits المدفوعة عبر pull request جيدًا. لكنه دائمًا رسالة الـ commit التي تُقرأ، لا كائن pull request أبدًا. إن كان #WEB-42 يعيش فقط في متن pull request ولا في أي رسالة commit، فلن يرتبط. ضع المفتاح في الـ commit.

الفروع لا تُتتبَّع. يقرأ Taskfolk مرجع الدفعة (ref) بقدر ما يكفي فقط لملاحظة دفع tag (لأجل ميزة الإصدار المنفصلة). لا يسجّل أو يعرض من أي فرع أتى commit، ولا يُنشئ روابط فروع على المهمة. صفحة المهمة تعرض commits. لا فروعًا، ولا pull requests.

رسالة الـ commit وحدها تُفحَص. لا وصف pull request، ولا تعليقات pull request، ولا حقل آخر ما. فقط سلسلة commit.message. مفتاح في أي مكان آخر غير مرئي للرابط.

المفاتيح العارية تعمل في البداية فقط. يستحق التكرار، لأنه أكثر مفاجأة شائعة: WEB-42 بلا hash يرتبط فقط حين يكون أول شيء في الرسالة تمامًا. في وسط الرسالة، تحتاج إلى #WEB-42. ويجب أن تكون المفاتيح بأحرف كبيرة، من 2 إلى 6 محارف. الـ web-42 يُتجاهل، وكذلك أي شيء أقصر من محرفين أو أطول من 6 محارف بعد الحرف.

الربط لا يطلق أي إشعار. هذا يشكّل التوقعات. حين يرتبط commit بمهمة، فإنه يُنشئ صف commit_refs ومدخل نشاط commit_linked، وهذا كل شيء. المُسند إليه لا يُرسَل إليه بريد. المُبلِّغ لا يُنبَّه. لا توجد إشارة @. فلا تدفع commit متوقّعًا أن يهزّ من يملك التذكرة، لأنه لن يفعل. إن احتاج أحدهم أن يعرف، فأخبره، أو علّق على المهمة وأشِر إليه هناك بإشارة @. دليل الإشعارات يغطي ما يطلق إشعارًا فعلًا.

الإطلاق التلقائي للإصدار ميزة مختلفة. إن اخترت أيضًا حدث release، فإن دفع tag أو إصدار GitHub منشور يمكن أن يطلق تلقائيًا إصدارًا مخططًا مطابقًا في Taskfolk (يقلبه إلى مُصدَر ويختم التاريخ، حين يطابق الـ tag الإصدار). ذلك يعيش في ميزة الإصدارات. إنه ليس ربط commit، والاثنان ينبغي أن يبقيا منفصلين في ذهنك. إضافة حدث release لا تغيّر شيئًا في كيفية ربط رسائل الـ commit بالمهام.

فحص المفاتيح السرية (secret scanning) شيء منفصل تمامًا. يشغّل Taskfolk مستقبِلًا شريكًا متمايزًا لفحص المفاتيح السرية من GitHub عند نقطة نهاية مختلفة. يعالج مفاتيح Taskfolk API المسرّبة (من نوع tfk_live_): إن اكتشف GitHub أحد مفاتيح Taskfolk لديك مكشوفًا في مستودع عام، فإنه ينبّه ذلك المستقبِل، الذي يلغي تلقائيًا المفتاح المسرّب ويرسل بريدًا إلى مالك مساحة العمل. لا تشغّله لكل مستودع من تبويب Integrations، وهو لا يفحص كودك بحثًا عن مفاتيح سرية. لا تخلط بينه وبين ربط مستودع لأجل روابط الـ commit. يتشاركان كلمة "GitHub" ولا شيء غيرها.

هذا هو الحدّ الصادق للميزة. وارد فقط، مدفوع برسالة الـ commit، لكل مشروع، بلا إشعارات، بلا وعي بـ pull request أو الفروع. ضيّق عن قصد، وموثوق بسبب ذلك.

اذهب وافتح تبويب Integrations في مشروع WEB، سجّل مستودعك، وضع #WEB-42 في الـ commit التالي. سيكون الرابط بانتظارك على المهمة حين تصل.

أسئلة شائعة

كيف أربط GitHub بأداة إدارة المشاريع في Taskfolk؟

افتح المشروع، ثم Settings، ثم تبويب Integrations، واكتب مستودعك بصيغة owner/name في بطاقة GitHub، وانقر Register repository. ينشئ Taskfolk مفتاح webhook سريًا يُعرض مرة واحدة فقط، فانسخه واذهب إلى GitHub: Settings، ثم Webhooks، ثم Add webhook، والصق عنوان الحمولة https://taskfolk.ai/api/integrations/github/webhook مع Content type بقيمة application/json والمفتاح السري وحدث push. تحتاج إلى الصلاحية project.edit_settings، والربط لكل مشروع على حدة.

لماذا لا تظهر الـ commits الخاصة بي على المهمة؟

السبب الأشيع هو مفتاح سري لا يتطابق. يتحقق Taskfolk من ترويسة X-Hub-Signature-256 بمقارنة HMAC-SHA256 بالمفتاح السري المخزّن، وإن لم يتطابقا فلا يفعل شيئًا بصمت، بلا فشل مرئي في التطبيق. افحص سجل تسليم webhook في GitHub بحثًا عن ردٍّ غير أخضر. تحقق أيضًا أن رسالة الـ commit تحمل مفتاحًا صالحًا (بأحرف كبيرة، من 2 إلى 6 محارف)، وأن المفتاح العاري في بداية الرسالة، وأن المهمة موجودة فعلًا في المشروع المربوط.

هل ترتبط عناوين pull request أو أوصافها بالمهام؟

لا. لا يوجد معالج pull_request في مستقبِل الـ webhook. الربط يأتي فقط من نص رسالة الـ commit، لا من عنوان pull request أو وصفه. عمليًا، الـ commits التي تصل عبر pull request ترتبط جيدًا لأنها تحمل رسائلها، لكن المفتاح يجب أن يكون في رسالة الـ commit نفسها. إن عاش ‎#WEB-42 في متن pull request فقط، فلن يرتبط.

ما الفرق بين ‎#WEB-42 والمفتاح العاري WEB-42 في الـ commit؟

الصيغة ‎#WEB-42 ترتبط في أي موضع من الرسالة. أما المفتاح العاري WEB-42 فيرتبط فقط حين يكون أول شيء في الرسالة تمامًا، متبوعًا بـ : أو - أو مسافة بيضاء أو نهاية السطر. في وسط الرسالة، المفتاح العاري يُتجاهل وتحتاج إلى ‎#. المفاتيح دائمًا بأحرف كبيرة، من 2 إلى 6 محارف. عند الشك، اكتب ‎#WEB-42 لأنه يعمل في كل مكان.

أضعت المفتاح السري لـ webhook. كيف أستعيده؟

لا تستطيع استعادته. يُعرض المفتاح السري مرة واحدة بالضبط، ويخزّنه Taskfolk مشفّرًا في حالة السكون بخوارزمية AES-256-GCM ولا يستطيع أبدًا قراءته لك ثانيةً. لا يوجد زر reveal ولا rotate. مسار الاسترداد الوحيد هو أن تلغي المستودع وتسجّله من جديد، ما يسكّ مفتاحًا سريًا جديدًا تمامًا تُدخله في جانب GitHub.

هل يرسل ربط الـ commit إشعارًا إلى المُسند إليه؟

لا. حين يرتبط commit بمهمة، يُنشئ Taskfolk صف commit_refs ومدخل نشاط commit_linked، وهذا كل شيء. المُسند إليه لا يُرسَل إليه بريد، والمُبلِّغ لا يُنبَّه، ولا توجد إشارة @. إن احتاج أحدهم أن يعرف، فأخبره أو علّق على المهمة وأشِر إليه هناك بإشارة @.

هل يمكنني ربط مستودع واحد بأكثر من مشروع؟

نعم. الربط لكل مشروع على حدة، ومستودع واحد يمكن أن يرتبط بعدة مشاريع. للمستودع الأحادي (monorepo)، سجّله في مشروع WEB ومشروع API ومشروع MOBILE كلٌّ على حدة. كلٌّ منها يحصل على سجل تكامل خاص به ومفتاح webhook سري خاص به، ولا يصل commit إلى مهمة إلا إذا كانت تلك المهمة تعيش في المشروع الذي استقبل تكامله الدفعة.

كيف أقرأ الـ commits المرتبطة برمجيًا؟

استخدم REST API العام: GET /v1/workspaces/{slug}/projects/{key}/issues/{KEY-N}/commits. يحتاج إلى النطاق issues:read على مفتاح API الذي تسكّه في وحدة تحكم المطوّر. تعود النتائج مرتبةً حسب تاريخ الـ commit، الأحدث أولًا، بترقيم صفحات keyset. الرد هو المغلّف القياسي data إضافةً إلى pagination، ويعطيك البيانات نفسها التي يعرضها قسم Linked commits: SHA والرسالة والمؤلف والتاريخ والمستودع ورابط الـ commit. حين يعود next_cursor غير فارغ، مرّره كمؤشر في طلبك التالي.

قراءات ذات صلة

أضف تعليقًا

ابدأ النقاش.