Crowdin Synchronization Workflow for i18n in OpenLogi: Automated Translation Management
OpenLogi maintains perfect locale key parity through a GitHub Actions workflow that uploads English source strings to Crowdin, downloads sparse translations, and merges them back using a custom Python script to ensure every locale file contains the exact same key set as en.toml.
The AprilNEA/OpenLogi repository implements a fully automated Crowdin synchronization workflow for i18n that keeps UI translations synchronized while guaranteeing semantic consistency across all supported languages. This system ensures that crates/openlogi-ui/locales/en.toml serves as the single source of truth, with automated processes verifying that every locale file maintains identical key structures regardless of translation completion status.
How the Crowdin Synchronization Workflow Works
The automation is driven by .github/workflows/crowdin.yml, which orchestrates a nine-step process to synchronize translations without human intervention.
Trigger Conditions
The workflow initiates on a daily schedule or whenever critical files change. According to the on section of the workflow configuration, it monitors:
crates/openlogi-ui/locales/en.toml— the English source catalog.config/crowdin.yml— Crowdin configuration mappings.github/scripts/i18n/**— the merge script utilities
This ensures the pipeline executes immediately when developers modify the source of truth or the synchronization tooling itself.
Snapshot and Authentication
Before contacting Crowdin, the workflow establishes secure credentials and baselines the current state:
-
Authentication: The action mints a GitHub App token to enable branch creation and pull request generation, bypassing the default
GITHUB_TOKENlimitations. -
Credential Retrieval: The Crowdin project ID and personal token are fetched from 1Password, ensuring secrets remain encrypted.
-
Self-Test: The helper script
merge_crowdin_download.pyruns with--self-testto verify its internal logic before processing live data. -
Snapshot Creation: All existing locale TOML files are copied to
/tmp/openlogi-locales-before, creating a "merge base" that represents the complete key set before any Crowdin modifications.
Upload, Download, and Merge
The core synchronization uses the official Crowdin GitHub Action with a specific sparse export strategy:
- Upload: Pushes the current
en.tomlto Crowdin as the source of truth - Seed: Uploads existing translations from the repository so Crowdin learns current progress
- Download: Requests a sparse export with
skip_untranslated_strings: true, which omits untranslated keys from the downloaded files
After download, the merge script restores key parity:
python3 .github/scripts/i18n/merge_crowdin_download.py \
--before /tmp/openlogi-locales-before \
--locales crates/openlogi-ui/locales \
--en crates/openlogi-ui/locales/en.toml
This invocation preserves the snapshot directory as reference, applies downloaded translations only where values differ from English, and restores any keys omitted by the sparse export.
Branch Creation and Pull Request
If git diff detects changes after the merge, the workflow:
- Creates a branch named
crowdin/i18n - Commits the updated locale files
- Pushes the branch using the minted GitHub App token
- Opens a pull request titled "chore(i18n): sync Crowdin translations"
The PR description explicitly notes that en.toml drives parity and that the merge guarantees semantic-key alignment across locales.
Maintaining Locale Key Parity
OpenLogi employs a multi-layered defense against key drift, ensuring every locale file contains exactly the same keys as the English source.
Source-of-Truth Principle
crates/openlogi-ui/locales/en.toml serves as the single source of truth for all translation keys. Developers must add new keys to this file first; the synchronization pipeline propagates these keys to other locales automatically. This strict hierarchy prevents fragmented keysets across different language files.
Automated Parity Testing
The crate includes crates/openlogi-ui/tests/catalog_parity.rs, a dedicated CI test that loads every locale TOML file and asserts that the key set exactly matches en.toml:
#[test]
fn catalog_parity() {
let en = i18n::load("crates/openlogi-ui/locales/en.toml");
for locale_path in glob::glob("crates/openlogi-ui/locales/*.toml").unwrap() {
let locale = i18n::load(&locale_path.unwrap().to_string_lossy());
assert_eq!(en.keys(), locale.keys(),
"Locale {} does not have the same keys as en.toml", locale_path);
}
}
This test executes on every CI run, catching accidental key mismatches before they reach production.
The Merge Script Strategy
The merge_crowdin_download.py script guarantees parity even when Crowdin's sparse export removes untranslated keys. By comparing the downloaded files against the pre-sync snapshot stored in /tmp/openlogi-locales-before, the script re-inserts any missing keys while preserving translated values. This ensures the repository never contains a locale with a divergent key set, regardless of translation completion rates.
Running the Workflow Locally
Developers can debug the synchronization process or manually merge Crowdin exports using the following procedure.
First, create a snapshot of current catalogs:
mkdir -p /tmp/openlogi-locales-before
cp crates/openlogi-ui/locales/*.toml /tmp/openlogi-locales-before/
After downloading translations from Crowdin (via their web interface or CLI), run the merge script:
python3 .github/scripts/i18n/merge_crowdin_download.py \
--before /tmp/openlogi-locales-before \
--locales crates/openlogi-ui/locales \
--en crates/openlogi-ui/locales/en.toml
This local execution follows the exact logic used in .github/workflows/crowdin.yml, making it useful for troubleshooting merge conflicts or verifying sparse export handling.
Summary
- Automated Triggers: The workflow runs daily or when
en.toml,.config/crowdin.yml, or merge scripts change - Sparse Export Handling: Uses
skip_untranslated_strings: trueto reduce download size, then restores missing keys viamerge_crowdin_download.py - Key Parity Guarantee: The merge script compares against pre-sync snapshots to ensure every locale matches the English key set
- CI Enforcement:
tests/catalog_parity.rsasserts that all locales contain identical keys toen.toml - Manual Debugging: The merge script supports local execution with
--before,--locales, and--enparameters
Frequently Asked Questions
What triggers the Crowdin synchronization workflow in OpenLogi?
The workflow triggers on a daily schedule and whenever files in three specific paths change: crates/openlogi-ui/locales/en.toml (the English source), .config/crowdin.yml (Crowdin configuration), or any file in .github/scripts/i18n/ (the merge utilities). This ensures immediate synchronization when developers modify the source catalog or when the automation tooling itself updates.
How does OpenLogi prevent missing translation keys when using Crowdin's sparse export?
OpenLogi uses a snapshot-and-merge strategy. Before downloading from Crowdin, the workflow copies all existing locale files to /tmp/openlogi-locales-before. Even though Crowdin's skip_untranslated_strings: true setting omits untranslated keys from downloads, the merge_crowdin_download.py script restores these missing entries from the snapshot while keeping newly translated values. This guarantees that no keys disappear from locale files, maintaining parity with the English source.
What is the role of the merge_crowdin_download.py script?
The script at .github/scripts/i18n/merge_crowdin_download.py serves as the parity enforcement engine. It accepts three arguments: --before (the snapshot directory), --locales (the target locale directory), and --en (the English source file). The script ensures that every locale file ends up with the exact same key set as the English catalog, inserting missing keys from the snapshot and only keeping translation values that differ from the English source. It also supports --self-test for validating its internal logic before network operations.
How does OpenLogi verify that all locale files maintain key parity with the English source?
The repository includes a Rust integration test in crates/openlogi-ui/tests/catalog_parity.rs that executes during CI. This test loads en.toml and compares its key set against every other locale file in the crates/openlogi-ui/locales/ directory. If any locale contains extra or missing keys compared to the English source, the test fails immediately, preventing merges that would break translation consistency.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →