
คุณไม่จำเป็นต้องแปลทุกอย่างใหม่: วิธีการทำงานของการแปลเดลต้าใน 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 ทุกครั้งหลังจากนั้นจะแปลเฉพาะสิ่งที่เปลี่ยนแปลงเท่านั้น