Step 1: ꯍꯟꯗꯣꯛꯄꯒꯤ ꯄ꯭ꯔꯣꯚꯥꯏꯗꯔ ꯑꯃ ꯈꯜꯂꯨ
ꯑꯦꯛꯁꯟ ꯑꯁꯤ ꯌꯨꯅꯤꯐꯥꯏꯗ ꯑꯦꯄꯤꯑꯥꯏ ꯁꯔꯐꯦꯁ ꯑꯃꯒꯤ ꯃꯅꯤꯡꯗ Azure AI Translator, ꯑꯦ.ꯗꯕꯜꯌꯨ.ꯑꯦꯁ. ꯇ꯭ꯔꯥꯟꯁ꯭ꯂꯦꯠ ꯑꯃꯁꯨꯡ ꯒꯨꯒꯜ ꯀ꯭ꯂꯥꯎꯗ ꯇ꯭ꯔꯥꯟꯁ꯭ꯂꯦꯁꯟ ꯑꯃꯒ ꯂꯣꯏꯅꯅ ꯊꯕꯛ ꯇꯧꯋꯤ꯫ provider ꯏꯟꯄꯨꯠꯀ ꯂꯣꯏꯅꯅ ꯆꯦꯟꯕ ꯑꯃꯗ ꯄ꯭ꯔꯣꯚꯥꯏꯗꯔ ꯑꯃꯈꯛꯇ ꯈꯜꯂꯨ — ꯋꯥꯔ꯭ꯛꯐ꯭ꯂꯣ ꯑꯁꯤ ꯄ꯭ꯔꯣꯚꯥꯏꯗꯔ ꯑꯗꯨ ꯌꯦꯡꯗꯅ ꯆꯞ ꯃꯥꯟꯅꯕ ꯃꯑꯣꯡꯗ ꯇꯧꯋꯤ; ꯁꯛꯇꯥꯛꯁꯤꯡ ꯈꯛꯇ ꯈꯦꯠꯅꯩ꯫ ꯃꯄꯨꯡ ꯐꯥꯅ ꯆꯥꯡꯗꯝꯅꯕꯒꯤꯗꯃꯛꯇ ꯍꯟꯗꯣꯛꯄ ꯄꯤꯔꯤꯕꯁꯤꯡ ꯌꯦꯡꯕꯤꯌꯨ꯫
Step 2: ꯀ꯭ꯔꯦꯗꯦꯟꯁ꯭ꯌꯦꯜꯁꯤꯡ ꯑꯃꯁꯨꯡ ꯋꯥꯔ꯭ꯛꯐ꯭ꯂꯣ ꯑꯃ ꯍꯥꯞꯆꯤꯜꯂꯨ
ꯅꯍꯥꯛꯀꯤ ꯄ꯭ꯔꯣꯚꯥꯏꯗꯔꯒꯤ ꯀ꯭ꯔꯦꯗꯦꯟꯁ꯭ꯌꯦꯜꯁꯤꯡ ꯑꯗꯨ ꯒꯤꯠꯍꯕ ꯔꯤꯄꯣꯁꯤꯇꯔꯤ ꯁꯤꯀ꯭ꯔꯦꯠꯁꯤꯡ ꯑꯣꯏꯅ ꯊꯝꯃꯨ, ꯃꯗꯨꯒꯤ ꯃꯇꯨꯡꯗ .github/workflows/translate.yml ꯁꯦꯝꯃꯨ꯫ ꯃꯁꯤꯒꯤ ꯑꯀꯛꯅꯕ ꯁꯦꯠꯑꯞꯀꯤꯗꯃꯛ ꯃꯈꯥꯗ ꯄꯤꯔꯤꯕ ꯅꯍꯥꯛꯀꯤ ꯄ꯭ꯔꯣꯚꯥꯏꯗꯔ ꯑꯗꯨ ꯈꯜꯂꯨ — ꯂꯦꯝꯍꯧꯔꯤꯕ ꯋꯥꯔ꯭ꯛꯐ꯭ꯂꯣ ꯑꯗꯨ ꯆꯞ ꯃꯥꯟꯅꯩ꯫
Azure AI Translator
ꯑꯦꯓꯨꯔ ꯑꯁꯤ ꯗꯤꯐꯣꯜꯠ ꯄ꯭ꯔꯣꯚꯥꯏꯗꯔꯅꯤ, ꯃꯔꯝ ꯑꯗꯨꯅ provider ꯂꯧꯊꯣꯛꯄ ꯌꯥꯏ꯫ ꯑꯦꯓꯨꯔ ꯄꯣꯔꯇꯦꯜꯗ ꯑꯦꯓꯨꯔ ꯑꯦꯑꯥꯏ ꯇ꯭ꯔꯥꯟꯁ꯭ꯂꯦꯇꯔ ꯔꯤꯁꯣꯔꯁ ꯑꯃ ꯄꯤꯌꯨ, ꯃꯗꯨꯒꯤ ꯃꯇꯨꯡꯗ ꯃꯁꯤꯒꯤ ꯀ꯭ꯔꯦꯗꯦꯟꯁ꯭ꯌꯦꯜꯁꯤꯡ ꯊꯝꯃꯨ:
ꯍꯥꯏꯔꯤꯕꯁꯤꯡ ꯑꯁꯤ ꯔꯤꯄꯣꯁꯤꯇꯔꯤ ꯁꯤꯀ꯭ꯔꯦꯠꯁ ꯑꯣꯏꯅ ꯊꯝꯃꯨ
TRANSLATOR_KEY— ꯔꯤꯁꯣꯔꯁ ꯑꯗꯨꯒꯤ ꯁꯕꯁ꯭ꯀ꯭ꯔꯤꯞꯁꯟ ꯀꯤ.TRANSLATOR_ENDPOINT— ꯔꯤꯖꯅꯦꯜ ꯑꯦꯟꯗꯄꯣꯏꯟꯠ ꯌꯨ.ꯑꯥꯔ.ꯑꯦꯜ.TRANSLATOR_REGION— ꯔꯤꯁꯣꯔꯁꯀꯤ ꯑꯦꯓꯨꯔ ꯃꯐꯝ.
ꯋꯥꯔ꯭ꯛꯐ꯭ꯂꯣ ꯍꯥꯞꯆꯤꯜꯂꯨ
name: translate
on: push: branches: [main] paths: - "src/**/*.en.resx" - "src/**/*.en.json"
permissions: contents: write pull-requests: write
jobs: translate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - id: translate uses: IEvangelist/resource-translator@v3 with: provider: | azure: subscriptionKey: ${{ secrets.TRANSLATOR_KEY }} endpoint: ${{ secrets.TRANSLATOR_ENDPOINT }} region: ${{ secrets.TRANSLATOR_REGION }} sourceLocale: en toLocales: '["fr","de","es"]' - if: steps.translate.outputs.has-new-translations == 'true' uses: peter-evans/create-pull-request@v7 with: title: ${{ steps.translate.outputs.summary-title }} body: ${{ steps.translate.outputs.summary-details }} branch: machine-translationꯑꯦ.ꯗꯕꯜꯌꯨ.ꯑꯦꯁ. ꯇ꯭ꯔꯥꯟꯁ꯭ꯂꯦꯠ
provider aws ꯍꯥꯏꯅ ꯊꯝꯃꯨ꯫ ꯃꯇꯝ ꯁꯥꯡꯅ ꯍꯤꯡꯕ ꯑꯔꯣꯟꯕ ꯄꯣꯠꯁꯛ ꯑꯃꯠꯇ ꯊꯝꯖꯤꯟꯗꯅꯕ ꯑꯣ.ꯑꯥꯏ.ꯗꯤ.ꯁꯤ.ꯒꯤ ꯈꯨꯠꯊꯥꯡꯗ ꯑꯣ.ꯑꯥꯏ.ꯗꯤ.ꯁꯤ. aws-actions/configure-aws-credentials ꯄꯥꯝꯕꯤꯌꯨ — ꯈꯣꯡꯊꯥꯡ ꯃꯄꯥꯟꯗ ꯊꯥꯗꯣꯛꯄ ꯑꯁꯤ ꯑꯗꯣꯝꯒꯤꯗꯃꯛꯇ AWS_REGION꯫ ꯃꯗꯨꯒꯤ ꯃꯍꯨꯠꯇ ꯁ꯭ꯇꯦꯇꯤꯛ ꯀꯤꯁꯤꯡ ꯁꯤꯖꯤꯟꯅꯅꯕ, ꯁ꯭ꯇꯣꯔ:
ꯍꯥꯏꯔꯤꯕꯁꯤꯡ ꯑꯁꯤ ꯔꯤꯄꯣꯁꯤꯇꯔꯤ ꯁꯤꯀ꯭ꯔꯦꯠꯁ ꯑꯣꯏꯅ ꯊꯝꯃꯨ
AWS_ACCESS_KEY_ID— ꯅꯍꯥꯛꯀꯤ ꯑꯦ.ꯗꯕꯜꯌꯨ.ꯑꯦꯁ. ꯑꯦꯛꯁꯦꯁ ꯀꯤ ꯑꯥꯏ.ꯗꯤ.AWS_SECRET_ACCESS_KEY— ꯅꯍꯥꯛꯀꯤ ꯑꯦ.ꯗꯕꯜꯌꯨ.ꯑꯦꯁ. ꯁꯤꯀ꯭ꯔꯦꯠ ꯑꯦꯛꯁꯦꯁ ꯀꯤ꯫
ꯃꯐꯝ ꯑꯃ ꯃꯇꯝ ꯄꯨꯝꯅꯃꯛꯇ ꯃꯊꯧ ꯇꯥꯏ — ꯃꯗꯨꯗ awsRegion ꯅꯠꯇ꯭ꯔꯒ AWS_REGION ꯑꯀꯣꯏꯕꯒꯤ ꯑꯍꯣꯡꯕ ꯌꯥꯎꯔꯒ ꯊꯝꯃꯨ꯫
ꯋꯥꯔ꯭ꯛꯐ꯭ꯂꯣ ꯍꯥꯞꯆꯤꯜꯂꯨ
name: translate
on: push: branches: [main] paths: - "src/**/*.en.resx" - "src/**/*.en.json"
permissions: id-token: write # for aws-actions/configure-aws-credentials (OIDC) contents: write pull-requests: write
jobs: translate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::123456789012:role/gh-actions-translate aws-region: us-east-1 - id: translate uses: IEvangelist/resource-translator@v3 with: provider: | aws: region: us-east-1 # or rely on AWS_REGION from the step above formality: FORMAL brevity: true sourceLocale: en toLocales: '["fr","de","es"]' - if: steps.translate.outputs.has-new-translations == 'true' uses: peter-evans/create-pull-request@v7 with: title: ${{ steps.translate.outputs.summary-title }} body: ${{ steps.translate.outputs.summary-details }} branch: machine-translationꯒꯨꯒꯜ ꯀ꯭ꯂꯥꯎꯗ ꯇ꯭ꯔꯥꯟꯁ꯭ꯂꯦꯁꯟ
provider google ꯍꯥꯏꯅ ꯊꯝꯃꯨ꯫ ꯁꯔꯚꯤꯁ-ꯑꯦꯀꯥꯎꯟꯠ JSON ꯀ꯭ꯔꯦꯗꯦꯟꯁ꯭ꯌꯦꯜ ꯅꯠꯇ꯭ꯔꯒ ꯑꯦꯄꯤꯑꯥꯏ ꯀꯤ ꯑꯃꯅ ꯑꯣꯊꯦꯟꯇꯤꯀꯦꯠ ꯇꯧꯕꯤꯌꯨ — ꯆꯞ ꯆꯥꯅ ꯑꯃ ꯄꯤꯌꯨ:
ꯍꯥꯏꯔꯤꯕꯁꯤꯡ ꯑꯁꯤ ꯔꯤꯄꯣꯁꯤꯇꯔꯤ ꯁꯤꯀ꯭ꯔꯦꯠꯁ ꯑꯣꯏꯅ ꯊꯝꯃꯨ
GCP_TRANSLATE_CREDENTIALS— ꯁꯔꯚꯤꯁ-ꯑꯦꯀꯥꯎꯟꯠ JSON ꯀꯤ (JSON string ꯑꯣꯏꯅ).GCP_TRANSLATE_API_KEY— ꯅꯠꯇ꯭ꯔꯒ ꯒꯨꯒꯜ ꯀ꯭ꯂꯥꯎꯗ ꯑꯦꯄꯤꯑꯥꯏ ꯀꯤ ꯑꯃꯥ꯫
ꯑꯣꯞꯁꯅꯦꯜ googleProjectId ꯑꯃ ꯌꯥꯎꯗꯕ ꯃꯇꯝꯗ ꯀ꯭ꯔꯦꯗꯦꯟꯁ꯭ꯌꯦꯜ ꯑꯗꯨꯗꯒꯤ ꯂꯧꯅꯩ ꯫
ꯋꯥꯔ꯭ꯛꯐ꯭ꯂꯣ ꯍꯥꯞꯆꯤꯜꯂꯨ
name: translate
on: push: branches: [main] paths: - "src/**/*.en.resx" - "src/**/*.en.json"
permissions: contents: write pull-requests: write
jobs: translate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - id: translate uses: IEvangelist/resource-translator@v3 with: provider: | google: # Provide EITHER a service-account JSON credential... credentials: ${{ secrets.GCP_TRANSLATE_CREDENTIALS }} # ...OR an API key: # apiKey: ${{ secrets.GCP_TRANSLATE_API_KEY }} model: nmt sourceLocale: en toLocales: '["fr","de","es"]' - if: steps.translate.outputs.has-new-translations == 'true' uses: peter-evans/create-pull-request@v7 with: title: ${{ steps.translate.outputs.summary-title }} body: ${{ steps.translate.outputs.summary-details }} branch: machine-translationStep 3: ꯁꯣꯔꯁ ꯔꯤꯁꯣꯔꯁ ꯐꯥꯏꯜ ꯑꯃ ꯀꯝꯃꯤꯠ ꯇꯧ
ꯔꯤꯁꯣꯔꯁ ꯐꯥꯏꯜꯁꯤꯡꯅ Name.<sourceLocale>.<ext> ꯀꯟꯚꯦꯟꯁꯟ ꯁꯤꯖꯤꯟꯅꯩ꯫ ꯈꯨꯗꯝ ꯑꯣꯏꯅ Greetings.en.resx ꯆꯦꯟꯕ ꯃꯇꯨꯡꯗ Greetings.fr.resx, Greetings.de.resx ꯑꯃꯁꯨꯡ ꯑꯁꯤꯅꯆꯤꯡꯕ ꯑꯣꯏꯔꯛꯏ꯫
Step 4: Let smart change detection protect your bill
changeDetection defaults to smart and stores a compact .github/resource-translator-state.json manifest in the repo. Commit that file so future runs can reuse stable translations, preserve manual target edits, and send only new, missing, changed, or settings-invalidated keys to the provider. If localized files already exist, run once with snapshotOnly: true to create the manifest without provider calls.
Step 5: ꯑꯥꯎꯠꯄꯨꯠ ꯑꯗꯨ ꯌꯦꯡꯁꯤꯜꯂꯨ
ꯋꯥꯔ꯭ꯛꯐ꯭ꯂꯣ ꯑꯗꯨ ꯍꯦꯛ ꯂꯣꯏꯔꯕ ꯃꯇꯨꯡꯗ, ꯑꯦꯛꯁꯟ ꯑꯗꯨꯅ ꯅꯍꯥꯛꯅ ꯄꯤ.ꯑꯥꯔ. ꯗꯤꯁꯀ꯭ꯔꯤꯞꯁꯟ ꯑꯃꯗ ꯋꯥꯌꯔ ꯇꯧꯕ ꯌꯥꯕ ꯑꯥꯎꯠꯄꯨꯠ ꯑꯍꯨꯝ ꯎꯠꯊꯣꯛꯏ: summary-title, summary-details, ꯑꯃꯁꯨꯡ has-new-translations꯫ ꯃꯁꯤꯅ ꯊꯕꯛ ꯑꯗꯨꯒꯤ ꯂꯃꯥꯏꯗ ꯃꯥꯔꯛꯗꯥꯎꯟ ꯁꯝꯂꯞꯁꯨ ꯏ core.summary ꯫