From 2dfa7425439dae1fb16a06ebf9c982bb5452ac1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Mon, 23 Mar 2026 12:53:31 +0100 Subject: [PATCH] chore: improve i18n workflow to prevent stale compiled translations (#18850) ## Summary - **Add `lingui:compile` to Dockerfile** before both the server and frontend build stages, ensuring compiled translation catalogs are always fresh regardless of git state - **Add `repository-dispatch` to i18n workflows** (`i18n-push.yaml` and `i18n-pull.yaml`) to trigger reactive automerge in `twenty-infra` when the i18n PR is ready, replacing the 15-minute polling approach ## Context Users sometimes see "Uncompiled message detected" errors because releases can be cut from `main` before the i18n PR (with freshly compiled translation catalogs) has been merged. This creates a race condition between new translatable strings landing on `main` and their compiled catalogs being available. These changes fix this in two ways: 1. **Safety net in builds**: Every Docker build now compiles translations before building, so even if compiled catalogs in git are stale, the build artifact is always correct 2. **Faster i18n PR merges**: Instead of a 15-minute cron polling for i18n PRs, the workflows now notify `twenty-infra` immediately when translations are ready, reducing merge latency from ~15 minutes to ~1 minute Companion PR in twenty-infra: twentyhq/twenty-infra (feat/i18n-reactive-automerge) ## Test plan - [ ] Verify `TWENTY_INFRA_TOKEN` secret is available to i18n workflows - [ ] Docker build still succeeds with the added `lingui:compile` steps - [ ] i18n-push triggers automerge in twenty-infra after pushing changes - [ ] i18n-pull triggers automerge in twenty-infra after pulling translations Made with [Cursor](https://cursor.com) --- .github/workflows/docs-i18n-pull.yaml | 8 ++++++++ .github/workflows/i18n-pull.yaml | 8 ++++++++ .github/workflows/i18n-push.yaml | 8 ++++++++ packages/twenty-docker/twenty/Dockerfile | 7 +++++++ packages/twenty-emails/project.json | 2 ++ packages/twenty-front/project.json | 2 ++ packages/twenty-server/project.json | 2 ++ 7 files changed, 37 insertions(+) diff --git a/.github/workflows/docs-i18n-pull.yaml b/.github/workflows/docs-i18n-pull.yaml index 40cd4413b07..76ad5b042f3 100644 --- a/.github/workflows/docs-i18n-pull.yaml +++ b/.github/workflows/docs-i18n-pull.yaml @@ -150,3 +150,11 @@ jobs: fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Trigger i18n automerge + if: github.event_name != 'pull_request' && steps.check_changes.outputs.changes_detected == 'true' + uses: peter-evans/repository-dispatch@v2 + with: + token: ${{ secrets.TWENTY_INFRA_TOKEN }} + repository: twentyhq/twenty-infra + event-type: i18n-pr-ready diff --git a/.github/workflows/i18n-pull.yaml b/.github/workflows/i18n-pull.yaml index 27e023af005..6d3cdbf179f 100644 --- a/.github/workflows/i18n-pull.yaml +++ b/.github/workflows/i18n-pull.yaml @@ -138,3 +138,11 @@ jobs: fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Trigger i18n automerge + if: steps.compile_translations.outputs.changes_detected == 'true' + uses: peter-evans/repository-dispatch@v2 + with: + token: ${{ secrets.TWENTY_INFRA_TOKEN }} + repository: twentyhq/twenty-infra + event-type: i18n-pr-ready diff --git a/.github/workflows/i18n-push.yaml b/.github/workflows/i18n-push.yaml index 7b30d98bbe4..2f7229674de 100644 --- a/.github/workflows/i18n-push.yaml +++ b/.github/workflows/i18n-push.yaml @@ -102,3 +102,11 @@ jobs: fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Trigger i18n automerge + if: steps.check_extract_changes.outputs.changes_detected == 'true' || steps.check_compile_changes.outputs.changes_detected == 'true' + uses: peter-evans/repository-dispatch@v2 + with: + token: ${{ secrets.TWENTY_INFRA_TOKEN }} + repository: twentyhq/twenty-infra + event-type: i18n-pr-ready diff --git a/packages/twenty-docker/twenty/Dockerfile b/packages/twenty-docker/twenty/Dockerfile index ed3b82045a7..7c2147dd8f9 100644 --- a/packages/twenty-docker/twenty/Dockerfile +++ b/packages/twenty-docker/twenty/Dockerfile @@ -30,6 +30,11 @@ COPY ./packages/twenty-ui /app/packages/twenty-ui COPY ./packages/twenty-sdk /app/packages/twenty-sdk COPY ./packages/twenty-server /app/packages/twenty-server +RUN npx nx run twenty-server:lingui:extract && \ + npx nx run twenty-server:lingui:compile && \ + npx nx run twenty-emails:lingui:extract && \ + npx nx run twenty-emails:lingui:compile + RUN npx nx run twenty-server:build RUN yarn workspaces focus --production twenty-emails twenty-shared twenty-sdk twenty-server @@ -43,6 +48,8 @@ COPY ./packages/twenty-front /app/packages/twenty-front COPY ./packages/twenty-ui /app/packages/twenty-ui COPY ./packages/twenty-shared /app/packages/twenty-shared COPY ./packages/twenty-sdk /app/packages/twenty-sdk +RUN npx nx run twenty-front:lingui:extract && \ + npx nx run twenty-front:lingui:compile RUN npx nx build twenty-front diff --git a/packages/twenty-emails/project.json b/packages/twenty-emails/project.json index 6f73f1f85e7..57153312595 100644 --- a/packages/twenty-emails/project.json +++ b/packages/twenty-emails/project.json @@ -38,6 +38,7 @@ }, "lingui:extract": { "executor": "nx:run-commands", + "dependsOn": ["^build"], "options": { "cwd": "{projectRoot}", "command": "lingui extract --overwrite --clean" @@ -45,6 +46,7 @@ }, "lingui:compile": { "executor": "nx:run-commands", + "dependsOn": ["^build"], "options": { "cwd": "{projectRoot}", "command": "lingui compile --typescript" diff --git a/packages/twenty-front/project.json b/packages/twenty-front/project.json index c2937e4f03a..380b44cce30 100644 --- a/packages/twenty-front/project.json +++ b/packages/twenty-front/project.json @@ -292,6 +292,7 @@ }, "lingui:extract": { "executor": "nx:run-commands", + "dependsOn": ["^build"], "options": { "cwd": "{projectRoot}", "command": "lingui extract --overwrite --clean" @@ -299,6 +300,7 @@ }, "lingui:compile": { "executor": "nx:run-commands", + "dependsOn": ["^build"], "options": { "cwd": "{projectRoot}", "command": "lingui compile --typescript" diff --git a/packages/twenty-server/project.json b/packages/twenty-server/project.json index 4cef79ce2e2..edb65f0bffe 100644 --- a/packages/twenty-server/project.json +++ b/packages/twenty-server/project.json @@ -279,6 +279,7 @@ }, "lingui:extract": { "executor": "nx:run-commands", + "dependsOn": ["^build"], "options": { "cwd": "{projectRoot}", "command": "lingui extract --overwrite --clean" @@ -286,6 +287,7 @@ }, "lingui:compile": { "executor": "nx:run-commands", + "dependsOn": ["^build"], "options": { "cwd": "{projectRoot}", "command": "lingui compile --typescript"