ΛειτουργίεςPluginΤιμολόγησηΠόροι
Αλλαγή γλώσσας
ΠόροιΠώς να αυτοματοποιήσετε τη μετάφραση .po στο CI/CD Pipeline σας

Πώς να αυτοματοποιήσετε τη μετάφραση .po στο CI/CD Pipeline σας

SimplePoTranslate Team9 Ιουνίου 2026
Πώς να αυτοματοποιήσετε τη μετάφραση .po στο CI/CD Pipeline σας

Η ομάδα σας κάνει merges στο main δεκατέσσερις φορές την ημέρα. Κάθε ένα από αυτά τα merges μπορεί να προσθέσει μια νέα συμβολοσειρά που βλέπει ο χρήστης – μια ετικέτα κουμπιού, ένα μήνυμα σφάλματος, μια επεξήγηση. Και κάθε μία από αυτές τις συμβολοσειρές ξεκινάει τη ζωή της μόνο στα Αγγλικά. Κάπου στη διαδικασία κυκλοφορίας σας, ένας άνθρωπος πρέπει να παρατηρήσει τις νέες συμβολοσειρές, να τις εξάγει, να τις μεταφράσει, να τις επικολλήσει πίσω και να τις μεταγλωττίσει ξανά. Αυτός ο άνθρωπος αποτελεί ένα «σημείο συμφόρησης», και σε μια ομάδα που κυκλοφορεί γρήγορα προϊόντα, αυτό το σημείο συμφόρησης σημαίνει ότι οι Γερμανοί χρήστες σας βλέπουν αγγλικούς placeholders για δύο sprints.

Η λύση είναι να αυτοματοποιήσετε τη μετάφραση στο CI/CD pipeline σας, έτσι ώστε οι νέες συμβολοσειρές να μεταφράζονται με το ίδιο merge που τις εισήγαγε – χωρίς ανθρώπινο παράγοντα στην κρίσιμη διαδρομή για τις τυπικές περιπτώσεις. Αυτό είναι απόλυτα εφικτό σήμερα, αλλά μόνο αν αποφύγετε την παγίδα στην οποία πέφτουν οι περισσότερες ομάδες: τη χειροκίνητη δημιουργία απλών κλήσεων LLM που καταστρέφουν αθόρυβα τους %s placeholders σας και τη δομή .po. Αυτός ο οδηγός περιγράφει ένα ρεαλιστικό μοτίβο CI pipeline, ένα λειτουργικό σκελετό GitHub Actions και τις αποφάσεις σχεδιασμού – ιδιοδυναμία, μετάφραση μόνο νέων, πύλες αναθεώρησης – που ξεχωρίζουν ένα pipeline που βοηθά από ένα που δημιουργεί προβληματικά builds.

Γιατί η χειροκίνητη μετάφραση αποτελεί σημείο συμφόρησης στην κυκλοφορία

Η απάντηση στο «γιατί να μην μεταφράζουμε απλώς πριν από κάθε κυκλοφορία» είναι ότι ο συγχρονισμός δεν ταιριάζει ποτέ. Οι συμβολοσειρές προστίθενται συνεχώς από τους προγραμματιστές, αλλά η μετάφραση γίνεται σε παρτίδες από διαφορετικό άτομο, με διαφορετικό χρονοδιάγραμμα. Το κενό μεταξύ αυτών των δύο ρυθμών είναι εκεί που συσσωρεύεται το χρέος τοπικοποίησης.

Το πρόβλημα των δύο ρυθμών

Φανταστείτε τη χειροκίνητη ροή. Ένας προγραμματιστής προσθέτει __( 'Export to CSV', 'mytextdomain' ) και κάνει merge. Κανείς δεν αναδημιουργεί το .pot. Δύο εβδομάδες αργότερα κάποιος εκτελεί το wp i18n make-pot, παρατηρεί σαράντα νέες αμετάφραστες συμβολοσειρές (μερικές από προγραμματιστές που έχουν φύγει για διακοπές), μαντεύει την πρόθεση των μισών και στέλνει ένα αρχείο .po σε μεταφραστή. Η μετάφραση επιστρέφει, επικολλάται, και ίσως οι placeholders να επιβίωσαν ή ίσως όχι. Εν τω μεταξύ, τρεις εκδόσεις κυκλοφόρησαν με αυτές τις συμβολοσειρές στα Αγγλικά.

Κάθε βήμα εκεί είναι χειροκίνητο, γίνεται σε παρτίδες και είναι επιρρεπές σε σφάλματα. Ο στόχος της αυτοματοποίησης CI/CD είναι να συμπτύξει αυτή τη διαδικασία σε κάτι που εκτελείται αυτόματα κατά το merge, μεταφράζει μόνο ό,τι πραγματικά άλλαξε και αποτυγχάνει ηχηρά όταν κάτι φαίνεται λάθος – μετατρέποντας τη μετάφραση από μια περιοδική αγγαρεία σε ένα αόρατο μέρος του pipeline.

Το μοτίβο του Pipeline: Εξαγωγή, Διάκριση, Μετάφραση, Δέσμευση

Σε γενικές γραμμές, μια αυτοματοποιημένη εργασία μετάφρασης εκτελεί τέσσερα βήματα κατά το merge στο main: αναδημιουργεί το πρότυπο, εντοπίζει τι είναι καινούργιο, μεταφράζει μόνο αυτές τις συμβολοσειρές και δεσμεύει τα αποτελέσματα πίσω. Όλη η διαδικασία πρέπει να είναι ιδιοδύναμη – η εκτέλεσή της σε ένα merge χωρίς αλλαγές συμβολοσειρών πρέπει να παράγει μηδενικό diff και μηδενικό «θόρυβο».

Εξαγωγή και Διάκριση

Το πρώτο βήμα είναι η εξαγωγή. Αναδημιουργήστε το αρχείο .pot από την τρέχουσα πηγή ώστε να αντικατοπτρίζει κάθε συμβολοσειρά στη βάση κώδικα:

wp i18n make-pot . languages/myplugin.pot

Το δεύτερο βήμα είναι το diff. Αυτή είναι η πιο σημαντική σχεδιαστική απόφαση σε ολόκληρο το pipeline. Δεν θέλετε να μεταφράζετε ξανά κάθε συμβολοσειρά σε κάθε merge – αυτό σπαταλά κλήσεις API, κινδυνεύει να μεταφράσει ξανά συμβολοσειρές που έχει ήδη διορθώσει ένας άνθρωπος και παράγει τεράστια review diffs. Αντίθετα, συγχωνεύετε το φρέσκο .pot σε κάθε υπάρχον .po και μεταφράζετε μόνο τις καταχωρίσεις που είναι πλέον κενές (τις πραγματικά νέες συμβολοσειρές):

# Merge new template into each locale, preserving existing translations.
# Newly-added strings appear with empty msgstr; --backup=none keeps the tree clean.
for po in languages/*.po; do
    msgmerge --update --backup=none "$po" languages/myplugin.pot
done

Μετά το msgmerge, μόνο οι ολοκαίνουργιες συμβολοσειρές έχουν ένα κενό msgstr. Όλα τα προηγουμένως μεταφρασμένα παραμένουν ανέγγιχτα. Αυτή η ιδιότητα είναι που καθιστά το pipeline ιδιοδύναμο και που διατηρεί τα review diffs σας μικρά και αναθεωρήσιμα.

Μετάφραση και Δέσμευση

Το τρίτο βήμα στέλνει μόνο αυτές τις κενές καταχωρίσεις σε ένα βήμα μετάφρασης. Το τέταρτο βήμα δεσμεύει το ενημερωμένο .po, μεταγλωττίζει το .mo και αναδημιουργεί οποιοδήποτε JSON. Όλα αυτά θα τα ενσωματώσουμε στο GitHub Actions στη συνέχεια.

Ένας σκελετός GitHub Actions

Εδώ είναι η απάντηση στο «πώς μοιάζει αυτό στην πραγματικότητα σε ένα αρχείο workflow»: μια εργασία που ενεργοποιείται κατά το push στο main και εκτελεί τον κύκλο εξαγωγής-διάκρισης-μετάφρασης-δέσμευσης και ανοίγει ένα pull request με τα αποτελέσματα αντί να δεσμεύει απευθείας στο main.

Το αρχείο Workflow

name: Translate on merge

on:
  push:
    branches: [ main ]

jobs:
  translate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install WP-CLI and gettext
        run: |
          sudo apt-get update && sudo apt-get install -y gettext
          curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
          sudo mv wp-cli.phar /usr/local/bin/wp && sudo chmod +x /usr/local/bin/wp

      - name: Regenerate template and merge into locales
        run: |
          wp i18n make-pot . languages/myplugin.pot
          for po in languages/*.po; do
            msgmerge --update --backup=none "$po" languages/myplugin.pot
          done

      - name: Translate only new (empty) strings
        env:
          TRANSLATE_API_KEY: ${{ secrets.TRANSLATE_API_KEY }}
        run: ./scripts/translate-new-strings.sh languages/

      - name: Compile .mo and JSON
        run: |
          wp i18n make-mo languages/
          wp i18n make-json languages/ --no-purge

      - name: Open pull request with translations
        uses: peter-evans/create-pull-request@v6
        with:
          branch: chore/auto-translations
          title: "chore: auto-translate new strings"
          commit-message: "chore: auto-translate new strings"

Πού κρύβεται η πραγματική δουλειά

Το βήμα translate-new-strings.sh είναι εκεί όπου γίνεται η πραγματική μετάφραση. Η αφελής έκδοση αυτού του script διαβάζει κάθε κενή καταχώριση, την στέλνει σε ένα LLM API μία συμβολοσειρά τη φορά και επικολλά την απάντηση πίσω. Αυτή η αφελής έκδοση είναι ακριβώς η παγίδα, και αξίζει να είμαστε σαφείς ως προς το γιατί.

Γιατί οι χειροποίητες κλήσεις LLM καταστρέφουν τα αρχεία σας

Η σύντομη απάντηση: οι απλές κλήσεις LLM αντιμετωπίζουν τις συμβολοσειρές .po ως πεζό λόγο, και οι συμβολοσειρές .po δεν είναι πεζός λόγος – είναι δομημένα δεδομένα με placeholders, πληθυντικούς τύπους και περιεχόμενο που μια κλήση chat-completion καταστρέφει ευχαρίστως.

Η καταστροφή των Placeholder που δεν θα δείτε στα Tests

Στείλτε το Deleted %d of %s files σε ένα γενικό chat endpoint και μπορεί να λάβετε πίσω Supprimé %d des %s fichiers (εντάξει) ή Supprimé %d de % s fichiers (μια κενή θέση μπήκε στον placeholder, και τώρα το sprintf() εμφανίζει σφάλμα κατά την εκτέλεση). Στείλτε μια πληθυντική καταχώριση και το μοντέλο μπορεί να συμπτύξει δύο μορφές σε μία, καταστρέφοντας γλώσσες με περισσότερες από δύο πληθυντικές κατηγορίες. Στείλτε μια συμβολοσειρά με <a href="%s"> και το μοντέλο μπορεί να μεταφράσει τη διεύθυνση URL ή να αφαιρέσει την ετικέδα. Καμία από αυτές τις αστοχίες δεν εμφανίζεται στα tests σας, εκτός αν δοκιμάσετε ειδικά την αποδοθείσα έξοδο σε κάθε locale – εμφανίζονται ως σφάλματα χρόνου εκτέλεσης στην παραγωγή για χρήστες από τους οποίους δεν μπορείτε να διαβάσετε αναφορές σφαλμάτων.

Η παγίδα της συντήρησης

Μπορείτε να προσπαθήσετε να αμυνθείτε ενάντια σε αυτό με prompt engineering και regex post-processing, και πολλές ομάδες το κάνουν. Το πρόβλημα είναι ότι τώρα συντηρείτε μια εύθραυστη μηχανή μετάφρασης ως παράπλευρο έργο, ανακαλύπτοντας ξανά κάθε οριακή περίπτωση placeholder που έχει ήδη λύσει το οικοσύστημα Gettext. Καταγράφουμε τους συγκεκριμένους τρόπους με τους οποίους παραμορφώνονται οι μεταβλητές – και πώς να τις αποτρέψετε – στο μετάφραση αρχείων PO χωρίς να καταστρέφονται οι μεταβλητές κώδικα. Το μάθημα εκεί ισχύει άμεσα: η ποιότητα του μοντέλου σπάνια είναι το ζήτημα· η δομική διαχείριση γύρω από αυτό είναι.

Ενσωμάτωση ενός Cloud Translator με API στο CI

Εδώ είναι που μια υπηρεσία μετάφρασης που βασίζεται σε API αντικαθιστά τις εικασίες του translate-new-strings.sh. Αντί να δημιουργείτε χειροκίνητα κλήσεις LLM και regex μετα-επεξεργασίας, το βήμα CI σας ανεβάζει το αλλαγμένο .po σε μια υπηρεσία που κατανοεί ήδη τη δομή Gettext και επιστρέφει καθαρή έξοδο. Το σχήμα του pipeline παραμένει ίδιο – εξαγωγή, διάκριση, μετάφραση, δέσμευση – αλλά το εύθραυστο ενδιάμεσο βήμα γίνεται μια ενιαία κλήση API.

Η κλήση API που αντικαθιστά το Script σας

Το SimplePoTranslate είναι φτιαγμένο ακριβώς για αυτό. Εκθέτει ένα cloud API κατάλληλο για αυτοματοποίηση και CI, έτσι το βήμα μετάφρασης του workflow σας γίνεται μια αίτηση που παραδίδει το .po και λαμβάνει πίσω ένα μεταφρασμένο, χωρίς επαναλήψεις ανά συμβολοσειρά. Το Syntax Locking του διατηρεί τους %s, %1$s, {count}, HTML και tokens κώδικα στη θέση τους αυτόματα – ολόκληρη η κατηγορία σφαλμάτων από την προηγούμενη ενότητα αντιμετωπίζεται από τον μηχανισμό και όχι από regex που συντηρείτε. Με πλήρη υποστήριξη Gettext plural και msgctxt, οι πληθυντικοί τύποι και το context επιβιώνουν από την αμφίδρομη επικοινωνία, κάτι που μια κλήση chat-completion δεν μπορεί να εγγυηθεί.

Η ιδιοδυναμία και η πύλη αναθεώρησης παραμένουν δικές σας

Δύο σχεδιαστικές αποφάσεις εξακολουθούν να ανήκουν σε εσάς, ανεξάρτητα από το ποιον μηχανισμό χρησιμοποιείτε. Πρώτον, η ιδιοδυναμία: συνεχίστε να μεταφράζετε μόνο τις κενές καταχωρίσεις μετά το msgmerge, ώστε τα no-op merges να μην παράγουν diff. Δεύτερον, μια πύλη αναθεώρησης: αφήστε την εργασία να ανοίξει ένα pull request, όπως κάνει ο παραπάνω σκελετός, αντί να δεσμεύει απευθείας στο main. Η αυτόματη μετάφραση είναι εξαιρετική για να εμφανίζονται οι συμβολοσειρές γρήγορα, αλλά μια ανθρώπινη ματιά πριν από το merge εντοπίζει τη σπάνια παράλειψη περιεχομένου – και ένα PR σας προσφέρει αυτή τη ματιά χωρίς να μπλοκάρει τη συνήθη περίπτωση. Οι ομάδες που διαχειρίζονται πολλά locales ή πολλούς ιστότοπους πελατών θα αναγνωρίσουν αυτό το σχήμα από την ιδανική ροή εργασίας τοπικοποίησης για πρακτορεία, όπου το ίδιο μοτίβο αυτοματοποίησης-μετά-αναθεώρησης κλιμακώνεται σε δεκάδες έργα.

Συμπέρασμα

Για να αυτοματοποιήσετε τη μετάφραση στο CI/CD χωρίς να κυκλοφορείτε προβληματικά builds, το μοτίβο είναι συνεπές: αναδημιουργήστε το .pot κατά το merge, msgmerge το σε κάθε locale για να εμφανιστούν μόνο οι νέες συμβολοσειρές, μεταφράστε μόνο αυτές τις συμβολοσειρές και δεσμεύστε το αποτέλεσμα πίσω από μια πύλη αναθεώρησης pull-request. Η ιδιοδυναμία διατηρεί τα diffs σας καθαρά· η πύλη αναθεώρησης κρατά τη σπάνια κακή μετάφραση εκτός παραγωγής.

Το μέρος που πρέπει να γίνει σωστά είναι το ίδιο το βήμα της μετάφρασης. Οι χειροποίητες κλήσεις LLM θα καταστρέψουν τους placeholders και τους πληθυντικούς τύπους με τρόπους που τα tests σας δεν θα εντοπίσουν, και θα αφιερώσετε περισσότερο χρόνο στη συντήρηση της μεταφραστικής «κόλλας» παρά στον κώδικα των λειτουργιών που εξυπηρετεί. Ένας μηχανισμός βασισμένος σε API με Syntax Locking αφαιρεί ολόκληρο αυτόν τον τρόπο αποτυχίας, ώστε το pipeline σας να μεταφράζει νέες συμβολοσειρές με το ίδιο merge που τις εισήγαγε – και οι μη-Αγγλόφωνοι χρήστες σας να σταματήσουν να βλέπουν αγγλικούς placeholders.

Είστε έτοιμοι να αυτοματοποιήσετε τη μετάφραση στο pipeline σας χωρίς να καταστρέψετε τους placeholders; Δοκιμάστε το SimplePoTranslate δωρεάν — δεν απαιτείται πιστωτική κάρτα. Ξεκινήστε με τη δωρεάν βαθμίδα, επικυρώστε το API έναντι των δικών σας αρχείων .po και ενσωματώστε το στο CI όταν είστε έτοιμοι.

Μοιραστείτε αυτό το άρθρο