กลับไปที่บล็อก
A git diff view showing a locale file with three changed keys highlighted, and only those three keys being sent to the translation API below.

คุณไม่จำเป็นต้องแปลทุกอย่างใหม่: วิธีการทำงานของการแปลเดลต้าใน CI

By Robert M

คุณไม่จำเป็นต้องแปลซ้ำทั้งหมด: วิธีการทำงานของการแปลแบบเดลต้าใน CI

เมื่อคุณเชื่อมต่อการแปลอัตโนมัติเข้ากับ pipeline CI ของคุณ คำถามที่เกิดขึ้นโดยธรรมชาติคือ: มันจะแปลไฟล์ locale ทั้งหมดใหม่ทุกครั้งที่มีการเปลี่ยนแปลงหรือไม่?

ถ้าไม่มีโหมดเดลต้า ใช่ ทุกครั้งที่มีการ push ที่แตะต้องไฟล์ locale ต้นทางของคุณ จะส่งไฟล์ทั้งหมดไปยัง API ทุกคีย์ ทุกสตริง ไม่ว่าจะเปลี่ยนแปลงหรือไม่ก็ตาม สำหรับโปรเจกต์เล็ก ๆ ในช่วงเริ่มต้น นั่นก็โอเค สำหรับโปรเจกต์ที่โตเต็มที่ที่มีคีย์แปลหลายร้อยคีย์ใน 10 หรือ 20 ภาษา คุณจะเสียโทเค็นไปกับสตริงที่ไม่ได้เปลี่ยนแปลงตั้งแต่รันครั้งก่อน และได้รับผลลัพธ์เหมือนเดิมกลับมาโดยเปล่าประโยชน์

การแปลแบบเดลต้าจัดการปัญหานี้ แทนที่จะส่งไฟล์เต็ม Action จะเปรียบเทียบไฟล์ต้นทางปัจจุบันกับ baseline ที่เก็บไว้ ระบุเฉพาะคีย์ที่เพิ่มหรือแก้ไข และส่งเฉพาะคีย์เหล่านั้นไปยัง API ผลลัพธ์สำหรับคีย์ที่ไม่เปลี่ยนแปลงจะถูกนำมาจากไฟล์แปลที่มีอยู่ การใช้โทเค็นลดลงให้สอดคล้องกับงานที่ทำจริง


วิธีการทำงานของ baseline

เมื่อโหมดเดลต้ารันครั้งแรก หรือเมื่อคุณบังคับรีเฟรชเต็ม Action จะทำการแปลไฟล์ต้นทางทั้งหมดและเก็บ JSON แบบแบนของไฟล์นั้นเป็น baseline ใน repository ของคุณ ในการรันครั้งถัดไป Action จะโหลด baseline นั้น เปรียบเทียบกับไฟล์ต้นทางปัจจุบัน และสร้าง payload ที่มีเฉพาะคีย์ที่เปลี่ยนแปลง

สำหรับไฟล์ locale JSON baseline จะถูกเก็บเป็น .polylingo-baseline.json ในไดเรกทอรี messages สำหรับไฟล์ locale YAML baseline จะถูกเก็บเป็น .polylingo-yaml-baseline.json ในไดเรกทอรี locales สำหรับไฟล์ Laravel PHP lang baseline จะถูกเก็บเป็น .polylingo-laravel-php-baseline.json ในไดเรกทอรี lang

baseline จะถูก commit พร้อมกับไฟล์แปลของคุณ ดังนั้นมันจะเดินทางไปกับ repository นักพัฒนาคนใดที่ clone repo จะได้ baseline เดียวกับที่ pipeline ใช้งาน


สิ่งที่นับว่าเป็นการเปลี่ยนแปลง

การ diff ทำงานบนการแทนคีย์แบบแบนของไฟล์ต้นทาง โครงสร้างซ้อนจะถูกแปลงเป็นคีย์แบบ dot-notation ก่อนเปรียบเทียบ:

{
  "nav.home": "หน้าแรก",
  "nav.about": "เกี่ยวกับเรา",
  "hero.title": "ยินดีต้อนรับสู่แพลตฟอร์มของเรา",
  "hero.cta": "เริ่มต้นใช้งาน"
}

คีย์จะถูกรวมใน payload เดลต้าถ้า:

  • มีอยู่ในไฟล์ต้นทางปัจจุบันแต่ไม่มีใน baseline (คีย์ใหม่)
  • มีอยู่ทั้งสองที่แต่ค่ามีการเปลี่ยนแปลง (คีย์ที่แก้ไข) คีย์ที่มีใน baseline แต่ไม่มีในไฟล์ต้นทางปัจจุบัน (คีย์ที่ถูกลบ) จะถูกลบออกจากไฟล์แปลโดยอัตโนมัติ คีย์ที่เหมือนกันทั้งสองฝั่งจะถูกข้ามและแปลเดิมจะถูกเก็บไว้

สิ่งนี้ดูเป็นอย่างไรในทางปฏิบัติ

สมมติว่าคุณมีโปรเจกต์ Next.js ที่มี 200 คีย์แปลใน messages/en.json ซึ่งแปลแล้วเป็น 12 ภาษา นักพัฒนาคนหนึ่งอัปเดตข้อความในส่วน hero และเพิ่มคีย์ใหม่สองคีย์สำหรับประกาศฟีเจอร์ นั่นคือ 4 คีย์ที่เปลี่ยนจาก 200 คีย์

ถ้าไม่มีโหมดเดลต้า pipeline จะส่งคีย์ทั้งหมด 200 คีย์ คูณด้วย 12 ภาษาในทุกครั้งที่ push แต่ถ้ามีโหมดเดลต้า จะส่งแค่ 4 คีย์ การใช้โทเค็นสำหรับรันนั้นประมาณ 2% ของค่าใช้จ่ายการแปลเต็ม Pipeline ยังเร็วขึ้นเพราะมีข้อมูลส่งและรอคอยน้อยลง

ในช่วงเดือนของการพัฒนาปกติ การประหยัดนี้สะสมอย่างมาก ส่วนใหญ่การ push แตะเพียงไม่กี่สตริง การแปลซ้ำเต็มจะเกิดขึ้นเฉพาะเมื่อคุณเพิ่มภาษาใหม่หรือรีเซ็ต baseline อย่างชัดเจน


PolyLingo GitHub Actions ทั้งสาม

โหมดเดลต้ามีให้ใช้ในทั้งสาม PolyLingo translation Actions แต่ละตัวถูกสร้างขึ้นสำหรับประเภทเนื้อหาและโครงสร้างโปรเจกต์เฉพาะ

translateAction — JSON และ Markdown

Action ต้นฉบับ จัดการไฟล์ locale JSON แบบแบนในสไตล์ next-intl และ i18next พร้อมตัวเลือกผ่าน async jobs API สำหรับไฟล์ Markdown ขนาดใหญ่

- uses: UsePolyLingo/translate-action@v1
  with:
    api_key: ${{ secrets.POLYLINGO_API_KEY }}
    source_file: messages/en.json
    locales: fr,de,es,ja,zh
    delta: true
    commit: true
    commit_message: "chore(i18n): sync translations"

Delta baseline: messages/.polylingo-baseline.json

github.com/UsePolyLingo/translateActionดูใน Marketplace


translate-action-yaml — ไฟล์ locale YAML

สำหรับโปรเจกต์ที่ใช้ไฟล์ locale YAML ซ้อน: Rails i18n, Vue i18n และเฟรมเวิร์กอื่น ๆ ที่ใช้ฟอร์แมต YAML Action จัดการ convention ของ Rails ที่มีคีย์ root locale อัตโนมัติ — en.yml มีคีย์ root en: และแต่ละไฟล์ผลลัพธ์จะได้คีย์ locale เป้าหมายที่ถูกต้อง (fr:, de: ฯลฯ)

เนื่องจาก PolyLingo API ทำงานกับ JSON โดยตรง Action จะ flatten YAML ซ้อนเป็น JSON dot-notation ก่อนส่ง แปล แล้วสร้างโครงสร้างซ้อนขึ้นมาใหม่และเขียนผลลัพธ์ YAML ที่ถูกต้อง caveat ของ v1 คือคีย์ที่มีจุดตามธรรมชาติจะไม่รองรับเพราะขัดแย้งกับการ flatten dot-notation

- uses: UsePolyLingo/translate-action-yaml@v1
  with:
    api_key: ${{ secrets.POLYLINGO_API_KEY }}
    locales_dir: config/locales
    source_file: config/locales/en.yml
    locales: fr,de,es,ja
    delta: true
    commit: true

Delta baseline: config/locales/.polylingo-yaml-baseline.json

github.com/UsePolyLingo/translate-action-yamlดูใน Marketplace


translate-action-laravel — ไฟล์ lang Laravel

สำหรับโปรเจกต์ Laravel ที่ใช้ไฟล์แปล JSON (lang/en.json รองรับทั้งโครงสร้างซ้อนและแบนในสไตล์ Laravel 9+) หรือไฟล์ PHP array (lang/en/*.php) Action ตรวจจับฟอร์แมตโดยอัตโนมัติผ่าน php_format: auto — ตรวจ lang/en.json ก่อน ถ้าไม่เจอจะใช้ไฟล์ PHP array

สำหรับไฟล์ PHP จะเรียก PHP CLI เพื่ออ่านไฟล์ต้นทางและ serialize ผลลัพธ์แปลกลับเป็น syntax PHP array ที่ถูกต้องใน JavaScript โดยไม่มี dependencies เพิ่มเติม runners ubuntu-latest ของ GitHub มี PHP 8.x ติดตั้งมาแล้วจึงไม่ต้องตั้งค่าเพิ่ม ต้องใช้ PHP 7.4 ขึ้นไป

caveat ของ v1: คีย์ที่มีจุดไม่รองรับในโหมด PHP เนื่องจากกลยุทธ์ flatten dot-notation

- uses: UsePolyLingo/translate-action-laravel@v1
  with:
    api_key: ${{ secrets.POLYLINGO_API_KEY }}
    lang_dir: lang
    source_locale: en
    locales: fr,de,es,pt,nl
    php_format: auto
    delta: true
    open_pr: true

Delta baseline: lang/.polylingo-laravel-json-baseline.json หรือ lang/.polylingo-laravel-php-baseline.json ขึ้นกับฟอร์แมต

github.com/UsePolyLingo/translate-action-laravelดูใน Marketplace


โหมด PR กับโหมด commit

ทั้งสาม Action รองรับสองโหมดผลลัพธ์

โหมด commit (commit: true) เขียนไฟล์แปลและ commit ลงสาขาปัจจุบันทันที ตั้งค่าง่าย เหมาะกับทีมที่จัดการแปลเป็นกระบวนการอัตโนมัติที่ไม่ต้องการรีวิว

โหมด PR (open_pr: true) สร้างสาขาใหม่ (polylingo/yaml-<sha>, polylingo/laravel-<sha> ฯลฯ) เขียนไฟล์แปลที่นั่น และเปิด pull request กับสาขาหลัก เหมาะกับทีมที่ต้องการขั้นตอนรีวิวโดยมนุษย์ก่อนรวมเนื้อหาแปล หรือโปรเจกต์ที่คุณภาพการแปลมีผลโดยตรงกับประสบการณ์ผู้ใช้

ถ้าตั้งทั้งสองพร้อมกัน โหมด PR จะมีผล

โหมด PR ต้องการสิทธิ์ pull-requests: write ใน workflow:

permissions:
  contents: write
  pull-requests: write

การบังคับรีเฟรชเต็ม

โหมดเดลต้าเปรียบเทียบกับ baseline ที่เก็บไว้ ถ้าคุณต้องการแปลใหม่ทั้งหมดไม่ว่าจะ baseline แสดงอะไร ให้ตั้ง delta: false ซึ่งจะอัปเดต baseline ให้ตรงกับไฟล์ต้นทางปัจจุบันด้วย ดังนั้นการรันเดลต้าครั้งถัดไปจะเริ่มจากสถานะใหม่

การรีเฟรชเต็มมีประโยชน์เมื่อคุณเพิ่มภาษาเป้าหมายใหม่ ต้องการรับการปรับปรุงคุณภาพแปลในโมเดลเวอร์ชันใหม่ หรือเมื่อ baseline เบี่ยงเบนจากความเป็นจริงด้วยเหตุผลใดก็ตาม

- uses: UsePolyLingo/translate-action-yaml@v1
  with:
    api_key: ${{ secrets.POLYLINGO_API_KEY }}
    locales_dir: config/locales
    locales: fr,de,es,ja,zh,ko,ar
    delta: false  # รีเฟรชเต็ม อัปเดต baseline
    commit: true

ผลลัพธ์สำหรับขั้นตอนถัดไป

ทั้งสาม Action เปิดเผยผลลัพธ์เหมือนกันเพื่อให้คุณใช้ในขั้นตอน workflow ถัดไปได้:

- uses: UsePolyLingo/translate-action@v1
  id: translate
  with:
    api_key: ${{ secrets.POLYLINGO_API_KEY }}
    source_file: messages/en.json
    locales: fr,de,es
    delta: true
    commit: true

- name: บันทึกสถิติการแปล
  run: |
    echo "Locales translated: ${{ steps.translate.outputs.locales_translated }}"
    echo "Files changed: ${{ steps.translate.outputs.files_changed }}"
    echo "Tokens used: ${{ steps.translate.outputs.tokens_used }}"

แต่ละรันยังเขียนตารางสรุปลงใน GitHub Actions step summary เพื่อให้คุณเห็นการใช้โทเค็นและผลลัพธ์การแปลโดยไม่ต้องค้นหาใน logs


เริ่มต้นใช้งาน

ทั้งสาม Action มีให้ใน GitHub Marketplace คุณจะต้องมี PolyLingo API key ซึ่งใช้ฟรีได้ที่ usepolylingo.com แผนฟรีรวม 50,000 โทเค็นต่อเดือน เมื่อเปิดโหมดเดลต้า โปรเจกต์ส่วนใหญ่จะอยู่ในขอบเขตนี้สำหรับการพัฒนาปกติ

เพิ่ม API key เป็น secret ของ repository (POLYLINGO_API_KEY) และใส่ Action ที่เกี่ยวข้องใน workflow ของคุณ การรันครั้งแรกจะทำการแปลเต็มและตั้ง baseline ทุกครั้งหลังจากนั้นจะแปลเฉพาะสิ่งที่เปลี่ยนแปลงเท่านั้น

คุณไม่จำเป็นต้องแปลทุกอย่างใหม่: วิธีการทำงานของการแปลเดลต้าใน CI | PolyLingo