From c29d2c7decbe5ec0be31d99d9d17345afc256166 Mon Sep 17 00:00:00 2001 From: itsneufox <156133096+itsneufox@users.noreply.github.com> Date: Sat, 20 Dec 2025 02:45:09 +0000 Subject: [PATCH 1/3] Add workflow to mark translations as potentially outdated --- .../workflows/mark-translations-outdated.yml | 109 +++++++++++++++ .../scripts/mark-translations-outdated.js | 127 ++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 .github/workflows/mark-translations-outdated.yml create mode 100644 .github/workflows/scripts/mark-translations-outdated.js diff --git a/.github/workflows/mark-translations-outdated.yml b/.github/workflows/mark-translations-outdated.yml new file mode 100644 index 00000000000..91965119663 --- /dev/null +++ b/.github/workflows/mark-translations-outdated.yml @@ -0,0 +1,109 @@ +name: Mark Translations as Potentially Outdated + +on: + pull_request: + paths: + - 'frontend/docs/**/*.md' + +permissions: + contents: write + pull-requests: write + +jobs: + mark-outdated: + name: Mark translations outdated + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.head_ref }} + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Get changed English documentation files + id: changed-files + run: | + git fetch origin ${{ github.base_ref }} + CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep "^frontend/docs/.*\.md$" || echo "") + + if [ -z "$CHANGED_FILES" ]; then + echo "has_changes=false" >> $GITHUB_OUTPUT + else + echo "$CHANGED_FILES" > changed_english_docs.txt + echo "has_changes=true" >> $GITHUB_OUTPUT + fi + + - name: Mark translations as outdated + if: steps.changed-files.outputs.has_changes == 'true' + run: | + node .github/workflows/scripts/mark-translations-outdated.js + + - name: Check if translations were modified + if: steps.changed-files.outputs.has_changes == 'true' + id: check-changes + run: | + if [ -n "$(git status --porcelain)" ]; then + echo "translations_modified=true" >> $GITHUB_OUTPUT + else + echo "translations_modified=false" >> $GITHUB_OUTPUT + fi + + - name: Commit changes + if: steps.check-changes.outputs.translations_modified == 'true' + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add frontend/i18n/ + git commit -m "Mark translations as potentially outdated" + + - name: Push changes + if: steps.check-changes.outputs.translations_modified == 'true' + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.head_ref }} + + - name: Comment on PR + if: steps.check-changes.outputs.translations_modified == 'true' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const changedFiles = fs.readFileSync('changed_english_docs.txt', 'utf8').trim().split('\n'); + const fileList = changedFiles.map(f => `- \`${f}\``).join('\n'); + + let markedFilesList = ''; + if (fs.existsSync('marked_translation_files.txt')) { + const markedFiles = fs.readFileSync('marked_translation_files.txt', 'utf8').trim().split('\n'); + if (markedFiles.length > 0) { + const markedCount = markedFiles.length; + const displayFiles = markedFiles.slice(0, 20); + markedFilesList = '\n\n### Marked Translation Files\n\n'; + markedFilesList += displayFiles.map(f => `- \`${f}\``).join('\n'); + if (markedCount > 20) { + markedFilesList += `\n\n*...and ${markedCount - 20} more files*`; + } + } + } + + const body = `## 🌐 Translation Update Notice + +The following English documentation files were modified in this PR: + +${fileList} + +The corresponding translation files have been automatically marked as potentially outdated in this PR branch. Translators should review these changes and update translations accordingly.${markedFilesList}`; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: body + }); diff --git a/.github/workflows/scripts/mark-translations-outdated.js b/.github/workflows/scripts/mark-translations-outdated.js new file mode 100644 index 00000000000..8a7e0f47ea5 --- /dev/null +++ b/.github/workflows/scripts/mark-translations-outdated.js @@ -0,0 +1,127 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +const WARNING_BANNERS = { + 'es': `:::warning La traducción puede estar desactualizada +La versión en inglés de este documento se actualizó recientemente. Es posible que esta traducción aún no refleje esos cambios. + +¡Ayuda a mantener nuestras traducciones actualizadas! Si hablas este idioma con fluidez, considera revisar la [versión en inglés](ENGLISH_DOC_LINK) y actualizar esta traducción. +::: + +`, + 'pt-BR': `:::warning A tradução pode estar desatualizada +A versão em inglês deste documento foi atualizada recentemente. Esta tradução pode não refletir essas alterações ainda. + +Ajude-nos a manter nossas traduções atualizadas! Se você é fluente neste idioma, considere revisar a [versão em inglês](ENGLISH_DOC_LINK) e atualizar esta tradução. +::: + +`, +}; + +const DEFAULT_WARNING = `:::warning Translation May Be Outdated +The English version of this document was recently updated. This translation may not reflect those changes yet. + +Please help keep our translations up to date! If you're fluent in this language, consider reviewing the [English version](ENGLISH_DOC_LINK) and updating this translation. +::: + +`; + +const WARNING_MARKER = ':::warning'; + +const changedFilesPath = path.join(process.cwd(), 'changed_english_docs.txt'); +if (!fs.existsSync(changedFilesPath)) { + console.log('No changed English docs file found'); + process.exit(0); +} + +const changedEnglishDocs = fs.readFileSync(changedFilesPath, 'utf8') + .trim() + .split('\n') + .filter(line => line.trim().length > 0); + +if (changedEnglishDocs.length === 0) { + console.log('No changed English docs to process'); + process.exit(0); +} + +const i18nDir = path.join(process.cwd(), 'frontend', 'i18n'); +if (!fs.existsSync(i18nDir)) { + console.log('No i18n directory found'); + process.exit(0); +} + +const languages = fs.readdirSync(i18nDir).filter(item => { + const itemPath = path.join(i18nDir, item); + return fs.statSync(itemPath).isDirectory(); +}); + +console.log(`Found ${languages.length} language directories: ${languages.join(', ')}`); + +let totalFilesMarked = 0; +const markedFiles = []; + +changedEnglishDocs.forEach(englishDocPath => { + const relativePath = englishDocPath.replace('frontend/docs/', ''); + const englishDocLink = `/docs/${relativePath.replace('.md', '')}`; + + console.log(`\nProcessing: ${englishDocPath}`); + console.log(` Relative path: ${relativePath}`); + + languages.forEach(lang => { + const translationPath = path.join( + i18nDir, + lang, + 'docusaurus-plugin-content-docs', + 'current', + relativePath + ); + + if (!fs.existsSync(translationPath)) { + console.log(` [${lang}] Translation does not exist, skipping`); + return; + } + + let content = fs.readFileSync(translationPath, 'utf8'); + + if (content.includes(WARNING_MARKER)) { + console.log(` [${lang}] Already has outdated warning, skipping`); + return; + } + + let frontmatterEnd = 0; + if (content.startsWith('---')) { + const secondDelimiter = content.indexOf('---', 3); + if (secondDelimiter !== -1) { + frontmatterEnd = secondDelimiter + 3; + } + } + + const warningBanner = WARNING_BANNERS[lang] || DEFAULT_WARNING; + const warningWithLink = warningBanner.replace('ENGLISH_DOC_LINK', englishDocLink); + + let updatedContent; + if (frontmatterEnd > 0) { + const frontmatter = content.substring(0, frontmatterEnd); + const restOfContent = content.substring(frontmatterEnd).trimStart(); + updatedContent = `${frontmatter}\n\n${warningWithLink}${restOfContent}`; + } else { + const restOfContent = content.trimStart(); + updatedContent = `${warningWithLink}${restOfContent}`; + } + + fs.writeFileSync(translationPath, updatedContent, 'utf8'); + console.log(` [${lang}] ✓ Marked as outdated`); + totalFilesMarked++; + markedFiles.push(translationPath.replace(process.cwd() + path.sep, '').replace(/\\/g, '/')); + }); +}); + +console.log(`\n✅ Total files marked: ${totalFilesMarked}`); + +if (markedFiles.length > 0) { + const markedFilesPath = path.join(process.cwd(), 'marked_translation_files.txt'); + fs.writeFileSync(markedFilesPath, markedFiles.join('\n'), 'utf8'); + console.log(`Marked files list written to: ${markedFilesPath}`); +} From 374937d4bc741d8e8c8d6aa312ec9613f49a75ff Mon Sep 17 00:00:00 2001 From: itsneufox <156133096+itsneufox@users.noreply.github.com> Date: Sat, 20 Dec 2025 02:47:53 +0000 Subject: [PATCH 2/3] fix the YAML syntax error --- .github/workflows/mark-translations-outdated.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/mark-translations-outdated.yml b/.github/workflows/mark-translations-outdated.yml index 91965119663..daa656d71df 100644 --- a/.github/workflows/mark-translations-outdated.yml +++ b/.github/workflows/mark-translations-outdated.yml @@ -77,7 +77,7 @@ jobs: script: | const fs = require('fs'); const changedFiles = fs.readFileSync('changed_english_docs.txt', 'utf8').trim().split('\n'); - const fileList = changedFiles.map(f => `- \`${f}\``).join('\n'); + const fileList = changedFiles.map(f => `- \`${ f }\``).join('\n'); let markedFilesList = ''; if (fs.existsSync('marked_translation_files.txt')) { @@ -86,20 +86,20 @@ jobs: const markedCount = markedFiles.length; const displayFiles = markedFiles.slice(0, 20); markedFilesList = '\n\n### Marked Translation Files\n\n'; - markedFilesList += displayFiles.map(f => `- \`${f}\``).join('\n'); + markedFilesList += displayFiles.map(f => `- \`${ f }\``).join('\n'); if (markedCount > 20) { - markedFilesList += `\n\n*...and ${markedCount - 20} more files*`; + markedFilesList += `\n\n*...and ${ markedCount - 20 } more files*`; } } } const body = `## 🌐 Translation Update Notice -The following English documentation files were modified in this PR: + The following English documentation files were modified in this PR: -${fileList} + ${ fileList } -The corresponding translation files have been automatically marked as potentially outdated in this PR branch. Translators should review these changes and update translations accordingly.${markedFilesList}`; + The corresponding translation files have been automatically marked as potentially outdated in this PR branch. Translators should review these changes and update translations accordingly.${ markedFilesList }`; github.rest.issues.createComment({ issue_number: context.issue.number, From 335eb3d4d2cd8d4f20f5a3be4c77ca7827655426 Mon Sep 17 00:00:00 2001 From: itsneufox <156133096+itsneufox@users.noreply.github.com> Date: Sat, 20 Dec 2025 02:50:14 +0000 Subject: [PATCH 3/3] Refactor comment body construction for translation updates --- .../workflows/mark-translations-outdated.yml | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/workflows/mark-translations-outdated.yml b/.github/workflows/mark-translations-outdated.yml index daa656d71df..e269bb99005 100644 --- a/.github/workflows/mark-translations-outdated.yml +++ b/.github/workflows/mark-translations-outdated.yml @@ -77,7 +77,7 @@ jobs: script: | const fs = require('fs'); const changedFiles = fs.readFileSync('changed_english_docs.txt', 'utf8').trim().split('\n'); - const fileList = changedFiles.map(f => `- \`${ f }\``).join('\n'); + const fileList = changedFiles.map(f => '- `' + f + '`').join('\n'); let markedFilesList = ''; if (fs.existsSync('marked_translation_files.txt')) { @@ -86,20 +86,18 @@ jobs: const markedCount = markedFiles.length; const displayFiles = markedFiles.slice(0, 20); markedFilesList = '\n\n### Marked Translation Files\n\n'; - markedFilesList += displayFiles.map(f => `- \`${ f }\``).join('\n'); + markedFilesList += displayFiles.map(f => '- `' + f + '`').join('\n'); if (markedCount > 20) { - markedFilesList += `\n\n*...and ${ markedCount - 20 } more files*`; + markedFilesList += '\n\n*...and ' + (markedCount - 20) + ' more files*'; } } } - const body = `## 🌐 Translation Update Notice - - The following English documentation files were modified in this PR: - - ${ fileList } - - The corresponding translation files have been automatically marked as potentially outdated in this PR branch. Translators should review these changes and update translations accordingly.${ markedFilesList }`; + const body = '## 🌐 Translation Update Notice\n\n' + + 'The following English documentation files were modified in this PR:\n\n' + + fileList + '\n\n' + + 'The corresponding translation files have been automatically marked as potentially outdated in this PR branch. Translators should review these changes and update translations accordingly.' + + markedFilesList; github.rest.issues.createComment({ issue_number: context.issue.number,