أتمتة Broken Links: افتح Issue قبل ما الزائر يضيع
مستوى القارئ: متوسط
هتكسب من المقال ده أوتوميشن أسبوعي يكشف الروابط المكسورة، ويحوّل التقرير إلى GitHub Issue قابل للتنفيذ بدل ما تكتشف المشكلة من عميل غاضب.
المشكلة باختصار
اللينكات بتتكسر بصمت. صفحة وثائق اتنقلت. مقال قديم اتغير مساره. رابط خارجي رجّع 404. الطريقة الشائعة إنك تراجع الصفحات يدويًا كل فترة، ودي بتفشل لأن المراجعة بتتأجل أول ما الضغط يزيد.
السيناريو الواقعي هنا: عندك موقع توثيق أو مدونة تقنية فيها 250 صفحة، وكل أسبوع بتنشر 3 مقالات أو تعدل docs. لو بتراجع الروابط شهريًا، الرابط المكسور ممكن يفضل ظاهرًا 30 يوم. أوتوميشن أسبوعي يقلل نافذة الاكتشاف إلى 7 أيام تقريبًا. الرقم تقديري، لكنه كافي لتوضيح الفرق في التشغيل.
الفكرة بمثال بسيط
ركز في المثال ده. بدل ما شخص يفتح الموقع ويدخل على كل صفحة، GitHub Actions يشغل فحص تلقائي كل يوم اثنين. أداة Lychee تقرأ ملفات Markdown وHTML وتختبر الروابط. لو لقت خطأ، Workflow يفتح Issue بعنوان واضح، ويحط التقرير في جسم الـ Issue.
بالظبط زي smoke test، لكنه للروابط. مش بيصلح الرابط بدل منك. هو بيخلي المشكلة مرئية ومربوطة بمكان واحد في GitHub، وده أهم من تقرير بيتدفن في لوجات CI.
الـ workflow القابل للنسخ
اعمل ملف باسم .github/workflows/check-links.yml. الافتراض إن الموقع أو التوثيق موجودين داخل المستودع، وإنك عايز تفحص ملفات md وhtml مرة أسبوعيًا، مع تشغيل يدوي عند الحاجة.
name: Check broken links
on:
workflow_dispatch:
schedule:
- cron: "0 7 * * 1"
permissions:
contents: read
issues: write
jobs:
links:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Run lychee
id: lychee
uses: lycheeverse/lychee-action@v2
with:
args: --verbose --no-progress './**/*.md' './**/*.html'
format: markdown
output: ./lychee/out.md
fail: false
- name: Create issue from report
if: steps.lychee.outputs.exit_code != 0
uses: peter-evans/create-issue-from-file@v5
with:
title: "Broken links report"
content-filepath: ./lychee/out.md
labels: report, automated issue
الجزء المهم هنا هو fail: false. لو خليتها true هتفشل الـ workflow، وده مفيد في مشاريع strict. لكن لو هدفك تقرير أسبوعي بدون تعطيل الفريق، خليه يفتح Issue فقط. الـ trade-off هنا واضح: بتكسب استمرارية أقل إزعاجًا، لكن ممكن الفريق يتأخر في معالجة الـ Issue لو مفيش owner واضح.
ظبط الضوضاء قبل ما تثق في التقرير
أول تشغيل غالبًا هيطلع noise. روابط خارجية بترجع 429. مواقع بطيئة. صفحات بتحتاج user-agent معين. أفضل طريقة إنك تبدأ بفحص داخلي فقط، ثم تزود الروابط الخارجية بالتدريج.
لو عندك 500 رابط، متتوقعش أول تقرير يبقى نظيف. ابدأ بهدف عملي: أقل من 5 روابط مكسورة مفتوحة في نهاية الشهر. في تجربة فريق محتوى صغير، انخفاض التقرير من 18 رابط إلى رابط واحد خلال 4 أسابيع معقول جدًا لو كل Issue ليه owner ومراجعة أسبوعية.
لو عندك روابط معروفة إنها false positive، استخدم ملف .lycheeignore في جذر المستودع. حط فيه regex واحد لكل سطر. لكن متستخدموش كصندوق قمامة. كل استثناء لازم يبقى مفهوم، وإلا هترجع لنفس مشكلة المراجعة اليدوية.
# .lycheeignore
https://example.com/private-preview/.*
https://vendor.example.com/rate-limited/.*
التكلفة والـ trade-offs
- زمن التشغيل: فحص مئات الروابط ممكن يأخذ دقيقة أو أكثر حسب الشبكة. ده مقبول أسبوعيًا، لكنه مزعج لو اشتغل على كل push.
- صلاحيات GitHub: محتاج
issues: writeلأن الـ workflow هيكتب Issue. متديش صلاحيات أوسع من كده. - الروابط الخارجية: بعض المواقع تمنع الفحص الآلي أو تعمل rate limit. الحل مش إنك تعطل الفحص كله، لكن تضبط الاستثناءات أو تقلل التكرار.
- تراكم الـ Issues: لو كل تشغيل يفتح Issue جديد، هتعمل ضوضاء. الأفضل لاحقًا تطور الروتين ليحدّث Issue موجود، لكن النسخة هنا أبسط كبداية.
متى لا تستخدم هذه الطريقة
لا تستخدمها كحارس إلزامي على كل pull request لو موقعك فيه روابط خارجية كثيرة وغير مستقرة. هتعطل المطورين بسبب أخطاء خارج سيطرتهم. لا تستخدمها كبديل لاختبارات التنقل داخل التطبيق لو عندك routes ديناميكية خلف login. في الحالة دي Playwright أو Cypress أنسب.
كمان لا تشغلها كل 5 دقائق. GitHub Actions يدعم schedules متكررة، لكن فحص الروابط ضغط على مواقع خارجية. أسبوعيًا أو يوميًا كفاية لمعظم المدونات ومواقع التوثيق.
مصادر مفيدة
- lycheeverse/lychee-action: إعداد Lychee داخل GitHub Actions، وخيارات
failوoutput. - GitHub Actions schedule: تشغيل workflow بجدول cron وصلاحيات workflow.
- GitHub CLI issue create: بديل لو عايز تبني خطوة إنشاء الـ Issue بنفسك باستخدام
gh.
الخطوة التالية
الخطوة التالية: ضيف ملف check-links.yml وشغله يدويًا أول مرة من Actions. لو التقرير طلع أكثر من 20 رابط، ابدأ بالروابط الداخلية فقط قبل ما تضيف الروابط الخارجية.