docs: update README files and add release creation prompt #10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Internationalization (i18n) Workflow | |
| # Generates translation template (POT) files and validates i18n implementation | |
| # | |
| # Features: | |
| # - Automatic POT file generation from PHP and JavaScript | |
| # - JSON translation file generation for JavaScript | |
| # - i18n validation and best practices checks | |
| # - Automated POT file updates on push to main/develop | |
| name: Internationalization | |
| on: | |
| push: | |
| branches: [main, develop] | |
| paths: | |
| - '**.php' | |
| - '**.js' | |
| - '**.jsx' | |
| - 'src/**' | |
| - 'inc/**' | |
| - 'package.json' | |
| pull_request: | |
| branches: [main, develop] | |
| paths: | |
| - '**.php' | |
| - '**.js' | |
| - '**.jsx' | |
| - 'src/**' | |
| - 'inc/**' | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| env: | |
| TEXT_DOMAIN: '{{textdomain}}' | |
| POT_FILE: 'languages/{{slug}}.pot' | |
| jobs: | |
| validate-i18n: | |
| name: Validate Internationalization | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Setup PHP | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.1' | |
| tools: composer, wp-cli | |
| - name: Install dependencies | |
| run: | | |
| npm ci | |
| composer install --prefer-dist --no-progress | |
| - name: Check for hardcoded strings in source files | |
| run: | | |
| echo "## i18n Validation Report" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # Check for common hardcoded string patterns in all plugin folders | |
| HARDCODED=$(grep -r -E '>[[:space:]]*[A-Z][a-z]+[[:space:]<]' src/ inc/ templates/ parts/ patterns/ --include="*.js" --include="*.jsx" --include="*.php" --include="*.html" || true) | |
| if [ -n "$HARDCODED" ]; then | |
| echo "⚠️ **Potential hardcoded strings found:**" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "$HARDCODED" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "::warning::Potential hardcoded strings found in source files. Consider using translation functions." | |
| else | |
| echo "✅ No obvious hardcoded strings detected" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Validate text domain usage | |
| run: | | |
| # Check for incorrect text domain usage | |
| WRONG_DOMAIN=$(grep -r -E "__\(|_e\(|_x\(|_n\(|esc_html__|esc_attr__" . \ | |
| --include="*.php" \ | |
| --exclude-dir=vendor \ | |
| --exclude-dir=node_modules \ | |
| | grep -v "'${{ env.TEXT_DOMAIN }}'" \ | |
| | grep -v "// phpcs:" \ | |
| || true) | |
| if [ -n "$WRONG_DOMAIN" ]; then | |
| echo "⚠️ **Incorrect text domain usage:**" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Expected text domain: \`${{ env.TEXT_DOMAIN }}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "::warning::Some translation functions may be using incorrect text domain" | |
| else | |
| echo "✅ Text domain usage correct" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| generate-pot: | |
| name: Generate POT Files | |
| runs-on: ubuntu-latest | |
| needs: validate-i18n | |
| if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Setup PHP | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.1' | |
| tools: wp-cli | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Create languages directory | |
| run: mkdir -p languages | |
| - name: Generate POT from PHP files | |
| run: | | |
| wp i18n make-pot . languages/{{slug}}.pot \ | |
| --slug={{slug}} \ | |
| --domain={{textdomain}} \ | |
| --exclude=node_modules,vendor,build,tests \ | |
| --headers='{"Report-Msgid-Bugs-To":"{{supportUrl}}"}' | |
| echo "✅ PHP POT file generated" | |
| - name: Build JavaScript for translation extraction | |
| run: npm run build | |
| - name: Generate POT from JavaScript files | |
| run: | | |
| # JavaScript strings are extracted during build via @wordpress/babel-plugin-makepot | |
| # Merge JavaScript POT with main POT if it exists | |
| if [ -f "languages/{{slug}}-js.pot" ]; then | |
| msgcat --use-first languages/{{slug}}.pot languages/{{slug}}-js.pot -o languages/{{slug}}.pot | |
| rm languages/{{slug}}-js.pot | |
| echo "✅ JavaScript strings merged into main POT" | |
| fi | |
| - name: Generate JSON translation files | |
| run: | | |
| npm run makejson | |
| echo "✅ JSON translation files generated" | |
| - name: Update POT file metadata | |
| run: | | |
| # Update POT-Creation-Date | |
| sed -i "s/POT-Creation-Date: .*/POT-Creation-Date: $(date -u +"%Y-%m-%d %H:%M+0000")/" languages/{{slug}}.pot | |
| # Show statistics | |
| STRINGS=$(grep -c "^msgid " languages/{{slug}}.pot || echo "0") | |
| echo "📊 Total translatable strings: $STRINGS" | |
| echo "## Translation Statistics" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Total strings:** $STRINGS" >> $GITHUB_STEP_SUMMARY | |
| echo "- **POT file:** \`${{ env.POT_FILE }}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Text domain:** \`${{ env.TEXT_DOMAIN }}\`" >> $GITHUB_STEP_SUMMARY | |
| - name: Check for POT changes | |
| id: pot-changes | |
| run: | | |
| git add languages/ | |
| if git diff --cached --quiet; then | |
| echo "changed=false" >> $GITHUB_OUTPUT | |
| echo "No changes to POT files" | |
| else | |
| echo "changed=true" >> $GITHUB_OUTPUT | |
| echo "POT files have been updated" | |
| fi | |
| - name: Commit and push POT files | |
| if: steps.pot-changes.outputs.changed == 'true' | |
| run: | | |
| git config --local user.email "github-actions[bot]@users.noreply.github.com" | |
| git config --local user.name "github-actions[bot]" | |
| git commit -m "chore(i18n): update translation template files [skip ci]" | |
| git push | |
| - name: Upload POT as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: translation-template | |
| path: languages/*.pot | |
| retention-days: 30 | |
| test-translations: | |
| name: Test Translation Loading | |
| runs-on: ubuntu-latest | |
| needs: validate-i18n | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup PHP | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.1' | |
| - name: Test load_plugin_textdomain call | |
| run: | | |
| # Verify plugin loads translations correctly | |
| if grep -q "load_plugin_textdomain" {{slug}}.php; then | |
| echo "✅ load_plugin_textdomain() found in main plugin file" | |
| echo "✅ Plugin textdomain loading configured" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "::error::load_plugin_textdomain() not found in main plugin file" | |
| exit 1 | |
| fi | |
| - name: Check for JavaScript translation setup | |
| run: | | |
| # Check for wp_set_script_translations usage | |
| if grep -r "wp_set_script_translations" . --include="*.php" --exclude-dir=vendor --exclude-dir=node_modules; then | |
| echo "✅ JavaScript translations configured" | |
| else | |
| echo "::warning::No wp_set_script_translations() calls found. JavaScript translations may not load." | |
| fi | |
| summary: | |
| name: i18n Summary | |
| runs-on: ubuntu-latest | |
| needs: [validate-i18n, generate-pot, test-translations] | |
| if: always() | |
| steps: | |
| - name: Generate summary | |
| run: | | |
| echo "## Internationalization Workflow Complete" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Task | Status |" >> $GITHUB_STEP_SUMMARY | |
| echo "|------|--------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| Validation | ${{ needs.validate-i18n.result }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| POT Generation | ${{ needs.generate-pot.result }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Translation Tests | ${{ needs.test-translations.result }} |" >> $GITHUB_STEP_SUMMARY | |
| if [[ "${{ needs.validate-i18n.result }}" == "failure" ]] || \ | |
| [[ "${{ needs.test-translations.result }}" == "failure" ]]; then | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "❌ **i18n checks failed**" >> $GITHUB_STEP_SUMMARY | |
| exit 1 | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "✅ **All i18n checks passed**" >> $GITHUB_STEP_SUMMARY |