diff --git a/translate-changelog/action.yml b/translate-changelog/action.yml
index 5ec8aae..41bdad3 100644
--- a/translate-changelog/action.yml
+++ b/translate-changelog/action.yml
@@ -1,11 +1,26 @@
name: 'Translate Changelog and Create PR'
-description: 'Translates Russian changelog files to English and creates a PR'
+description: 'Translates changelog files between languages and creates a PR'
inputs:
changelog_path:
description: 'Path to CHANGELOG directory'
required: false
default: 'CHANGELOG'
+ file_prefix:
+ description: 'Prefix for changelog files (e.g., "CHANGELOG-v" or "v")'
+ required: false
+ default: 'v'
+ source_lang:
+ description: 'Source language code (ru or en)'
+ required: false
+ default: 'ru'
+ target_lang:
+ description: 'Target language code (en or ru)'
+ required: false
+ default: 'en'
+ github_token:
+ description: 'GitHub token for creating pull requests'
+ required: false
python_version:
description: 'Python version to use'
required: false
@@ -18,10 +33,10 @@ inputs:
outputs:
version:
description: 'Version of the translated changelog'
- ru_file:
- description: 'Russian changelog file name'
- eng_file:
- description: 'English changelog file name'
+ source_file:
+ description: 'Source changelog file name'
+ target_file:
+ description: 'Target changelog file name'
has_changes:
description: 'Whether CHANGELOG files were changed in the last commit'
@@ -32,17 +47,29 @@ runs:
id: check_changes
shell: bash
run: |
- # Проверить, есть ли изменения в CHANGELOG/*.ru.yml в последнем коммите
- # Используем git show для получения списка измененных файлов в HEAD
+ # Проверить, есть ли изменения в CHANGELOG файлах в последнем коммите
CHANGELOG_PATH="${{ inputs.changelog_path }}"
- CHANGED_FILES=$(git show --name-only --pretty=format: HEAD | grep "^${CHANGELOG_PATH}/.*\.ru\.yml$" || true)
-
+ FILE_PREFIX="${{ inputs.file_prefix }}"
+ SOURCE_LANG="${{ inputs.source_lang }}"
+
+ # Определить паттерн исходных файлов на основе source_lang
+ if [ "$SOURCE_LANG" = "en" ]; then
+ # Для английского ищем файлы без языкового суффикса
+ FILE_PATTERN="^${CHANGELOG_PATH}/${FILE_PREFIX}[0-9]+\.[0-9]+\.[0-9]+\.yml$"
+ else
+ # Для других языков ищем файлы с языковым суффиксом
+ FILE_PATTERN="^${CHANGELOG_PATH}/${FILE_PREFIX}[0-9]+\.[0-9]+\.[0-9]+\.${SOURCE_LANG}\.yml$"
+ fi
+
+ # Получить список измененных файлов в последнем коммите
+ CHANGED_FILES=$(git show --name-only --pretty=format: HEAD | grep -E "$FILE_PATTERN" || true)
+
if [ -n "$CHANGED_FILES" ]; then
- echo "CHANGELOG .ru.yml files changed in last commit:"
+ echo "CHANGELOG files changed in last commit (source_lang=$SOURCE_LANG):"
echo "$CHANGED_FILES"
echo "has_changes=true" >> $GITHUB_OUTPUT
else
- echo "No CHANGELOG .ru.yml files changed in last commit, skipping"
+ echo "No CHANGELOG files changed in last commit for source_lang=$SOURCE_LANG, skipping"
echo "has_changes=false" >> $GITHUB_OUTPUT
fi
@@ -58,166 +85,182 @@ runs:
run: |
pip install pyyaml deep-translator packaging
- - name: Find latest Russian changelog
+ - name: Find latest changelog
if: steps.check_changes.outputs.has_changes == 'true'
id: find_changelog
shell: bash
run: |
cd "${{ inputs.changelog_path }}"
-
- # Найти все русские файлы и отсортировать по semver
+
+ export FILE_PREFIX="${{ inputs.file_prefix }}"
+ export SOURCE_LANG="${{ inputs.source_lang }}"
+ export TARGET_LANG="${{ inputs.target_lang }}"
+
+ # Найти все файлы исходного языка и отсортировать по semver
python3 << 'EOF'
import os
import re
from packaging import version
-
- files = [f for f in os.listdir('.') if f.endswith('.ru.yml')]
-
+
+ file_prefix = os.environ.get('FILE_PREFIX', 'CHANGELOG-v')
+ source_lang = os.environ.get('SOURCE_LANG', 'ru')
+ target_lang = os.environ.get('TARGET_LANG', 'en')
+
+ # Определить паттерн файлов на основе source_lang
+ if source_lang == 'en':
+ # Для английского ищем файлы без языкового суффикса
+ file_pattern = re.compile(rf'^{re.escape(file_prefix)}(\d+\.\d+\.\d+)\.yml$')
+ source_suffix = ''
+ else:
+ # Для других языков ищем файлы с языковым суффиксом
+ file_pattern = re.compile(rf'^{re.escape(file_prefix)}(\d+\.\d+\.\d+)\.{re.escape(source_lang)}\.yml$')
+ source_suffix = f'.{source_lang}'
+
+ files = [f for f in os.listdir('.') if file_pattern.match(f)]
+
# Извлечь версии из имен файлов
versions = []
for f in files:
- match = re.match(r'v(\d+\.\d+\.\d+)\.ru\.yml', f)
+ match = file_pattern.match(f)
if match:
versions.append((version.parse(match.group(1)), f))
-
+
if not versions:
- print("No Russian changelog files found")
+ print(f"No changelog files found for source language: {source_lang}")
exit(1)
-
+
# Отсортировать по версии (последняя версия первая)
versions.sort(reverse=True)
- latest_version, latest_file = versions[0]
-
- # Проверить, существует ли уже английский файл
- eng_file = latest_file.replace('.ru.yml', '.yml')
- if os.path.exists(eng_file):
- print(f"English file {eng_file} already exists, skipping")
- exit(0)
+ latest_version, source_file = versions[0]
+
+ # Определить имя целевого файла
+ version_str = f"{latest_version}"
+ if target_lang == 'en':
+ # Для английского целевой файл без языкового суффикса
+ target_file = f"{file_prefix}{version_str}.yml"
+ else:
+ # Для других языков целевой файл с языковым суффиксом
+ target_file = f"{file_prefix}{version_str}.{target_lang}.yml"
- version_str = f"v{latest_version}"
- import os
github_output = os.environ.get('GITHUB_OUTPUT', '/dev/stdout')
with open(github_output, 'a') as f:
- f.write(f"version={version_str}\n")
- f.write(f"ru_file={latest_file}\n")
- f.write(f"eng_file={eng_file}\n")
- print(f"Latest version: {version_str}, file: {latest_file}")
+ f.write(f"version=v{version_str}\n")
+ f.write(f"source_file={source_file}\n")
+ f.write(f"target_file={target_file}\n")
+ print(f"Latest version: v{version_str}, source: {source_file}, target: {target_file}")
EOF
continue-on-error: true
- - name: Translate changelog
- if: steps.check_changes.outputs.has_changes == 'true' && steps.find_changelog.outcome == 'success'
- id: translate
- shell: bash
- env:
- RU_FILE: ${{ steps.find_changelog.outputs.ru_file }}
- ENG_FILE: ${{ steps.find_changelog.outputs.eng_file }}
- run: |
- cd "${{ inputs.changelog_path }}"
-
- python3 << 'EOF'
- from deep_translator import GoogleTranslator
- import os
-
- ru_file = os.environ['RU_FILE']
- eng_file = os.environ['ENG_FILE']
-
- # Загрузить русский файл построчно для сохранения форматирования
- with open(ru_file, 'r', encoding='utf-8') as f:
- ru_lines = f.readlines()
-
- # Перевести содержимое построчно
- translator = GoogleTranslator(source='ru', target='en')
-
- # Сохранить с сохранением оригинального форматирования
- with open(eng_file, 'w', encoding='utf-8') as f:
- for line in ru_lines:
- # Пропустить пустые строки
- if not line.strip():
- f.write(line)
- continue
-
- # Сохранить оригинальные отступы
- indent = len(line) - len(line.lstrip())
- content = line.strip()
-
- # Перевести содержимое строки
- translated_content = translator.translate(content)
-
- # Записать переведенную строку с сохранением отступов
- f.write(' ' * indent + translated_content + '\n')
-
- print(f"Translated {ru_file} to {eng_file}")
- EOF
-
- - name: Get current branch name
+ - name: Get current branch name and create translation branch
if: steps.check_changes.outputs.has_changes == 'true' && steps.find_changelog.outcome == 'success'
id: get_branch
shell: bash
- run: |
- BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
- echo "branch=$BRANCH_NAME" >> $GITHUB_OUTPUT
- echo "Current branch: $BRANCH_NAME"
-
- - name: Commit translated changelog
- if: steps.check_changes.outputs.has_changes == 'true' && steps.find_changelog.outcome == 'success'
- shell: bash
run: |
VERSION="${{ steps.find_changelog.outputs.version }}"
+ SOURCE_LANG="${{ inputs.source_lang }}"
+ TARGET_LANG="${{ inputs.target_lang }}"
- git config --local user.email "action@github.com"
- git config --local user.name "GitHub Action"
+ # Создать имя новой ветки для перевода
+ TRANSLATION_BRANCH="translation/${SOURCE_LANG}-to-${TARGET_LANG}/${VERSION}"
- git add "${{ inputs.changelog_path }}/"
- git commit -m "Translate changelog ${VERSION} to English"
+ # Проверить существует ли ветка локально или на remote
+ if git show-ref --verify --quiet "refs/heads/$TRANSLATION_BRANCH"; then
+ # Ветка существует локально, переключаемся на нее
+ git checkout "$TRANSLATION_BRANCH"
+ echo "Switched to existing local branch: $TRANSLATION_BRANCH"
+ elif git ls-remote --heads origin "$TRANSLATION_BRANCH" | grep -q "$TRANSLATION_BRANCH"; then
+ # Ветка существует на remote, получаем ее
+ git fetch origin "$TRANSLATION_BRANCH"
+ git checkout -b "$TRANSLATION_BRANCH" "origin/$TRANSLATION_BRANCH"
+ echo "Checked out existing remote branch: $TRANSLATION_BRANCH"
+ else
+ # Ветка не существует, создаем новую
+ git checkout -b "$TRANSLATION_BRANCH"
+ echo "Created new branch: $TRANSLATION_BRANCH"
+ fi
- # Пушим коммит в текущую ветку
- git push origin HEAD
+ echo "branch=$TRANSLATION_BRANCH" >> $GITHUB_OUTPUT
- - name: Create Pull Request using GitHub CLI
+ - name: Translate changelog
if: steps.check_changes.outputs.has_changes == 'true' && steps.find_changelog.outcome == 'success'
+ id: translate
shell: bash
env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ SOURCE_FILE: ${{ steps.find_changelog.outputs.source_file }}
+ TARGET_FILE: ${{ steps.find_changelog.outputs.target_file }}
+ SOURCE_LANG: ${{ inputs.source_lang }}
+ TARGET_LANG: ${{ inputs.target_lang }}
run: |
- BRANCH_NAME="${{ steps.get_branch.outputs.branch }}"
- BASE_BRANCH="${{ inputs.base_branch }}"
- VERSION="${{ steps.find_changelog.outputs.version }}"
-
- # Проверить, существует ли уже PR для этой ветки
- EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --base "$BASE_BRANCH" --json number --jq '.[0].number' 2>/dev/null || echo "")
-
- if [ -n "$EXISTING_PR" ] && [ "$EXISTING_PR" != "null" ]; then
- echo "PR #$EXISTING_PR already exists for branch $BRANCH_NAME"
- exit 0
- fi
-
- # Создать временный файл для body PR
- PR_BODY_FILE=$(mktemp)
- cat > "$PR_BODY_FILE" << EOF
- ## Changelog $VERSION
+ cd "${{ inputs.changelog_path }}"
+
+ python3 << 'EOF'
+ from deep_translator import GoogleTranslator
+ import os
+ import yaml
- This PR contains the English translation of the Russian changelog for version $VERSION.
+ source_file = os.environ['SOURCE_FILE']
+ target_file = os.environ['TARGET_FILE']
+ source_lang = os.environ['SOURCE_LANG']
+ target_lang = os.environ['TARGET_LANG']
- **Source file:** \`${{ inputs.changelog_path }}/${{ steps.find_changelog.outputs.ru_file }}\`
- **Translated file:** \`${{ inputs.changelog_path }}/${{ steps.find_changelog.outputs.eng_file }}\`
+ # Загрузить YAML файл
+ with open(source_file, 'r', encoding='utf-8') as f:
+ data = yaml.safe_load(f)
-
- Changelog content
+ # Инициализировать переводчик
+ translator = GoogleTranslator(source=source_lang, target=target_lang)
- \`\`\`yaml
- $(cat "${{ inputs.changelog_path }}/${{ steps.find_changelog.outputs.eng_file }}")
- \`\`\`
+ def translate_value(value):
+ """Рекурсивно переводит значения в структуре данных"""
+ if isinstance(value, str):
+ # Переводим строку
+ try:
+ return translator.translate(value)
+ except Exception as e:
+ print(f"Warning: Failed to translate '{value[:50]}...': {e}")
+ return value
+ elif isinstance(value, dict):
+ # Рекурсивно обрабатываем словарь (ключи остаются без изменений)
+ return {key: translate_value(val) for key, val in value.items()}
+ elif isinstance(value, list):
+ # Рекурсивно обрабатываем список
+ return [translate_value(item) for item in value]
+ else:
+ # Другие типы (числа, bool, None) возвращаем без изменений
+ return value
-
+ # Перевести все значения в структуре
+ translated_data = translate_value(data)
+
+ # Сохранить переведенный YAML
+ with open(target_file, 'w', encoding='utf-8') as f:
+ yaml.dump(translated_data, f, allow_unicode=True, default_flow_style=False, sort_keys=False)
+
+ print(f"Translated {source_file} ({source_lang}) to {target_file} ({target_lang})")
EOF
-
- # Создать PR
- gh pr create \
- --base "$BASE_BRANCH" \
- --head "$BRANCH_NAME" \
- --title "$VERSION" \
- --body-file "$PR_BODY_FILE"
-
- # Удалить временный файл
- rm -f "$PR_BODY_FILE"
+
+ - name: Create Pull Request
+ if: steps.check_changes.outputs.has_changes == 'true' && steps.find_changelog.outcome == 'success'
+ uses: peter-evans/create-pull-request@v7
+ with:
+ token: ${{ inputs.github_token }}
+ commit-message: Translate changelog ${{ steps.find_changelog.outputs.version }} from ${{ inputs.source_lang }} to ${{ inputs.target_lang }}
+ branch: translation/${{ inputs.source_lang }}-to-${{ inputs.target_lang }}/${{ steps.find_changelog.outputs.version }}
+ delete-branch: false
+ title: ${{ steps.find_changelog.outputs.version }}
+ body: |
+ ## Changelog ${{ steps.find_changelog.outputs.version }}
+
+ This PR contains the ${{ inputs.target_lang == 'ru' && 'Russian' || 'English' }} translation of the ${{ inputs.source_lang == 'ru' && 'Russian' || 'English' }} changelog for version ${{ steps.find_changelog.outputs.version }}.
+
+ **Source file:** `${{ inputs.changelog_path }}/${{ steps.find_changelog.outputs.source_file }}`
+ **Translated file:** `${{ inputs.changelog_path }}/${{ steps.find_changelog.outputs.target_file }}`
+
+
+ Changelog content
+
+ The translated changelog file has been generated and is ready for review.
+
+
+ base: ${{ inputs.base_branch }}
+