Files
bookorbit/.github/workflows/crowdin-translations.yml
T
neon 9eff914aef fix(client): stop requiring plural categories no count can select
The locale validator demanded every CLDR plural category, so each new ICU plural key took the daily
Crowdin sync red until a `many` branch was hand-added for Spanish and French. That branch can never
render: `many` selects at a million and over in Spanish, French, Italian and Portuguese, and only
for fractional counts in Czech and Slovak, while every catalog plural counts whole items well below
a million and intl-messageformat falls back to `other` regardless. Require only the categories an
integer count 0..1000 can select, which is the same set every integer below a million selects, and
keep `other` always so the categories everyday counts reach stay mandatory.

Drop a target message that still fails validation from the sparse catalog instead of failing the
whole export, so one broken string can no longer block the other 23 languages for days. Report the
rejections in the run log and the pull request body, and keep the retention guard fatal when a
rejected message would replace a translation that is already in Git.
2026-08-12 16:54:51 +00:00

133 lines
4.7 KiB
YAML

name: Crowdin Translation Sync
on:
workflow_dispatch:
inputs:
allowed_translation_losses:
description: "Comma-separated locale:message.key acknowledgements for intentional translation removals"
required: false
type: string
schedule:
- cron: "47 5 * * *"
permissions:
contents: read
concurrency:
group: crowdin-translation-sync
cancel-in-progress: false
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
NODE_VERSION: "24"
PNPM_VERSION: "10"
jobs:
synchronize:
name: Validate and propose translations
if: github.repository == 'bookorbit/bookorbit'
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout main
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: main
- name: Set up Node.js and pnpm
uses: ./.github/actions/setup-node-pnpm
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
prefetch: "true"
- name: Check synchronization credentials
env:
CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }}
CROWDIN_PR_TOKEN: ${{ secrets.CROWDIN_PR_TOKEN }}
run: |
if [ -z "$CROWDIN_TOKEN" ]; then
echo "::error::CROWDIN_TOKEN is required."
exit 1
fi
if [ -z "$CROWDIN_PR_TOKEN" ]; then
echo "::error::CROWDIN_PR_TOKEN is required so pull request workflows are triggered."
exit 1
fi
- name: Build sparse translation catalogs
env:
CROWDIN_ALLOWED_TRANSLATION_LOSSES: ${{ inputs.allowed_translation_losses }}
CROWDIN_PROJECT_ID: ${{ vars.CROWDIN_PROJECT_ID }}
CROWDIN_REJECTION_REPORT: ${{ runner.temp }}/crowdin-rejections.md
CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }}
run: pnpm --filter client sync:crowdin
- name: Validate translation catalogs
run: pnpm --filter client validate:locales
- name: Test localization runtime and synchronization
run: >-
pnpm --filter client exec vitest run
scripts/locale-catalog-validation.spec.mjs
scripts/sync-crowdin-translations.spec.mjs
src/i18n/icu.spec.ts
- name: Compose pull request body
env:
PR_BODY: ${{ runner.temp }}/crowdin-pr-body.md
REJECTION_REPORT: ${{ runner.temp }}/crowdin-rejections.md
run: |
{
echo "Automated sparse translation export from Crowdin."
echo
echo "Untranslated entries are omitted so Vue I18n falls back to the English catalog."
} > "$PR_BODY"
if [ -s "$REJECTION_REPORT" ]; then
echo >> "$PR_BODY"
cat "$REJECTION_REPORT" >> "$PR_BODY"
cat "$REJECTION_REPORT" >> "$GITHUB_STEP_SUMMARY"
echo "::warning::Crowdin returned translations that failed catalog validation; they were omitted and are listed in the pull request body."
fi
- name: Create translation pull request
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
token: ${{ secrets.CROWDIN_PR_TOKEN }}
add-paths: |
client/src/locales/cs.json
client/src/locales/da.json
client/src/locales/de.json
client/src/locales/el.json
client/src/locales/es.json
client/src/locales/fi.json
client/src/locales/fr.json
client/src/locales/hu.json
client/src/locales/id.json
client/src/locales/it.json
client/src/locales/ja.json
client/src/locales/ko.json
client/src/locales/nl.json
client/src/locales/pl.json
client/src/locales/pt.json
client/src/locales/ro.json
client/src/locales/ru.json
client/src/locales/sk.json
client/src/locales/sl.json
client/src/locales/sv.json
client/src/locales/tr.json
client/src/locales/uk.json
client/src/locales/zh.json
client/src/locales/zh-Hant.json
commit-message: |-
i18n(client): sync translations from Crowdin
Keep sparse translated catalogs synchronized with reviewed Crowdin content.
committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
branch: l10n_main
delete-branch: true
base: main
title: "i18n(client): sync translations from Crowdin"
body-path: ${{ runner.temp }}/crowdin-pr-body.md