تكامل Lingo.dev مع GitHub

إجراء Lingo.dev GitHub هو تكامل CI/CD مفتوح المصدر وآمن يقوم تلقائيًا بترجمة المحتوى الجديد ويمنع الترجمات غير المكتملة من الوصول إلى الإنتاج. يقوم بإنشاء طلبات سحب أو التزامات مباشرة إلى الفرع الخاص بك، اعتمادًا على متطلبات سير عمل فريقك.

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

يدعم الإجراء سيناريوهات سير العمل المتعددة:

  1. التزامات مباشرة إلى الفرع الرئيسي عند دمج تغييرات المحتوى
  2. التزامات مباشرة إلى فروع طلب السحب عند فتح طلبات السحب أو تحديثها
  3. طلبات السحب التي تستهدف الفرع الرئيسي لتحديثات الترجمة
  4. طلبات السحب التي تستهدف فروع طلب السحب الموجودة لتحديثات الترجمة

عند الانتهاء من هذا الدليل، سوف تقوم بما يلي:

  1. إعداد الترجمة الآلية التي يتم تشغيلها بواسطة دفعات الكود؛
  2. تكوين المصادقة الآمنة باستخدام أسرار المستودع؛
  3. الاختيار بين الالتزامات المباشرة أو سير عمل طلبات السحب؛
  4. فهم كيفية تناسب الترجمة المستمرة مع العملية الحالية الخاصة بك.

لنبدأ!

المتطلبات الأساسية

إعداد المستودع

يجب أن يكون مستودعك مكونًا بـ واجهة سطر أوامر Lingo.dev مع ملف i18n.json صالح. إذا لم تقم بإعداد ذلك بعد، أكمل البدء السريع لواجهة سطر الأوامر أولاً.

الخطوة 1. إعداد المصادقة

تحتاج إجراءات Lingo.dev GitHub إلى الوصول إلى محرك الترجمة والمستودع الخاص بك. تتم المصادقة من خلال أسرار المستودع التي تحافظ على أمان بيانات الاعتماد الخاصة بك.

إضافة مفتاح API الخاص بك

انتقل إلى إعدادات المستودع الخاص بك → الأسرار والمتغيرات → الإجراءات، ثم أضف بيانات اعتماد محرك الترجمة الخاص بك:

لمستخدمي واجهة برمجة التطبيقات LLM الأساسية:

  • اسم السر: OPENAI_API_KEY أو ANTHROPIC_API_KEY
  • قيمة السر: مفتاح API الخاص بك من المزود المعني

لمستخدمي محرك Lingo.dev:

  • اسم السر: LINGODOTDEV_API_KEY
  • قيمة السر: مفتاح API الخاص بمشروعك من lingo.dev/app

الخطوة 2. إنشاء سير العمل

قم بإنشاء ملف .github/workflows/i18n.yml في المستودع الخاص بك مع هذا التكوين الأساسي:

name: Lingo.dev i18n

on:
  workflow_dispatch:
  push:
    branches:
      - main
      - feat/*

permissions:
  contents: write
  pull-requests: write

jobs:
  i18n:
    name: Run i18n
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: lingodotdev/lingo.dev@main
        with:
          api-key: ${{ secrets.LINGODOTDEV_API_KEY }}

بدلاً من ذلك، يمكنك إضافة إجراء Lingo.dev على GitHub كخطوة في سير العمل الحالي الخاص بك:

- name: Lingo.dev
  uses: lingodotdev/lingo.dev@main
  with:
    api-key: ${{ secrets.LINGODOTDEV_API_KEY }}

الأذونات المطلوبة

يحتاج سير العمل الخاص بك إلى أذونات محددة ليعمل بشكل صحيح. تتطلب إجراءات GitHub تصريحات أذونات صريحة في ملف سير العمل:

permissions:
  contents: write # مطلوب: إنشاء عمليات الالتزام مع تحديثات الترجمة
  pull-requests: write # اختياري: مطلوب فقط عند استخدام وضع طلب السحب

إذن contents: write يسمح للإجراء بـ:

  • إنشاء عمليات الالتزام مع تحديثات الترجمة
  • دفع التغييرات مباشرة إلى المستودع الخاص بك
  • الوصول إلى الملفات وتعديلها في المستودع الخاص بك

يتم منح هذه الأذونات لرمز GitHub المؤقت للسير العمل (${{ github.token }})، والذي يتم إنشاؤه تلقائيًا بواسطة GitHub لكل تشغيل لسير العمل ويحتوي على الأذونات المحددة التي تحددها في ملف سير العمل.

هذا التكوين:

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

ميزة إضافية:

  • في Lingo.dev، نفضل إضافة مشغل workflow_dispatch إلى كل سير عمل، حتى نتمكن من تشغيله يدويًا (أو إعادة تشغيله) من واجهة مستخدم إجراءات GitHub. هذا اختياري تمامًا، لكننا وجدناه مفيدًا جدًا.

الخطوة 3. اختر وضع سير العمل الخاص بك

تدعم إجراءات GitHub من Lingo.dev وضعين تشغيليين اعتمادًا على متطلبات مراجعة الكود لفريقك.

وضع الالتزام المباشر (الافتراضي)

يقوم الإجراء بإرسال الترجمات مباشرة إلى الفرع الخاص بك:

- uses: lingodotdev/lingo.dev@main
  with:
    api-key: ${{ secrets.LINGODOTDEV_API_KEY }}

يعمل هذا الوضع بشكل أفضل لـ:

  • المطورين المنفردين أو الفرق الصغيرة
  • فروع الميزات التي ستتم مراجعتها قبل الدمج
  • المشاريع التي لا تتطلب فيها تحديثات الترجمة مراجعة منفصلة

وضع طلب السحب

ينشئ الإجراء طلبات سحب لتحديثات الترجمة:

- uses: lingodotdev/lingo.dev@main
  env:
    GH_TOKEN: ${{ github.token }}
  with:
    api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
    pull-request: true
    pull-request-title: "feat: update translations"

الأذونات المطلوبة لوضع طلب السحب

يتطلب وضع طلب السحب أذونات إضافية وإعدادات للمستودع:

permissions:
  contents: write # مطلوب: الوصول إلى محتوى المستودع وإنشاء الالتزامات
  pull-requests: write # مطلوب: إنشاء وتحديث طلبات السحب

إعداد رمز GitHub: يجب تعيين متغير البيئة GH_TOKEN إلى ${{ github.token }}، وهو رمز مؤقت يتم إنشاؤه تلقائيًا بواسطة GitHub لكل تشغيل لسير العمل. يحتوي هذا الرمز على الأذونات المحددة بالضبط في قسم permissions في ملف سير العمل الخاص بك.

إعدادات المستودع: يجب تمكين إجراءات GitHub لإنشاء طلبات السحب في إعدادات المستودع الخاص بك:

  1. انتقل إلى الإعداداتالإجراءاتعام
  2. قم بالتمرير إلى أسفل الصفحة
  3. ضمن "أذونات سير العمل"، تأكد من تمكين "السماح لإجراءات GitHub بإنشاء طلبات السحب والموافقة عليها"

إذا لم تر هذا الخيار في إعدادات المستودع الخاص بك، فتحقق من إعدادات المؤسسة:

  1. انتقل إلى إعدادات المؤسسة الخاصة بك → الإجراءاتعام
  2. ابحث عن نفس إعداد "السماح لإجراءات GitHub بإنشاء طلبات السحب والموافقة عليها"

يعمل هذا الوضع بشكل أفضل لـ:

  • الفرق ذات متطلبات مراجعة الكود الصارمة
  • المشاريع التي تحتاج فيها تغييرات الترجمة إلى موافقة منفصلة
  • سير العمل الذي يتطلب مراجعة صريحة لجميع التغييرات

الخطوة 4. سيناريوهات سير العمل

يتكيف إجراء Lingo.dev على GitHub تلقائيًا مع مختلف سير عمل التطوير. فهم هذه السيناريوهات يساعدك على اختيار التكوين المناسب لفريقك.

السيناريو 1: تحديثات الفرع الرئيسي (الالتزامات المباشرة)

المحفز: الدفع إلى الفرع الرئيسي (مثلاً، عند دمج طلبات السحب) الإجراء: يلتزم بتحديثات الترجمة مباشرة إلى الفرع الرئيسي

on:
  push:
    branches: [main]

# الإجراء يلتزم مباشرة بالفرع الرئيسي

- uses: lingodotdev/lingo.dev@main
  with:
    api-key: ${{ secrets.LINGODOTDEV_API_KEY }}

التدفق: يتم دفع تغييرات المحتوى إلى main → يلتزم الإجراء بالترجمات إلى main

يضمن هذا السيناريو أن الفرع الرئيسي يحتوي دائمًا على ترجمات محدثة مباشرة بعد دمج تغييرات المحتوى.

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

السيناريو 2: تحديثات طلب السحب (الالتزامات المباشرة)

المحفز: فتح طلب سحب أو تحديثه بتغييرات المحتوى الإجراء: يلتزم بتحديثات الترجمة مباشرة إلى فرع طلب السحب

on:
  pull_request:
    types: [opened, synchronize]

# الإجراء يلتزم مباشرة بفرع طلب السحب

- uses: lingodotdev/lingo.dev@main
  with:
    api-key: ${{ secrets.LINGODOTDEV_API_KEY }}

التدفق: تغييرات المحتوى في فرع طلب السحب → يلتزم الإجراء بالترجمات إلى نفس فرع طلب السحب

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

السيناريو 3: طلبات السحب إلى الفرع الرئيسي (وضع طلب السحب)

المحفز: الدفع إلى الفرع الرئيسي (مثلاً، عند دمج طلبات السحب) الإجراء: ينشئ طلب سحب مع تحديثات الترجمة

on:
  push:
    branches: [main]

# الإجراء ينشئ طلب سحب: main/lingo.dev ← main

- uses: lingodotdev/lingo.dev@main
  env:
    GH_TOKEN: ${{ github.token }}
  with:
    api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
    pull-request: true

التدفق: دفع تغييرات المحتوى إلى main ← الإجراء ينشئ فرع main/lingo.dev ← يفتح طلب سحب من main/lingo.devmain

السيناريو 4: طلبات السحب إلى فروع الميزات (وضع طلب السحب)

المحفز: فتح أو تحديث طلب سحب مع تغييرات المحتوى الإجراء: ينشئ طلب سحب مع تحديثات الترجمة يستهدف فرع الميزة

on:
  pull_request:
    types: [opened, synchronize]

# الإجراء ينشئ طلب سحب: feat/new-feature/lingo.dev ← feat/new-feature

- uses: lingodotdev/lingo.dev@main
  env:
    GH_TOKEN: ${{ github.token }}
  with:
    api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
    pull-request: true

التدفق: تغييرات المحتوى في feat/new-feature ← الإجراء ينشئ فرع feat/new-feature/lingo.dev ← يفتح طلب سحب من feat/new-feature/lingo.devfeat/new-feature

هذا يحافظ على مراجعات ترجمة منفصلة لكل فرع ميزة.

اتفاقية تسمية الفروع

عند استخدام وضع طلب السحب، يتبع إجراء Lingo.dev GitHub نمط تسمية متسق:

الصيغة: <base-branch>/lingo.dev

أمثلة:

  • تحديثات الفرع الرئيسي: main/lingo.devmain
  • تحديثات فرع الميزة: feat/user-auth/lingo.devfeat/user-auth
  • تحديثات فرع الإصدار: release/v2.0/lingo.devrelease/v2.0

تضمن اتفاقية التسمية هذه أن فروع الترجمة قابلة للتحديد بوضوح ومرتبطة تلقائيًا بفروعها المصدرية.

التعامل مع المساهمات الخارجية

عند العمل مع التفرعات الخارجية، قم بتنفيذ الاستخراج الانتقائي للحفاظ على أمان المستودع:

jobs:
  i18n:
    name: Run i18n
    runs-on: ubuntu-latest
    permissions:
      actions: write
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
      - run: find locales/** -name "*.json" | xargs git checkout ${{ github.event.pull_request.head.sha }} --
        shell: bash
      - uses: lingodotdev/lingo.dev@main
        with:
          api-key: ${{ secrets.LINGODOTDEV_API_KEY }}

الأذونات المطلوبة للمساهمات الخارجية

يتطلب التعامل مع المستودعات الخارجية المتفرعة صلاحيات مرتفعة لمعالجة المساهمات بشكل آمن:

permissions:
  actions: write # مطلوب: الوصول إلى معلومات سير العمل والمخرجات
  contents: write # مطلوب: إنشاء التزامات والوصول إلى محتوى المستودع
  pull-requests: write # مطلوب: تحديث طلبات السحب من المستودعات المتفرعة الخارجية

صلاحية actions: write مطلوبة تحديداً من أجل:

  • الوصول إلى البيانات الوصفية لطلبات السحب من المستودعات المتفرعة الخارجية
  • قراءة سياق سير العمل للتحقق الأمني
  • التعامل مع المخرجات وحالة سير العمل بشكل آمن

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

يعتمد هذا النهج على:

  • فحص ملفات الترجمة فقط من المستودع المتفرع
  • منع كشف رمز المستودع الحساس
  • الحفاظ على صلاحيات الكتابة الضرورية للإجراء

التكوين المتقدم

قم بتخصيص سلوك الإجراء باستخدام معلمات إضافية:

- uses: lingodotdev/lingo.dev@main
  env:
    GH_TOKEN: ${{ github.token }}
  with:
    api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
    pull-request: true
    commit-message: "feat: update translations via lingo.dev"
    working-directory: "apps/web"
    version: "latest"
    process-own-commits: false
    parallel: true

خيارات التكوين:

  • commit-message — رسالة مخصصة لالتزامات الترجمة
  • working-directory — تشغيل الإجراء في دليل فرعي
  • version — التثبيت على إصدار محدد من واجهة سطر الأوامر (غير موصى به)
  • process-own-commits — معالجة الالتزامات التي تم إجراؤها بواسطة هذا الإجراء
  • parallel — تمكين المعالجة المتوازية لمهام التوطين (الافتراضي: false)

المعالجة المتوازية

يدعم إجراء GitHub المعالجة المتوازية لمهام التوطين لتسريع سير عمل الترجمة بشكل كبير للمشاريع الكبيرة. قم بتمكين هذه الميزة عن طريق ضبط parallel: true:

- uses: lingodotdev/lingo.dev@main
  with:
    api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
    parallel: true

عند التمكين، يقوم الإجراء بما يلي:

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

هذه الميزة مفيدة بشكل خاص لـ:

  • المشاريع الكبيرة ذات متطلبات الترجمة الواسعة
  • سير العمل الذي يعالج لغات متعددة في وقت واحد
  • الفرق التي تتطلب تنفيذ أسرع لخط أنابيب CI/CD

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

وضع التحقق

باستخدام علامة --frozen، يمكنك التحقق من أن جميع الترجمات حديثة قبل كل نشر للإنتاج.

إليك مثال على كيفية استخدام علامة --frozen في خط أنابيب النشر الخاص بك:

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npx lingo.dev@latest i18n --frozen
      - run: npm run build
      - run: npm run deploy

علامة --frozen:

  • تتحقق من أن جميع الترجمات حديثة
  • لا تجري أي تغييرات على الملفات
  • تفشل عملية البناء إذا كانت الترجمات مفقودة أو قديمة