Skip to content

Commit 3fe0354

Browse files
authored
ci: Add new translation workflow for releases (#29495)
## **Description** Two new CI workflows have been added for uploading localized messages from releaase branches, and downloading translations onto releaase branches. Today we only use `main` as the source for localized messages, and all translations go through `main` first, then get cherry-picked onto the current RC. This process risks the translations getting out-of-sync with the sources on the current release (since they're derived from the localized message sources on `main`), which could cause severe localization errors. This process is also time-consuming for the delivery team. These updated workflows bypass that problem completely. Translations will always be in-sync on release branches, and we will have no conflicts. In the future this will run on a schedule, but it's just configured for manual workflow dispatch for now, so that we can test it further. ## **Changelog** CHANGELOG entry: N/A ## **Related issues** This is adapted from an older experiment: #8565 ## **Manual testing steps** This can't easily be tested (we'd have to setup a fork of the repo, and a new crowdin project, and new secrets, etc.). Instead it's configured to be run manually on targeted branches, so that we can test this after merge with minimal disruption. ## **Screenshots/Recordings** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Introduces new GitHub Actions that can create/commit translation PRs across release branches using a PAT, so misconfiguration could affect release branch contents and CI triggering (though currently `dryrun_action: true` limits impact). > > **Overview** > Adds two manually-triggered Crowdin GitHub Actions workflows for release candidates. > > `crowdin-rc-upload-sources.yml` uploads localization source strings from the current branch to the matching Crowdin branch. > > `crowdin-rc-download-translations.yml` downloads *approved* translations and opens per-branch localization PRs; when run on `main` it first discovers open `release/x.y.z` PR branches targeting `stable` and runs across them via a matrix, otherwise it runs only for the current branch. Both workflows use `METAMASKBOT_CROWDIN_TOKEN` and are currently configured in `dryrun_action` mode. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit ced3104. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 4711432 commit 3fe0354

2 files changed

Lines changed: 121 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: Crowdin Download Approved RC Translations
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
find-rc-branches:
8+
name: Find release candidate branches
9+
if: ${{ github.ref_name == 'main' }}
10+
runs-on: ubuntu-latest
11+
permissions:
12+
pull-requests: read
13+
outputs:
14+
branches: ${{ steps.find-branches.outputs.branches }}
15+
steps:
16+
- name: Find release candidate branches
17+
id: find-branches
18+
uses: actions/github-script@v9
19+
with:
20+
github-token: ${{ secrets.GITHUB_TOKEN }}
21+
script: |
22+
const { data: prs } = await github.rest.pulls.list({
23+
owner: context.repo.owner,
24+
repo: context.repo.repo,
25+
base: 'stable',
26+
state: 'open',
27+
});
28+
29+
const releaseBranchRegex = /^release\/[0-9]+\.[0-9]+\.[0-9]+$/;
30+
31+
const branches = prs
32+
.map((pr) => pr.head.ref)
33+
.filter((branchName) => releaseBranchRegex.test(branchName));
34+
35+
core.info(`Found release branches: ${branches.join(',')}`);
36+
core.setOutput('branches', JSON.stringify(branches));
37+
38+
39+
download-translations:
40+
name: Download translations
41+
# Use `!cancelled()` to ensure this runs even when `find-rc-branches` is skipped
42+
if: ${{ !cancelled() }}
43+
needs: [find-rc-branches]
44+
runs-on: ubuntu-latest
45+
timeout-minutes: 3
46+
47+
strategy:
48+
matrix:
49+
# If run on `main`, we download translations for all RCs
50+
# If run on a non-default branch, we just download translations for that individual branch
51+
branch: >-
52+
${{
53+
github.ref_name == 'main' &&
54+
fromJson(needs.find-rc-branches.outputs.branches) ||
55+
fromJson(format('[{0}]', github.ref_name))
56+
}}
57+
58+
steps:
59+
- name: Checkout
60+
uses: actions/checkout@v3
61+
with:
62+
ref: ${{ matrix.branch }}
63+
# Use PAT to ensure that the commit later can trigger status check workflows
64+
token: ${{ secrets.METAMASKBOT_CROWDIN_TOKEN }}
65+
66+
- name: crowdin download approved translations
67+
uses: crowdin/github-action@a3160b9e5a9e00739392c23da5e580c6cabe526d
68+
with:
69+
upload_sources: false
70+
upload_translations: false # disabled to prevent translations overwriting Blends translations
71+
download_translations: true # created separate action to pull down completed translations
72+
export_only_approved: true
73+
74+
crowdin_branch_name: ${{ matrix.branch }}
75+
pull_request_base_branch_name: ${{ matrix.branch }}
76+
localization_branch_name: l10n_crowdin_translations_${{ matrix.branch }}
77+
pull_request_title: 'chore: New Crowdin Translations for ${{ matrix.branch }}'
78+
skip_ref_checkout: true
79+
# This will be in dry-run mode until after we've tested this on `main`
80+
dryrun_action: true
81+
82+
github_user_name: metamaskbot
83+
github_user_email: metamaskbot@users.noreply.github.com
84+
env:
85+
GITHUB_TOKEN: ${{ secrets.METAMASKBOT_CROWDIN_TOKEN }}
86+
GITHUB_ACTOR: metamaskbot
87+
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
88+
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Crowdin Upload RC Sources
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
upload-sources:
8+
runs-on: ubuntu-latest
9+
timeout-minutes: 3
10+
11+
steps:
12+
- name: Checkout
13+
uses: actions/checkout@v3
14+
with:
15+
# Use PAT to ensure that the commit later can trigger status check workflows
16+
token: ${{ secrets.METAMASKBOT_CROWDIN_TOKEN }}
17+
18+
- name: crowdin upload sources
19+
uses: crowdin/github-action@a3160b9e5a9e00739392c23da5e580c6cabe526d
20+
with:
21+
crowdin_branch_name: ${{ github.ref_name }}
22+
upload_sources: true
23+
upload_translations: false # disabled to prevent translations overwriting Blends translations
24+
download_translations: false # created separate action to pull down completed translations
25+
# This will be in dry-run mode until after we've tested this on `main`
26+
dryrun_action: true
27+
github_user_name: metamaskbot
28+
github_user_email: metamaskbot@users.noreply.github.com
29+
env:
30+
GITHUB_TOKEN: ${{ secrets.METAMASKBOT_CROWDIN_TOKEN }}
31+
GITHUB_ACTOR: metamaskbot
32+
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
33+
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}

0 commit comments

Comments
 (0)