diff --git a/.github/workflows/crowdin.yml b/.github/workflows/crowdin.yml new file mode 100644 index 000000000..a21bd4810 --- /dev/null +++ b/.github/workflows/crowdin.yml @@ -0,0 +1,205 @@ +name: 🌐 Crowdin Translations + +on: + push: + branches: [dev] + paths: + - 'kubejs/assets/**/lang/en_us.json' + - 'kubejs/assets/**/patchouli_books/**/en_us/**/*.json' + workflow_dispatch: + inputs: + operation: + description: 'Operation type' + required: true + default: 'both' + type: choice + options: + - upload + - download + - both + - status + force_upload: + description: 'Force upload all sources' + required: false + default: false + type: boolean + skip_pr: + description: 'Skip pull request creation' + required: false + default: false + type: boolean + download_language: + description: 'Download specific language only (optional, e.g., ru, zh_cn)' + required: false + type: string + export_approved_only: + description: 'Export only approved translations' + required: false + default: false + type: boolean + dry_run: + description: 'Dry run mode (no actual changes)' + required: false + default: false + type: boolean + schedule: + # Run daily at 3 AM UTC + - cron: '0 3 * * *' + +jobs: + sync: + runs-on: ubuntu-latest + if: github.event.inputs.operation != 'status' + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Validate configuration + run: | + echo " Validating Crowdin configuration..." + if [ ! -f "crowdin.yml" ]; then + echo " crowdin.yml not found" + exit 1 + fi + echo " Configuration file found" + + - name: Validate source files + run: | + echo " Validating source language files..." + + # Check for required English source files + find kubejs/assets -name "en_us.json" -type f | while read file; do + echo " Found source file: $file" + # Basic JSON validation + if ! jq empty "$file" 2>/dev/null; then + echo " Invalid JSON in $file" + exit 1 + fi + done + + echo " All source files are valid JSON" + + - name: Upload Sources to Crowdin + if: github.event.inputs.operation == 'upload' || github.event.inputs.operation == 'both' || github.event_name == 'push' || github.event_name == 'schedule' + uses: crowdin/github-action@v2.15.0 + with: + upload_sources: true + upload_translations: false + configuration: crowdin.yml + upload_sources_args: ${{ github.event.inputs.force_upload == 'true' && '--auto-update --preserve-hierarchy' || '--preserve-hierarchy' }} + dry_run: ${{ github.event.inputs.dry_run == 'true' }} + env: + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_TOKEN }} + + - name: Download Translations from Crowdin + if: github.event.inputs.operation == 'download' || github.event.inputs.operation == 'both' || github.event_name == 'schedule' + uses: crowdin/github-action@v2.15.0 + with: + upload_sources: false + upload_translations: false + download_translations: true + configuration: crowdin.yml + localization_branch_name: translations + create_pull_request: ${{ github.event.inputs.skip_pr != 'true' }} + pull_request_base_branch_name: 'dev' + pull_request_body: | + ## New translations from Crowdin + + ### + - **Trigger**: ${{ github.event_name }} + - **Operation**: ${{ github.event.inputs.operation || 'auto-sync' }} + - **Language**: ${{ github.event.inputs.download_language || 'all languages' }} + - **Approved only**: ${{ github.event.inputs.export_approved_only || 'false' }} + + ### + - Updated JSON translation files + - Patchouli book translations + - Language-specific improvements + + ### + Please test the translations in-game: + 1. Switch to different languages + 2. Check mod descriptions and tooltips + 3. Verify Patchouli guide content + + --- + *Automated by [Crowdin GitHub Action](https://github.com/crowdin/github-action)* + download_language: ${{ github.event.inputs.download_language }} + export_only_approved: ${{ github.event.inputs.export_approved_only }} + dry_run: ${{ github.event.inputs.dry_run == 'true' }} + env: + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_TOKEN }} + + # Status check job + status: + runs-on: ubuntu-latest + if: github.event.inputs.operation == 'status' + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Get Crowdin Project Status + uses: crowdin/github-action@v2.15.0 + with: + command: 'status' + command_args: '--language ${{ github.event.inputs.download_language || "" }} --format json' + configuration: crowdin.yml + env: + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_TOKEN }} + + - name: Generate Status Report + run: | + echo "## Crowdin Translation Status Report" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Project ID**: ${{ vars.CROWDIN_ID }}" >> $GITHUB_STEP_SUMMARY + echo "**Language Filter**: ${{ github.event.inputs.download_language || 'All languages' }}" >> $GITHUB_STEP_SUMMARY + echo "**Generated**: $(date -u)" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo " Use the output above to review translation progress." >> $GITHUB_STEP_SUMMARY + + # Quality validation job (runs after successful sync) + validate-translations: + runs-on: ubuntu-latest + needs: sync + if: always() && needs.sync.result == 'success' && github.event.inputs.operation != 'upload' + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + # Fetch translations branch for validation + ref: translations + + - name: Validate translation files + run: | + echo " Validating downloaded translation files..." + + # Find all translation files (non-English) + find kubejs/assets -name "*.json" -type f ! -name "en_us.json" | while read file; do + echo " Validating: $file" + + # Check if file is valid JSON + if ! jq empty "$file" 2>/dev/null; then + echo " Invalid JSON in $file" + continue + fi + + # Check for empty translations + empty_keys=$(jq 'paths(scalars) as $p | $p | select(getpath($p) == "" or getpath($p) == null)) | length' "$file") + if [ "$empty_keys" -gt 0 ]; then + echo " Found $empty_keys empty translation keys in $file" + fi + + # Check file size (very small files might be incomplete) + file_size=$(stat -c%s "$file") + if [ "$file_size" -lt 100 ]; then + echo " Very small file ($file_size bytes): $file" + fi + done + + echo " Translation validation completed" \ No newline at end of file diff --git a/crowdin.yml b/crowdin.yml index b7b5993c2..24c6021b3 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -5,7 +5,7 @@ base_path: "./kubejs/assets" project_id_env: "CROWDIN_ID" api_token_env: "CROWDIN_TOKEN" -pull_request_title: "New Crowdin updates" +pull_request_title: "[🌐]: New Crowdin updates" # Automatically label PRs made by Crowdin pull_request_labels: [ "Pull request: Translation" ]