fix(i18n): resolve ISO 639-2/B language codes and stop gating validit… #447
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
| name: Update Translations | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'cps/**' | |
| - 'scripts/compile_translations.sh' | |
| - 'scripts/update_translations.sh' | |
| - 'scripts/generate_translation_status.py' | |
| - '.github/workflows/update-translations.yml' | |
| workflow_dispatch: | |
| # Two merges to main in quick succession trigger two runs; both commit a | |
| # translation update and the loser's push is rejected non-fast-forward. | |
| # Serialize runs so only pushes from outside this workflow can race the | |
| # commit step (those are handled by the rebase-and-retry loop below). | |
| # cancel-in-progress stays false: cancelling a run mid-push could strand | |
| # a half-finished commit. | |
| concurrency: | |
| group: ${{ github.workflow }} | |
| cancel-in-progress: false | |
| permissions: | |
| contents: write | |
| actions: write | |
| jobs: | |
| update-translations: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repo | |
| uses: actions/checkout@v7 | |
| with: | |
| persist-credentials: true | |
| # GH_PAT is a personal token belonging to new-usemame (the repo | |
| # admin). The "main protection" ruleset blocks direct pushes to | |
| # main for everyone except admins, so the default GITHUB_TOKEN | |
| # (which authenticates as github-actions[bot]) gets rejected | |
| # with GH013. Using GH_PAT lets the workflow's translation | |
| # commit land on main under new-usemame's admin-bypass. | |
| token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.13' | |
| - name: Install dependencies | |
| run: pip install Babel polib jinja2 | |
| - name: Install gettext | |
| run: sudo apt-get update && sudo apt-get install -y gettext | |
| - name: Detect commit PAT | |
| # The "main protection" ruleset blocks direct pushes to main for | |
| # everyone except admins, and personal repos can't bypass that | |
| # for the github-actions[bot] integration. Pushing the | |
| # translation-status commit therefore requires GH_PAT (new-usemame's | |
| # personal token, admin-bypass eligible). When the secret is | |
| # missing, the workflow still runs — it just skips the commit and | |
| # logs a notice. README translation status will go stale until | |
| # someone runs `scripts/update_translations.sh` locally and pushes | |
| # via a normal PR, or until GH_PAT is added to repo secrets. | |
| id: commit_pat | |
| env: | |
| GH_PAT: ${{ secrets.GH_PAT }} | |
| run: | | |
| if [ -n "${GH_PAT}" ]; then | |
| echo "available=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "available=false" >> "$GITHUB_OUTPUT" | |
| echo "::notice::GH_PAT secret not set; skipping translation auto-commit. Add a new-usemame PAT as GH_PAT to enable README auto-updates." | |
| fi | |
| - name: Run update_translations.sh | |
| run: bash scripts/update_translations.sh | |
| - name: Refresh translation-status table in README | |
| run: python scripts/generate_translation_status.py | |
| - name: Commit translation updates | |
| if: steps.commit_pat.outputs.available == 'true' | |
| run: | | |
| # Identity must be new-usemame: validate-author + the main | |
| # branch ruleset bypass list both key off this committer email. | |
| git config --global user.name "new-usemame" | |
| git config --global user.email "248195428+new-usemame@users.noreply.github.com" | |
| git add -f messages.pot cps/translations/*/LC_MESSAGES/messages.po README.md | |
| if git diff --cached --quiet; then | |
| echo "No translation changes to commit" | |
| echo "TRANSLATION_COMMITTED=0" >> $GITHUB_ENV | |
| else | |
| git commit -m "Update translations [skip ci]" | |
| # The autopilot pushes docs commits to main minutes after each | |
| # merge, so a bare `git push` here loses that race and fails | |
| # non-fast-forward (3 of the last 30 runs). The commit holds | |
| # only generated files; rebasing it onto updated main is safe. | |
| # On a genuine rebase conflict, abort and fail — the push that | |
| # beat us triggers its own run, which regenerates everything. | |
| pushed=0 | |
| for attempt in 1 2 3; do | |
| if git push; then | |
| pushed=1 | |
| break | |
| fi | |
| echo "push rejected (attempt ${attempt}/3); rebasing onto updated main" | |
| if ! git pull --rebase origin main; then | |
| git rebase --abort | |
| echo "::error::rebase conflict while retrying translation push" | |
| exit 1 | |
| fi | |
| done | |
| if [ "${pushed}" != "1" ]; then | |
| echo "::error::translation push failed after 3 attempts" | |
| exit 1 | |
| fi | |
| echo "TRANSLATION_COMMITTED=1" >> $GITHUB_ENV | |
| echo "TRANSLATION_COMMIT_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV | |
| fi | |
| - name: Select dev build SHA | |
| run: | | |
| if [ "${{ env.TRANSLATION_COMMITTED }}" = "1" ]; then | |
| echo "DEV_BUILD_SHA=${{ env.TRANSLATION_COMMIT_SHA }}" >> $GITHUB_ENV | |
| else | |
| echo "DEV_BUILD_SHA=${{ github.sha }}" >> $GITHUB_ENV | |
| fi | |
| - name: Trigger dev build for main | |
| # A workflow_dispatch HTTP API call returns 204 on success and 422 on | |
| # bad inputs (e.g. undeclared `inputs.*`). curl without --fail returns 0 | |
| # on 422, which previously masked silent dispatch failures — the step | |
| # went green while no dev build actually ran. Use --fail-with-body so | |
| # any non-2xx surfaces here, and assert 204 explicitly. | |
| run: | | |
| set -euo pipefail | |
| http_code=$(curl -sS -L -X POST \ | |
| -o /tmp/dispatch.out -w "%{http_code}" \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ | |
| https://api.github.com/repos/${{ github.repository }}/actions/workflows/docker-image-build-dev.yml/dispatches \ | |
| -d "{\"ref\":\"main\",\"inputs\":{\"ref\":\"${DEV_BUILD_SHA}\",\"branch\":\"main\"}}") | |
| echo "dispatch HTTP ${http_code}" | |
| if [ "${http_code}" != "204" ]; then | |
| echo "::error::dev-build dispatch failed (HTTP ${http_code})" | |
| cat /tmp/dispatch.out | |
| exit 1 | |
| fi | |
| # The per-language translation-status table lives in the repo README | |
| # (single source of truth) — see the "Translations" section of the | |
| # wiki's Contributing page. The old steps here cloned the wiki and | |
| # wrote the table into a `Contributing-Translations` page; that page | |
| # was consolidated away, so the generator crashed on the missing file | |
| # and this job went red on every push. The README refresh above is the | |
| # canonical output, so the wiki-write steps are gone. |