
Sie müssen nicht alles neu übersetzen: wie Delta-Übersetzung in CI funktioniert
By Robert M
Sie müssen nicht alles neu übersetzen: wie Delta-Übersetzung in CI funktioniert
Sobald Sie die automatisierte Übersetzung in Ihre CI-Pipeline integriert haben, stellt sich schnell eine natürliche Frage: Wird bei jeder Änderung die gesamte Lokalisierungsdatei neu übersetzt?
Ohne Delta-Modus, ja. Jeder Push, der Ihre Quell-Lokalisierungsdatei berührt, sendet die gesamte Datei an die API, jeden Schlüssel, jeden String, egal ob er sich geändert hat oder nicht. Für ein kleines Projekt in der Anfangsphase ist das in Ordnung. Für ein ausgereiftes Projekt mit Hunderten von Übersetzungsschlüsseln in 10 oder 20 Sprachen verbrauchen Sie Tokens für Strings, die sich seit dem letzten Lauf nicht geändert haben, und erhalten identische Ausgaben als Gegenleistung.
Delta-Übersetzung löst dieses Problem. Anstatt die gesamte Datei zu senden, vergleicht die Action Ihre aktuelle Quelldatei mit einer gespeicherten Basislinie, identifiziert nur die hinzugefügten oder geänderten Schlüssel und sendet nur diese an die API. Die Ausgabe für unveränderte Schlüssel wird aus den vorhandenen übersetzten Dateien übernommen. Der Tokenverbrauch sinkt und entspricht der tatsächlich geleisteten Arbeit.
Wie die Basislinie funktioniert
Wenn der Delta-Modus zum ersten Mal ausgeführt wird oder wenn Sie eine vollständige Aktualisierung erzwingen, übersetzt die Action die komplette Quelldatei und speichert eine flache JSON-Darstellung davon als Basisliniendatei in Ihrem Repository. Bei nachfolgenden Läufen lädt die Action diese Basislinie, vergleicht sie mit der aktuellen Quelldatei und erstellt eine Nutzlast, die nur die geänderten Schlüssel enthält.
Für JSON-Lokalisierungsdateien wird die Basislinie als .polylingo-baseline.json in Ihrem Nachrichtenverzeichnis gespeichert. Für YAML-Lokalisierungsdateien ist es .polylingo-yaml-baseline.json im Lokalisierungsverzeichnis. Für Laravel PHP lang-Dateien ist es .polylingo-laravel-php-baseline.json im lang-Verzeichnis.
Die Basislinie wird zusammen mit Ihren übersetzten Dateien committet, sodass sie mit dem Repository mitreist. Jeder Entwickler, der das Repo klont, erhält dieselbe Basislinie, mit der die Pipeline arbeitet.
Was als Änderung zählt
Der Diff arbeitet auf der abgeflachten Schlüssel-Darstellung Ihrer Quelldatei. Verschachtelte Strukturen werden vor dem Vergleich in Punktnotation-Schlüssel abgeflacht:
{
"nav.home": "Startseite",
"nav.about": "Über uns",
"hero.title": "Willkommen auf unserer Plattform",
"hero.cta": "Jetzt starten"
}
Ein Schlüssel wird in die Delta-Nutzlast aufgenommen, wenn:
- Er in der aktuellen Quelldatei existiert, aber nicht in der Basislinie (neuer Schlüssel)
- Er in beiden existiert, aber der Wert sich geändert hat (geänderter Schlüssel)
Schlüssel, die in der Basislinie existieren, aber nicht in der aktuellen Quelldatei (gelöschte Schlüssel), werden automatisch aus den übersetzten Ausgabedateien entfernt. Schlüssel, die in beiden identisch sind, werden vollständig übersprungen und ihre bestehenden Übersetzungen bleiben erhalten.
Wie das in der Praxis aussieht
Angenommen, Sie haben ein Next.js-Projekt mit 200 Übersetzungsschlüsseln in messages/en.json, bereits in 12 Sprachen übersetzt. Ein Entwickler aktualisiert den Text im Hero-Bereich und fügt zwei neue Schlüssel für eine Feature-Ankündigung hinzu. Das sind 4 geänderte Schlüssel von 200.
Ohne Delta-Modus sendet die Pipeline alle 200 Schlüssel multipliziert mit 12 Sprachen bei jedem Push. Mit Delta-Modus werden 4 Schlüssel gesendet. Der Tokenverbrauch für diesen Lauf beträgt ungefähr 2 % dessen, was eine vollständige Übersetzung kosten würde. Die Pipeline ist auch schneller, weil weniger gesendet und weniger gewartet werden muss.
Über einen Monat regelmäßiger Entwicklung summieren sich die Einsparungen erheblich. Die meisten Pushes betreffen nur eine Handvoll Strings. Eine vollständige Neuübersetzung erfolgt nur, wenn Sie eine neue Sprache hinzufügen oder die Basislinie explizit zurücksetzen.
Die drei PolyLingo GitHub Actions
Der Delta-Modus ist in allen drei PolyLingo Übersetzungs-Actions verfügbar. Jede ist für einen bestimmten Inhaltstyp und Projektstruktur gebaut.
translateAction — JSON und Markdown
Die ursprüngliche Action. Handhabt flache JSON-Lokalisierungsdateien im next-intl- und i18next-Stil, mit optionalem Markdown-Dokumentationsdurchlauf über die Async-Jobs-API für größere Dateien.
- 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-Basislinie: messages/.polylingo-baseline.json
github.com/UsePolyLingo/translateAction — Im Marketplace ansehen
translate-action-yaml — YAML-Lokalisierungsdateien
Für Projekte, die verschachtelte YAML-Lokalisierungsdateien verwenden: Rails i18n, Vue i18n und jedes andere Framework, das das YAML-Format nutzt. Die Action behandelt die Rails-Konvention eines Root-Lokalisierungsschlüssels automatisch — en.yml hat einen en: Root-Schlüssel, und jede Ausgabedatei erhält den korrekten Ziel-Lokalisierungsschlüssel (fr:, de: usw.).
Da die PolyLingo API nativ mit JSON arbeitet, flacht die Action verschachteltes YAML in Punktnotation-JSON ab, bevor sie es sendet, übersetzt es und rekonstruiert dann die verschachtelte Struktur und schreibt gültige YAML-Ausgabe. Ein v1-Hinweis: Schlüssel, die natürlich Punkte enthalten, werden nicht unterstützt, da sie mit der Punktnotation-Abflachung kollidieren.
- 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-Basislinie: config/locales/.polylingo-yaml-baseline.json
github.com/UsePolyLingo/translate-action-yaml — Im Marketplace ansehen
translate-action-laravel — Laravel lang-Dateien
Für Laravel-Projekte, die entweder JSON-Übersetzungsdateien (lang/en.json, unterstützt sowohl verschachtelte als auch flache Strukturen im Laravel 9+ Stil) oder PHP-Array-Lang-Dateien (lang/en/*.php) verwenden. Die Action erkennt automatisch, welches Format Ihr Projekt verwendet via php_format: auto — sie prüft zuerst auf lang/en.json und fällt auf PHP-Array-Dateien zurück, wenn diese nicht gefunden werden.
Für PHP-Dateien ruft sie die PHP-CLI auf, um Quell-Dateien zu lesen, und serialisiert die übersetzte Ausgabe zurück in gültige PHP-Array-Syntax in JavaScript, ohne zusätzliche Abhängigkeiten. GitHub-gehostete ubuntu-latest Runner enthalten standardmäßig PHP 8.x, sodass kein zusätzlicher Setup-Schritt nötig ist. PHP 7.4 oder höher ist erforderlich.
Ein v1-Hinweis: Schlüssel mit Punkten werden im PHP-Modus aufgrund der Punktnotation-Abflachungsstrategie nicht unterstützt.
- 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-Basislinie: lang/.polylingo-laravel-json-baseline.json oder lang/.polylingo-laravel-php-baseline.json je nach Format.
github.com/UsePolyLingo/translate-action-laravel — Im Marketplace ansehen
PR-Modus vs Commit-Modus
Alle drei Actions unterstützen zwei Ausgabemodi.
Commit-Modus (commit: true) schreibt die übersetzten Dateien und committet sie direkt in den aktuellen Branch. Einfache Einrichtung, gut für Teams, die Übersetzung als automatisierten Prozess ohne Review behandeln.
PR-Modus (open_pr: true) erstellt einen neuen Branch (polylingo/yaml-<sha>, polylingo/laravel-<sha> usw.), schreibt die übersetzten Dateien dort und öffnet einen Pull Request gegen Ihren Basis-Branch. Besser für Teams, die einen menschlichen Review-Schritt vor dem Merge der Übersetzungen wünschen oder für Projekte, bei denen die Übersetzungsqualität die Nutzererfahrung direkt beeinflusst.
Wenn beide gesetzt sind, gewinnt der PR-Modus.
PR-Modus benötigt pull-requests: write in Ihren Workflow-Berechtigungen:
permissions:
contents: write
pull-requests: write
Erzwingen einer vollständigen Aktualisierung
Der Delta-Modus vergleicht mit der gespeicherten Basislinie. Wenn Sie alles neu übersetzen wollen, unabhängig davon, was die Basislinie zeigt, setzen Sie delta: false. Dies aktualisiert auch die Basislinie, um der aktuellen Quelldatei zu entsprechen, sodass nachfolgende Delta-Läufe vom neuen Zustand ausgehen.
Eine vollständige Aktualisierung ist nützlich, wenn Sie eine neue Zielsprache hinzufügen, wenn Sie Verbesserungen der Übersetzungsqualität in einer neuen Modellversion übernehmen möchten oder wenn die Basislinie aus irgendeinem Grund von der Realität abgewichen ist.
- 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 # vollständige Aktualisierung, aktualisiert Basislinie
commit: true
Ausgaben für nachfolgende Schritte
Alle drei Actions geben dieselben Outputs aus, sodass Sie sie in nachfolgenden Workflow-Schritten verwenden können:
- 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: Übersetzungsstatistiken protokollieren
run: |
echo "Übersetzte Sprachen: ${{ steps.translate.outputs.locales_translated }}"
echo "Geänderte Dateien: ${{ steps.translate.outputs.files_changed }}"
echo "Verwendete Tokens: ${{ steps.translate.outputs.tokens_used }}"
Jeder Lauf schreibt außerdem eine Zusammenfassungstabelle in die GitHub Actions Schritt-Zusammenfassung, sodass Sie Tokenverbrauch und Übersetzungsergebnisse sehen können, ohne in Logs zu graben.
Erste Schritte
Alle drei Actions sind im GitHub Marketplace verfügbar. Sie benötigen einen PolyLingo API-Schlüssel, der kostenlos unter usepolylingo.com erhältlich ist. Der kostenlose Tarif umfasst 50.000 Tokens pro Monat. Mit aktiviertem Delta-Modus bleiben die meisten Projekte bei routinemäßigen Entwicklungs-Pushes gut innerhalb dieses Limits.
Fügen Sie Ihren API-Schlüssel als Repository-Geheimnis (POLYLINGO_API_KEY) hinzu und binden Sie die relevante Action in Ihren Workflow ein. Der erste Lauf führt eine vollständige Übersetzung durch und setzt die Basislinie. Jeder weitere Lauf übersetzt nur, was sich geändert hat.