From 29e03a6294edfe43b49eba20fe49099cef601d34 Mon Sep 17 00:00:00 2001 From: cihatata Date: Mon, 10 Mar 2025 23:39:32 +0300 Subject: [PATCH 1/3] feat: Sync strings from poeditor with github workfliw --- .github/scripts/download-translations.js | 92 ++++++++++++++++++++++++ .github/workflows/README.md | 41 +++++++++++ .github/workflows/poeditor-sync.yml | 92 ++++++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 .github/scripts/download-translations.js create mode 100644 .github/workflows/README.md create mode 100644 .github/workflows/poeditor-sync.yml diff --git a/.github/scripts/download-translations.js b/.github/scripts/download-translations.js new file mode 100644 index 000000000..a198ae093 --- /dev/null +++ b/.github/scripts/download-translations.js @@ -0,0 +1,92 @@ +import axios from 'axios'; +import fs from 'fs-extra'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +// Get current directory +const __filename = fileURLToPath(import.meta.url); + +// POEditor API information +const API_TOKEN = process.env.POEDITOR_API_TOKEN; +const PROJECT_ID = process.env.POEDITOR_PROJECT_ID; +const LANGUAGES = (process.env.LANGUAGES || 'tr,en').split(','); +const EXPORT_FORMAT = process.env.EXPORT_FORMAT || 'key_value_json'; + +// POEditor API endpoint +const API_URL = 'https://api.poeditor.com/v2'; + +// Function to download translations +async function downloadTranslations() { + try { + console.log('Downloading translations from POEditor...'); + console.log(`Using export format: ${EXPORT_FORMAT}`); + + for (const language of LANGUAGES) { + console.log(`Downloading translations for ${language} language...`); + + // Get export URL from POEditor + const exportResponse = await axios.post(`${API_URL}/projects/export`, + new URLSearchParams({ + api_token: API_TOKEN, + id: PROJECT_ID, + language: language, + type: EXPORT_FORMAT + }) + ); + + if (exportResponse.data.response.status !== 'success') { + throw new Error(`Failed to get export URL for ${language} language: ${JSON.stringify(exportResponse.data)}`); + } + + const fileUrl = exportResponse.data.result.url; + console.log(`Export URL obtained for ${language}`); + + // Download translation file + const downloadResponse = await axios.get(fileUrl, { responseType: 'json' }); + const translations = downloadResponse.data; + console.log(`Downloaded translations for ${language}`); + + // POEditor'den dönen veri formatını kontrol et ve gerekirse dönüştür + let formattedTranslations = translations; + + // Eğer dizi formatında geldiyse, key-value formatına dönüştür + if (Array.isArray(translations)) { + console.log(`Converting array format to key-value format for ${language}`); + formattedTranslations = {}; + translations.forEach(item => { + if (item.term && item.definition) { + formattedTranslations[item.term] = item.definition; + } + }); + } + + // Save file + const outputPath = path.join(process.cwd(), 'temp', `${language}.json`); + await fs.writeJson(outputPath, formattedTranslations, { spaces: 2 }); + + console.log(`Translations for ${language} language successfully downloaded and saved: ${outputPath}`); + } + + console.log('All translations successfully downloaded!'); + } catch (error) { + console.error('An error occurred while downloading translations:', error); + process.exit(1); + } +} + +// Main function +async function main() { + try { + // Clean temp folder + await fs.emptyDir(path.join(process.cwd(), 'temp')); + + // Download translations + await downloadTranslations(); + } catch (error) { + console.error('An error occurred during the process:', error); + process.exit(1); + } +} + +// Run script +main(); \ No newline at end of file diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 000000000..2ec6191b1 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,41 @@ +# POEditor Translation Synchronization + +This GitHub Actions workflow automatically downloads translation files from POEditor and integrates them into the project. + +## How It Works + +The workflow can be triggered in two ways: + +1. **Manual Trigger**: You can manually run the "POEditor Translation Synchronization" workflow from the "Actions" tab in the GitHub interface. +2. **Automatic Trigger**: The workflow runs automatically every day at midnight (UTC). + +## Required Settings + +For this workflow to function, you need to define the following secrets in your GitHub repository: + +1. `POEDITOR_API_TOKEN`: Your POEditor API token +2. `POEDITOR_PROJECT_ID`: Your POEditor project ID + +You can add these secrets in the "Settings > Secrets and variables > Actions" section of your GitHub repository. + +## Manual Execution + +When running the workflow manually, you can specify which languages to download. Languages should be entered as comma-separated values (e.g., `tr,gb,es`). + +If you don't specify any languages, the default languages `tr` and `gb` will be downloaded. + +## Output + +When the workflow completes successfully: + +1. Translation files for the specified languages are downloaded from POEditor +2. These files are copied to the `src/locales/` directory +3. Changes are automatically committed and pushed to the main branch + +## Troubleshooting + +If the workflow fails: + +1. Check the GitHub Actions logs +2. Make sure your POEditor API token and project ID are correct +3. Ensure that the languages you specified exist in your POEditor project diff --git a/.github/workflows/poeditor-sync.yml b/.github/workflows/poeditor-sync.yml new file mode 100644 index 000000000..e80fd478f --- /dev/null +++ b/.github/workflows/poeditor-sync.yml @@ -0,0 +1,92 @@ +name: POEditor Translation Synchronization + +on: + # For manual triggering + workflow_dispatch: + inputs: + languages: + description: "Languages to synchronize (comma separated, e.g.: tr,en,es)" + required: false + default: "tr,en" + format: + description: "Export format (key_value_json or json)" + required: false + default: "key_value_json" + + # For automatic execution at a specific time (every day at midnight) + schedule: + - cron: "0 0 * * *" + +jobs: + sync-translations: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "18" + + - name: Create package.json for scripts + run: | + mkdir -p .github/scripts + cat > .github/scripts/package.json << EOF + { + "name": "poeditor-scripts", + "version": "1.0.0", + "type": "module", + "private": true, + "dependencies": { + "axios": "^1.6.0", + "fs-extra": "^11.1.1" + } + } + EOF + + - name: Install dependencies + run: | + cd .github/scripts + npm install + + - name: Download translations from POEditor + env: + POEDITOR_API_TOKEN: ${{ secrets.POEDITOR_API_TOKEN }} + POEDITOR_PROJECT_ID: ${{ secrets.POEDITOR_PROJECT_ID }} + LANGUAGES: ${{ github.event.inputs.languages || 'tr,gb' }} + EXPORT_FORMAT: ${{ github.event.inputs.format || 'key_value_json' }} + run: | + mkdir -p temp + node .github/scripts/download-translations.js + + - name: Verify translation files + run: | + echo "Verifying translation files..." + for file in temp/*.json; do + echo "Checking $file" + if [ ! -s "$file" ]; then + echo "Error: $file is empty or does not exist" + exit 1 + fi + # Validate JSON format + cat "$file" | jq . > /dev/null || { echo "Error: $file is not valid JSON"; exit 1; } + done + echo "All translation files are valid" + + - name: Copy translations to project + run: | + mkdir -p src/locales + cp -r temp/* src/locales/ + echo "Translation files copied to src/locales/" + + - name: Commit changes + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add src/locales/*.json + git diff --staged --quiet || git commit -m "Translations updated from POEditor" + git push From 7522879e2a628d1aa9a98af620afbdd959c0a232 Mon Sep 17 00:00:00 2001 From: cihatata Date: Mon, 10 Mar 2025 23:41:33 +0300 Subject: [PATCH 2/3] fix: key --- .github/scripts/download-translations.js | 2 +- .github/workflows/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/download-translations.js b/.github/scripts/download-translations.js index a198ae093..94975de0c 100644 --- a/.github/scripts/download-translations.js +++ b/.github/scripts/download-translations.js @@ -7,7 +7,7 @@ import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); // POEditor API information -const API_TOKEN = process.env.POEDITOR_API_TOKEN; +const API_TOKEN = process.env.POEDITOR_API; const PROJECT_ID = process.env.POEDITOR_PROJECT_ID; const LANGUAGES = (process.env.LANGUAGES || 'tr,en').split(','); const EXPORT_FORMAT = process.env.EXPORT_FORMAT || 'key_value_json'; diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 2ec6191b1..11b04d657 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -22,7 +22,7 @@ You can add these secrets in the "Settings > Secrets and variables > Actions" se When running the workflow manually, you can specify which languages to download. Languages should be entered as comma-separated values (e.g., `tr,gb,es`). -If you don't specify any languages, the default languages `tr` and `gb` will be downloaded. +If you don't specify any languages, the default languages `tr` and `en` will be downloaded. ## Output From c50b45f9ecf86b878188606d51a961277b57ae26 Mon Sep 17 00:00:00 2001 From: cihatata Date: Mon, 10 Mar 2025 23:46:26 +0300 Subject: [PATCH 3/3] fix: strings --- .github/scripts/download-translations.js | 4 ++-- .github/workflows/poeditor-sync.yml | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/scripts/download-translations.js b/.github/scripts/download-translations.js index 94975de0c..8eb3fd69f 100644 --- a/.github/scripts/download-translations.js +++ b/.github/scripts/download-translations.js @@ -46,10 +46,10 @@ async function downloadTranslations() { const translations = downloadResponse.data; console.log(`Downloaded translations for ${language}`); - // POEditor'den dönen veri formatını kontrol et ve gerekirse dönüştür + // Check the format of data returned from POEditor and convert if necessary let formattedTranslations = translations; - // Eğer dizi formatında geldiyse, key-value formatına dönüştür + // If data is in array format, convert it to key-value format if (Array.isArray(translations)) { console.log(`Converting array format to key-value format for ${language}`); formattedTranslations = {}; diff --git a/.github/workflows/poeditor-sync.yml b/.github/workflows/poeditor-sync.yml index e80fd478f..876ab811b 100644 --- a/.github/workflows/poeditor-sync.yml +++ b/.github/workflows/poeditor-sync.yml @@ -39,7 +39,6 @@ jobs: { "name": "poeditor-scripts", "version": "1.0.0", - "type": "module", "private": true, "dependencies": { "axios": "^1.6.0", @@ -57,7 +56,7 @@ jobs: env: POEDITOR_API_TOKEN: ${{ secrets.POEDITOR_API_TOKEN }} POEDITOR_PROJECT_ID: ${{ secrets.POEDITOR_PROJECT_ID }} - LANGUAGES: ${{ github.event.inputs.languages || 'tr,gb' }} + LANGUAGES: ${{ github.event.inputs.languages || 'tr,en' }} EXPORT_FORMAT: ${{ github.event.inputs.format || 'key_value_json' }} run: | mkdir -p temp