## Summary
Two robustness fixes to `docs-i18n-pull.yaml` so localized docs can't
silently drift:
1. **Prune orphan localized files.** The pull only adds/updates files,
never deletes — so localized copies of renamed/moved/deleted English
pages linger and serve dead URLs (recently ~113 of them). A new
`prune-orphan-translations` script (run with `--apply` in the workflow,
on real pulls only) removes any `l/<lang>/**` file whose English source
no longer exists.
2. **Surface per-language download failures.** The loop previously
swallowed failures with `|| echo "Warning..."`, so a language whose
Crowdin server-side build fails (e.g. `ja`, failing at 79%) was skipped
*silently* and froze indefinitely while every other language updated. We
now collect failures, still commit the languages that succeeded, and
**fail the run at the end** so a broken language is visible.
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
# Introduction
Getting rid of the fine grained PAT used to dispatch to internal
repositories.
Repo dispatch requires the contents write permissions which is too wide
for such use
Refactored all senders and target to pass through a workflow dispatch
instead
Creating a centralize app that forges a token with actions: write only
provided permissions to mitigate any token exfiltrations
## 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)
## Summary
This PR fixes several small documentation issues in the contributor and
setup guides:
- fixes broken docs links in the root README
- corrects multiple typos and capitalization issues in contributor docs
- fixes malformed Markdown for the Redis command in local setup
- improves wording in the Docker Compose self-hosting guide
## Changes
- updated README installation links to the current docs routes
- changed `Open-source` to `open-source`
- fixed `specially` -> `especially` in the frontend style guide
- normalized `MacOS` -> `macOS`, `powershell` -> `PowerShell`, and
`Postgresql` -> `PostgreSQL`
- replaced the invalid `localhost:5432` Markdown link with inline code
- fixed the malformed fenced code block for `brew services start redis`
- cleaned up Redis naming/capitalization and a few grammar issues in the
setup docs
- improved the warning and environment-variable wording in the Docker
Compose guide
## Testing
- not run; docs-only changes
---------
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
## Summary
- Replaces all `depot-ubuntu-24.04` runners with `ubuntu-latest`
- Replaces all `depot-ubuntu-24.04-8` runners with
`ubuntu-latest-8-cores`
- Updates storybook build cache keys in ci-front.yaml to reflect the
runner name change
Reverts the temporary Depot migration introduced in #18163 / #18179
across all 23 workflow files.
## Summary
- **Fix junction relation toggle not being saved**: The form schema
wasn't tracking the `settings` field, so changes to
`junctionTargetFieldId` weren't marked as dirty
- **Add type-safe documentation paths**: Generate TypeScript constants
from `base-structure.json` to prevent broken documentation links
- **Create many-to-many relations documentation**: Step-by-step guide
for building many-to-many relations using junction objects
- **Update `getDocumentationUrl`**: Now uses shared constants from
`twenty-shared` for base URL, default path, and supported languages
## Key Changes
### Junction Toggle Fix
- Added `settings` field to the form schema in
`SettingsDataModelFieldRelationForm.tsx`
- Fixed the toggle to properly merge settings when updating
`junctionTargetFieldId`
### Type-Safe Documentation Paths
- New constants in `twenty-shared/constants`:
- `DOCUMENTATION_PATHS` - All 161 documentation paths as typed constants
- `DOCUMENTATION_SUPPORTED_LANGUAGES` - 14 supported languages
- `DOCUMENTATION_BASE_URL` / `DOCUMENTATION_DEFAULT_PATH`
- Generator script: `yarn docs:generate-paths`
- CI integration: Added to `docs-i18n-pull.yaml` workflow
### Documentation
- New article:
`/user-guide/data-model/how-tos/create-many-to-many-relations`
- Updated `/user-guide/data-model/capabilities/relation-fields.mdx` with
Lab warning and link
## Test plan
- [ ] Verify junction toggle saves correctly when enabled/disabled
- [ ] Verify documentation link opens correct localized page
- [ ] Verify `yarn docs:generate-paths` regenerates paths correctly
## Summary
This PR reduces clutter at the repository root to improve navigation on
GitHub. The README is now visible much sooner when browsing the repo.
## Changes
### Deleted from root
- `nx` wrapper script → use `npx nx` instead
- `render.yaml` → no longer used
- `jest.preset.js` → inlined `@nx/jest/preset` directly in each
package's jest.config
- `.prettierrc` → moved config to `package.json`
- `.prettierignore` → patterns already covered by `.gitignore`
### Moved/Consolidated
| From | To |
|------|-----|
| `Makefile` | `packages/twenty-docker/Makefile` (merged) |
| `crowdin-app.yml` | `.github/crowdin-app.yml` |
| `crowdin-docs.yml` | `.github/crowdin-docs.yml` |
| `.vale.ini` | `.github/vale.ini` |
| `tools/eslint-rules/` | `packages/twenty-eslint-rules/` |
| `eslint.config.react.mjs` |
`packages/twenty-front/eslint.config.react.mjs` |
## Result
Root items reduced from ~32 to ~22 (folders + files).
## Files updated
- GitHub workflow files updated to reference new crowdin config paths
- Jest configs updated to use `@nx/jest/preset` directly
- ESLint configs updated with new import paths
- `nx.json` updated with new paths
- `package.json` now includes prettier config and updated workspace
paths
- Dockerfile updated with new eslint-rules path
Created by Github action
Pulls the latest documentation translations from Crowdin for all
supported languages:
- French (fr)
- Arabic (ar)
- Czech (cs)
- German (de)
- Spanish (es)
- Italian (it)
- Japanese (ja)
- Korean (ko)
- Portuguese (pt)
- Romanian (ro)
- Russian (ru)
- Turkish (tr)
- Chinese (zh-CN)
---------
Co-authored-by: github-actions <github-actions@twenty.com>
## Summary
The Crowdin GitHub Action was failing at ~54% progress with the error:
> Failed to build translation. Please contact our support team for help
## Root Cause
The build was attempting to process all target languages configured in
Crowdin, including languages not supported by Mintlify (as defined in
`supported-languages.ts`). Some of these unsupported languages had
translation issues causing the build to fail.
## Fix
Added the `download_language` parameter to the Crowdin GitHub Action to
restrict downloads to only the languages supported by Mintlify:
- fr, ar, cs, de, es, it, ja, ko, pt, ro, ru, tr, zh-CN
## Testing
Verified via Crowdin API that builds succeed when specifying only these
supported languages, while the full build fails.