Automating localization with DotNetResourcesExtract and CI/CD
Overview
Use DotNetResourcesExtract (or similar .NET resource-extraction tools) to pull .resx/.resources from builds, send them to translators or translation services, then push translated files back into the repo and rebuild via CI/CD so localized artifacts are produced automatically.
Recommended pipeline (presumes a dotnet CLI tool like DotNetResourcesExtract)
- Build and package
- CI job builds the project (dotnet build) and produces assemblies containing embedded resources.
- Extract resources
- Run DotNetResourcesExtract to list and extract resource files to a workspace folder.
- Example CLI step:
dotnet-extract -s ./artifacts -d ./extracted -p .Resources.
- Normalize & validate
- Convert extracted binary .resources to editable .resx or .po as needed (use resgen or custom converter).
- Run schema/placeholder checks and unit tests on resource keys.
- Send for translation
- Push extracted files to a translation management system (TMS) via API, or create a PR in a localization branch for human translators.
- Tag files with language codes and metadata (context, character limits).
- Import translated files
- When translations complete, fetch translated .resx/.resources from TMS or apply PR merges into a localization branch.
- Run automated validation (missing keys, placeholder mismatches, string length checks).
- Merge & build localized artifacts
- CI triggers on merge to main/localization branch: place translated .resx into appropriate folders (e.g., Resources.fr.resx), rebuild, and produce localized packages (nuget, installers, docker images).
- Automated testing & release
- Run UI/text snapshot tests and smoke tests for each locale.
- On success, publish localized artifacts or create release bundles per locale.
CI/CD implementation tips
- Separate pipeline stages: build → extract → translate → import → validate → build-localized → test → publish.
- Use branches or tags for localization batches to keep work isolated until validated.
- Store artifacts between jobs (CI artifacts or object storage) so extraction and translation steps are reproducible.
- Automate conversions: include resgen or custom scripts to convert .resources ↔ .resx and to normalize encodings.
- Validation scripts: enforce key parity, placeholder consistency ({0}, %s), ICU format checks, and max-length constraints.
- Fail fast: reject merges or releases when validation errors exist; surface clear error messages.
- Parallelize builds: run per-locale builds in parallel to reduce CI time.
- Secrets & access: store TMS/API keys in CI secret store; limit write access to localization branches.
Example GitHub Actions snippet (conceptual)
Code
jobs: extract:runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: dotnet build -c Release - run: dotnet tool install -g dotnet-extract - run: dotnet-extract -s ./bin/Release -d ./extracted - uses: actions/upload-artifact@v4 with: name: extracted-resources path: ./extracted(Continue with jobs for send-to-TMS, import-translations, validate, and build-localized.)
Monitoring & maintenance
- Track translation throughput and common validation failures.
- Periodically update extraction tool and converters to match .NET runtime changes.
- Keep a canonical source of truth for keys (single-responsibility resource files) to reduce churn.
If you want, I can generate a ready-to-use GitHub Actions workflow (full YAML) for a specific repo layout and target locales.
Leave a Reply