دليل الإجراءات

لقطات أسبوعية للروابط الخلفية على GitHub Actions: دليل إجراءات

الهدف: كل يوم اثنين، يقوم العمل بن كتابة النطاقات المرجعية والنصوص الوصفية لليوم في المستودع. لا شيء آخر. سيتم إجراء المقارنات لاحقًا.

جسر حديدي يعبر نهرًا، يرمز إلى بنية تشغيل الجدول الزمني الموثوقة
قبل البدء

تحتاج إلى مستودع، ومفتاح Linkzoid مخزن كسرية باسم LZ_KEY، ونطاق واحد تمتلكه. الميزانية: حوالي 6 ائتمانات لكل هدف في كل تشغيل، وهو ما يعادل $0.0006. اللقطة هي حقيقة عن شهر واحد، لذا فإن التشغيلات الأسبوعية تعيد غالبًا جلب نفس الفهرس. إعداد طريقة فحص الروابط الخلفية لموقعي بهذه الطريقة يستغرق مساءً واحدًا.

دليل الإجراءات، بالترتيب

01

1. أضف السرية

إعدادات المستودع، ثم الأسرار والمتغيرات، ثم Actions. سمّه LZ_KEY. إذا قمت بلصقه في ملف العمل بدلاً من ذلك، قم بتدوير المفتاح اليوم.

02

2. التزم بالسكريبت

احفظ بايثون أدناه باسم snap.py. يكتب الملف في data/YYYY-MM-DD/refdomains.json ويتوقف عند أي استجابة تكون فيها ok غير صحيحة.

03

3. التزم بالعمل

استخدم ملف YAML أدناه. شغله مرة يدويًا باستخدام الزناد workflow_dispatch واقرأ السجل قبل أن تثق بالجدول الزمني.

04

4. تحقق من الملف الأول

افتح ملف JSON. تحقق من عدد الصفوف مقابل total، وقارن الرقم مع ما تقرئه استدعاء overview المجاني لنطاقك.

05

5. أضف التنبيه

يعمل الفشل في إرسال بريد إلكتروني إلى مالك المستودع بشكل افتراضي. اترك هذا الخيار مفعلاً. العمل الذي يتوقف بصمت هو الطريقة المعتادة التي تموت بها هذه الإعدادات.

snap.py

مكتبة قياسية. ينتهي الحلقة عند العدد، وليس على تخمين.

python
import json, os, sys, datetime, pathlib, urllib.request as u
KEY = os.environ['LZ_KEY']
TARGET = sys.argv[1]
def get(**p):
    q = '&'.join(f'{k}={v}' for k, v in p.items())
    url = f'https://linkzoid.pro/api.php?{q}&key={KEY}'
    with u.urlopen(url, timeout=30) as r:
        return json.load(r)
rows, page = [], 1
while True:
    d = get(action='refdomains', q=TARGET, page=page, per=1000)
    if not d['ok']:
        sys.exit(f'bad response: {d}')
    rows += d['rows']
    if not d['rows'] or len(rows) >= d['total']:
        break
    page += 1
day = datetime.date.today().isoformat()
out = pathlib.Path('data') / day
out.mkdir(parents=True, exist_ok=True)
(out / 'refdomains.json').write_text(json.dumps(rows))
print(len(rows), 'rows, balance', d['_credits'])

.github/workflows/snapshot.yml

التوقيت في GitHub يعمل بتوقيت UTC وقد يبدأ متأخرًا عندما تكون المشغلات مشغولة. لا تبني أي شيء يعتمد على الدقيقة.

yaml
name: backlink-snapshot
on:
  schedule:
    - cron: '17 6 * * 1'
  workflow_dispatch:
jobs:
  snap:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - run: python snap.py example.com
        env:
          LZ_KEY: ${{ secrets.LZ_KEY }}
      - run: |
          git config user.name snapshot-bot
          git config user.email "snapshot-bot@localhost"
          git add data
          git commit -m "snapshot $(date -u +%F)" || exit 0
          git push
مزارع يقطع شتلة صغيرة، يمثل التحضير قبل بدء الجدول الزمني

قبل تشغيل الجدول الزمني

  • المفتاح موجود في أسرار المستودع، وملف العمل يشير إليه فقط بالاسم.
  • ملف العمل موجود على الفرع الافتراضي، لأنه النسخة التي يقرأها الجدول الزمني.
  • تشغيل يدوي مع workflow_dispatch انتهى وكتب مجلدًا مؤرخًا واحدًا.
  • عدد الصفوف في الملف يطابق المجموع الذي أثارته API لذلك الاستدعاء.
  • يخرج العمل برمز غير صفري عند استجابة سيئة، لذا فإن الفشل يجعل التشغيل أحمر.

الأخطاء والإصلاحات

ما الذي ينكسر أولاً في مهمة الروابط الخلفية المجدولة
خطأما تراهالإصلاح
المفتاح ملصق في ملف YAMLالمفتاح مرئي في سجل المستودعقم بتدويره، انقله إلى secrets.LZ_KEY
دقيقة غريبة مثل 0 0يبدأ التشغيل متأخرًا 20 دقيقةاختر 17 6؛ قمة الساعة مزدحمة
المستودع خامل لمدة 60 يومًايتوقف GitHub عن الجدول الزمنيالتزم بشيء، أو أعد تمكينه في تبويب Actions
تتوقف الحلقة عند صفحة فارغة فقطتشغيل لا نهائي عند حد الصفحةتوقف أيضًا عندما len(rows) >= total
تم تجاهل رمز الخروجعلامة خضراء، مجلد فارغاستخدم sys.exit على ok: false
يفشل الالتزام عند عدم وجود تغييرتشغيل أحمر بلا فائدةأضف || exit 0 بعد الالتزام

الحفاظ على أمان المفتاح والمستودع

المفتاح هو الشيء الوحيد في هذه الإعدادات الذي يستحق الحماية. عامله مثل كلمة المرور، لأن أي شخص يملكه يمكنه إنفاق رصيدك.

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

قم بتدوير المفتاح عندما يغادر شخص ما

عند مغادرة زميل لديه صلاحية الوصول، أنشئ مفتاحًا جديدًا، حدّث السرية وأوقف المفتاح القديم. ثم تأكد من أن التشغيل التالي يمر. تشغيل أخضر واحد بعد التغيير هو أرخص اختبار ستقوم به طوال العام. اكتب تاريخ التدوير في ملاحظات المستودع أيضًا، حتى لا يكون التدوير التالي مفاجئًا.

حد من من يمكنه تعديل العمل

أي شخص يمكنه تعديل ملف YAML يمكنه طباعة السرية في تشغيل. حافظ على صلاحية الكتابة قصيرة، وراجع التغييرات في ملف العمل كما تراجع الكود. شخصان لديهم صلاحية الكتابة عادةً ما يكونان كافيين لمستودع صغير.

لا تطبع عنوان URL للطلب أبدًا

اطبع الرصيد وعدد الصفوف، ولا تطبع عنوان URL للطلب أبدًا. ينتقل المفتاح في سلسلة الاستعلام، لذا فإن سطر تصحيح الأخطاء الذي يطبع عنوان URL يكتب المفتاح في السجل. إذا اضطررت لمشاركة طلب في قضية، استبدل المفتاح بمكان احتياطي أولاً.

بوصلة ونبات في أصيص، يشير إلى التقدم الثابت والكشف المبكر عن المشكلات

ما هي اللقطة، وما ليست عليه

ما تحصل عليه هو صورة شهرية. يقوم زاحفنا الخاص بتحديث الفهرر مرة واحدة تقريبًا في الشهر، لذا فإن تشغيلين يوم الاثنين في نفس الشهر غالبًا ما يعيدان نفس الصفوف. هذا متوقع.

الإيقاع الأسبوعي يعمل. يحافظ على العادة حية، وتكتشف العمل الفاشل خلال سبعة أيام بدلاً من ثلاثين. إذا كان الرابط الذي بنيتَه يوم الثلاثاء مفقودًا يوم الاثنين، انتظر التحديث التالي قبل الذعر.

عندما يكون لديك ثلاثة أو أربعة مجلدات مؤرخة، انتقل إلى فرق ملف SQLite. إذا كنت عالقًا في رمز استجابة عنيد، جدول حد معدل يوضح ما يعنيه كل حالة للحلقة.

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

إضافة النصوص الوصفية (Anchors) والصفحات العليا

عمل واحد لكل ملف يجعل الفروق قابلة للقراءة. انسخ الحلقة في snap.py، غير refdomains إلى anchors أو toppages، واكتب في اسم ملف ثانٍ. كل منهما يكلف 2 ائتمانات.

الملف المجمع يخفي أي جزء تغير، والمراجع الذي يتصفح طلب السحب يريد رؤية مفهوم واحد لكل فرق. افصلها. إذا كنت تتبع ثلاثة نطاقات، قم بالتكرار عبر قائمة قصيرة في العمل باستخدام مصفوفة، بحيث يحصل كل هدف على وظيفته الخاصة وفشله الخاص.

النصوص الوصفية هي ملف ثانٍ بحد خاص به في الفرق، لذا راجعها بشكل منفصل عن النطاقات المرجعية. يبقى كل تشغيل رخيصًا وقابلًا للتكرار، وهو الفكرة كلها.

قراءة سجل التشغيل

افتح سجل التشغيل الأول. افعل ذلك قبل أن تثق بالجدول الزمني. ابحث عن عدد الصفوف، والرصيد، وسطر الالتزام. إذا كان أي من الثلاثة مفقودًا، فإن المهمة قامت بأقل مما تدعي. احتفظ بملاحظة قصيرة عن الرصيد في كل تشغيل أيضًا، حتى يكون الإنفاق الشهري مرئيًا دون فتح لوحة التحكم.

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

كيف يبدو السجل الصحي

التشغيل الصحي يطبع سطرًا واحدًا يحتوي على عدد الصفوف ورصيد الائتمان، ثم التزامًا بتاريخ اليوم. أي شيء يخبئ هذه الأسطر تحت ضوضاء إضافية يستحق نظرة ثانية.

اكتشاف الفشل الصامت

راقب مجلدًا فارغًا، أو التزامًا لا يظهر أبدًا، أو عدد صفوف يختلف عن المجموع. كل هذه تشير إلى الحلقة أو التحليل، وليس إلى API نفسه. احفظ أول سجل صحي كمرجع للمقارنات المستقبلية.

بعض الفشل تترك مجلدًا وراءه بعدد صفوف أقل من المعتاد. قارن العدد مع الأسبوع السابق قبل أن تحتفل بتشغيل أخضر، لأن التقصير الهادئ يبدو تمامًا مثل شهر هادئ.

إضافة هدف ثانٍ بأمان

النطاق الثاني هو إدخال مصفوفة، وليس نسخة من العمل بالكامل. امنح كل هدف وظيفته الخاصة حتى لا يخفي فشل واحد آخرًا. حافظ على فصل كل وظيفة. تحقق من أن المسارات تتضمن اسم النطاق، حتى لا يكتب تشغيلان في نفس الملف.

ابدأ بالهدف الثاني وحده. بمجرد أن يبدو المجلد صحيحًا، أضف الباقي. مصفوفة تفشل في منتصف الطريق أصعب في القراءة من تشغيلين بسيطين.

سمِّ المجلدات حسب الهدف

ضع النطاق في المسار، على سبيل المثال data/<domain>/YYYY-MM-DD، وتبقى المجلدات منفصلة حتى عندما يعمل وظيفتان في نفس الدقيقة. يمكن أن تبقى المجلدات القديمة حيث هي، لأن التاريخ في المسار يجعلها سهلة البحث.

استخدم قاعدة التسمية نفسها لكل هدف. يمكن للسكريبت بعد ذلك سرد المجلدات بدون حالات خاصة.

خطط لميزانية الائتمان أولاً

اضرب المكالمات لكل هدف في عدد الأهداف، ثم تحقق من المجموع مقابل رصيدك قبل التشغيل الأول. تضرب المصفوفة الإنفاق بسرعة تضرب بها الوظائف. اكتب الإجمالي الشهري المتوقع في المستودع بجانب العمل. عندما ينخفض الرصيد أسرع من ذلك، فمن المحتمل أن الحلقة تعيد جلب الصفحات، ويمكنك إيقافها قبل التشغيل التالي.

الأسئلة التي تظهر في الأسبوع الأول

هل يمكنني تشغيل هذا على مستودع خاص مجانًا؟
عادةً نعم، ضمن الدقائق الشهرية التي تمنحها الحسابات المجانية في GitHub. يعمل تشغيل اللقطة في أقل من دقيقة، لذا فإن الجدول الزمني الأسبوعي يستخدم حصة صغيرة. تحقق من السماح الحالي لخطة الخاصة بك، لأن GitHub يغيره من وقت لآخر.
أين يجب أن يعيش المفتاح إذا دفع عدة أشخاص؟
في سرية المنظمة أو المستودع، وليس في الملفات. أي شخص يمكنه تعديل العمل يمكنه طباعة سرية في سجل، لذا حد من من لديهم صلاحية الكتابة، وقم بتدوير المفتاح إذا غادر شخص ما المشروع.
لماذا لم يشغل تشغيلي المجدول؟
ثلاثة أسباب شائعة. ملف العمل ليس على الفرع الافتراضي، أو المستودع كان خاملًا لمدة 60 يومًا وتوقف GitHub عن الجدول الزمني، أو أن سلسلة Cron تحتوي على خطأ مطبعي. شغله مرة واحدة مع workflow_dispatch لاستبعاد السكريبت نفسه.
كم يصبح حجم مجلدات البيانات؟
صغيرة. ألف نطاق مرجعي هو بضع مئات من كيلوبايت من JSON. سنة من الملفات الأسبوعية لنطاق واحد تبقى أقل بكثير من مئة ميجابايت، وهو أمر جيد لـ git، على الرغم من أنه يمكنك ضغط المجلدات القديمة إذا كان ذلك يزعجك.