name: POEditor Diff & Sync on: push: branches: [ master ] workflow_dispatch: {} concurrency: group: poeditor-sync cancel-in-progress: false jobs: sync-translations: runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v4 with: python-version: '3.x' - name: Install jq run: sudo apt-get update && sudo apt-get install -y jq - name: Extract source strings from codebase env: API_TOKEN: ${{ secrets.POEDITOR_API_TOKEN }} PROJECT_ID: ${{ secrets.POEDITOR_PROJECT_ID }} run: | set -euo pipefail echo "::group::Extracting strings from QML files" python3 translations/extract_translations.py echo "::endgroup::" echo "::group::Checking for changes in en.json" if [[ -f "translations/en.json" ]]; then jq -S . "translations/en.json" > /tmp/en_new.json if [[ -f "translations/en.json.orig" ]]; then jq -S . "translations/en.json.orig" > /tmp/en_old.json else git show HEAD:translations/en.json > /tmp/en_old.json 2>/dev/null || echo "[]" > /tmp/en_old.json jq -S . /tmp/en_old.json > /tmp/en_old.json.tmp && mv /tmp/en_old.json.tmp /tmp/en_old.json fi if diff -q /tmp/en_new.json /tmp/en_old.json >/dev/null 2>&1; then echo "No changes in source strings" echo "source_changed=false" >> "$GITHUB_OUTPUT" else echo "Detected changes in source strings" echo "source_changed=true" >> "$GITHUB_OUTPUT" echo "::group::Uploading source strings to POEditor" RESP=$(curl -sS -X POST https://api.poeditor.com/v2/projects/upload \ -F api_token="$API_TOKEN" \ -F id="$PROJECT_ID" \ -F updating="terms" \ -F file=@"translations/en.json") STATUS=$(echo "$RESP" | jq -r '.response.status') if [[ "$STATUS" != "success" ]]; then echo "::warning::POEditor upload failed: $RESP" else TERMS_ADDED=$(echo "$RESP" | jq -r '.result.terms.added // 0') TERMS_UPDATED=$(echo "$RESP" | jq -r '.result.terms.updated // 0') TERMS_DELETED=$(echo "$RESP" | jq -r '.result.terms.deleted // 0') echo "Terms added: $TERMS_ADDED, updated: $TERMS_UPDATED, deleted: $TERMS_DELETED" fi echo "::endgroup::" fi else echo "::warning::translations/en.json not found" echo "source_changed=false" >> "$GITHUB_OUTPUT" fi echo "::endgroup::" id: extract - name: Commit and push source strings if: steps.extract.outputs.source_changed == 'true' run: | set -euo pipefail git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add translations/en.json translations/template.json git commit -m "i18n: update source strings from codebase" for attempt in 1 2 3; do if git push; then echo "Successfully pushed source string updates" exit 0 fi echo "Push attempt $attempt failed, pulling and retrying..." git pull --rebase sleep $((attempt*2)) done echo "Failed to push after retries" >&2 exit 1 - name: Export and update translations from POEditor env: API_TOKEN: ${{ secrets.POEDITOR_API_TOKEN }} PROJECT_ID: ${{ secrets.POEDITOR_PROJECT_ID }} run: | set -euo pipefail LANGUAGES=( "ja:translations/poexports/ja.json" "zh-Hans:translations/poexports/zh_CN.json" "zh-Hant:translations/poexports/zh_TW.json" "pt-br:translations/poexports/pt.json" "tr:translations/poexports/tr.json" "it:translations/poexports/it.json" ) ANY_CHANGED=false for lang_pair in "${LANGUAGES[@]}"; do IFS=':' read -r PO_LANG REPO_FILE <<< "$lang_pair" echo "::group::Processing $PO_LANG" RESP=$(curl -sS -X POST https://api.poeditor.com/v2/projects/export \ -d api_token="$API_TOKEN" \ -d id="$PROJECT_ID" \ -d language="$PO_LANG" \ -d type="key_value_json") STATUS=$(echo "$RESP" | jq -r '.response.status') if [[ "$STATUS" != "success" ]]; then echo "POEditor export request failed for $PO_LANG: $RESP" >&2 continue fi URL=$(echo "$RESP" | jq -r '.result.url') if [[ -z "$URL" || "$URL" == "null" ]]; then echo "No export URL returned for $PO_LANG" >&2 continue fi curl -sS -L "$URL" -o "/tmp/po_export_${PO_LANG}.json" jq -S . "/tmp/po_export_${PO_LANG}.json" > "/tmp/po_export_${PO_LANG}.norm.json" if [[ -f "$REPO_FILE" ]]; then jq -S . "$REPO_FILE" > "/tmp/repo_${PO_LANG}.norm.json" || echo "{}" > "/tmp/repo_${PO_LANG}.norm.json" else echo "{}" > "/tmp/repo_${PO_LANG}.norm.json" fi if diff -q "/tmp/po_export_${PO_LANG}.norm.json" "/tmp/repo_${PO_LANG}.norm.json" >/dev/null; then echo "No changes for $PO_LANG" else echo "Detected changes for $PO_LANG" mkdir -p "$(dirname "$REPO_FILE")" cp "/tmp/po_export_${PO_LANG}.norm.json" "$REPO_FILE" ANY_CHANGED=true fi echo "::endgroup::" done echo "any_changed=$ANY_CHANGED" >> "$GITHUB_OUTPUT" id: export - name: Commit and push translation updates if: steps.export.outputs.any_changed == 'true' run: | set -euo pipefail git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add translations/poexports/*.json git commit -m "i18n: update translations" for attempt in 1 2 3; do if git push; then echo "Successfully pushed translation updates" exit 0 fi echo "Push attempt $attempt failed, pulling and retrying..." git pull --rebase sleep $((attempt*2)) done echo "Failed to push after retries" >&2 exit 1