Files
twenty/.github/workflows/ci-utils-test.yaml
Abdul Rahman 9ec11bd7aa fix: repair escaped inline-code tags in Crowdin docs translations (#24397)
## Why

Crowdin's `mdx_v2` parser HTML-escapes tags inside inline code
(`\`<path>\`` → `\`&lt;path&gt;\``). `exclude_code_blocks` only protects
fenced blocks, so one escaped span fails the **entire language build**
and every other translated page in that language goes stale.

This PR adds a repair for that, and puts it in a small rule-based
normalizer instead of a third one-off script. The existing
escaped-unicode fixer (`fix-crowdin-translations.ts`, used by the app
pull) is folded into the same engine so the next corruption class is a
~4-line rule, not another script plus workflow step.

## What landed

**New — docs inline-code repair**
- Rule `escaped-inline-code-tags`: detect/unescape `&lt;`/`&gt;`
(including hex/numeric entities) **only inside backtick spans**, so a
literal `<` in prose is left alone.
- Wired into `docs-i18n-pull.yaml` after pre-translate and before
download (`--project=2 --rules=escaped-inline-code-tags`). Non-blocking.

**Also — consolidate the existing unicode fixer**
- Rule `escaped-unicode` replaces `fix-crowdin-translations.ts`
(deleted).
- App `i18n-pull.yaml` now calls the shared CLI (`--project=1
--rules=escaped-unicode`).

**Shared engine (`packages/twenty-utils/crowdin-normalizer/`)**
- One export per file: rules, Crowdin client helpers, CLI orchestrator.
- Reads the **exported** translation (not stale suggestions).
- Add-before-delete, so a failed re-add cannot leave a string empty;
partial failures exit non-zero.
- `--project` and `--rules` are required. Dry-run unless `--apply`.
- `nx test twenty-utils` plus `ci-utils-test.yaml` on `pull_request`
(`contents: read`), kept separate from `ci-utils.yaml`
(`pull_request_target`).

## Testing

- Unit tests pin: unescape only inside inline-code spans, prose entities
untouched, unicode restoration, idempotent rules, concurrency helper.
- Controlled injection on docs (project 2): injected `&lt;...&gt;` →
dry-run found 1 → `--apply` restored the original → follow-up scan 0.
- Live unicode dry-run on app (project 1): flagged real cases such as
`S\u00f6k` → `Sök`.
2026-08-21 13:26:17 +00:00

46 lines
1.1 KiB
YAML

name: CI Utils Test
permissions:
contents: read
on:
push:
branches:
- main
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
packages/twenty-utils/**
utils-test:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 10
- name: Install dependencies
uses: ./.github/actions/yarn-install
- name: Run utils tests
run: npx nx test twenty-utils
ci-utils-test-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
needs: [changed-files-check, utils-test]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1