From c4b4b64985241acb6c44e4249dd3f3316909f552 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Thu, 5 Dec 2024 08:23:14 -0600 Subject: [PATCH] Automated, scheduled crowdin sync (#7272) * chore: add wip action * feat: automated crowdin sync * add dry run, workflow_dispatch * rename token * add mention of translation deployment * Update .github/workflows/translations-sync.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Brian Muenzenmeyer * docs: clarified our translation flows * separate translation source upload from download * Update TRANSLATION.md Co-authored-by: Michael Esteban Signed-off-by: Brian Muenzenmeyer * Update .github/workflows/translations-sync.yml Co-authored-by: Claudio W Signed-off-by: Brian Muenzenmeyer * Update .github/workflows/translations-upload.yml Co-authored-by: Claudio W Signed-off-by: Brian Muenzenmeyer --------- Signed-off-by: Brian Muenzenmeyer Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Michael Esteban Co-authored-by: Claudio W --- ...ml => translations-pr-lint-and-format.yml} | 3 +- .github/workflows/translations-sync.yml | 54 +++++++++++++++++++ .github/workflows/translations-upload.yml | 41 ++++++++++++++ TRANSLATION.md | 9 ++++ crowdin.yml | 6 +-- 5 files changed, 108 insertions(+), 5 deletions(-) rename .github/workflows/{translations-pr.yml => translations-pr-lint-and-format.yml} (97%) create mode 100644 .github/workflows/translations-sync.yml create mode 100644 .github/workflows/translations-upload.yml diff --git a/.github/workflows/translations-pr.yml b/.github/workflows/translations-pr-lint-and-format.yml similarity index 97% rename from .github/workflows/translations-pr.yml rename to .github/workflows/translations-pr-lint-and-format.yml index f3dce60376045..681d9a6108538 100644 --- a/.github/workflows/translations-pr.yml +++ b/.github/workflows/translations-pr-lint-and-format.yml @@ -1,7 +1,8 @@ # This Workflow is used to comment on PRs that have changes that touch Translated Files # and then comments on their PRs mentioning that they should not do so +# It also formats incoming content because it is often not adherent to our rules post-translation. -name: Crowdin Checks +name: Incoming Translation Checks on: pull_request_target: diff --git a/.github/workflows/translations-sync.yml b/.github/workflows/translations-sync.yml new file mode 100644 index 0000000000000..2c492b2da07f4 --- /dev/null +++ b/.github/workflows/translations-sync.yml @@ -0,0 +1,54 @@ +# This action automates the synchronization of our crowdin translations, so that a human does not need to kick it off from the crowdin UI +# See translations-upload.yml for automation to upload our source content +# See translations-pr-lint-and-format.yml for quality control we conduct on ingress of new translations. +name: Crowdin Download + +on: + workflow_dispatch: # Allow running when we want to, for events such as urgent translation mistakes or 100% completed languages + schedule: + - cron: '0 5 * * 5' # At 05:00 on Fridays. This guarantees that we have the 72 hour weekend time to review translations. + +# Cancel any runs on the same branch +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + # These permissions required by `crowdin/github-action` + contents: write + pull-requests: write + +jobs: + synchronize-with-crowdin: + runs-on: ubuntu-latest + + steps: + - name: Harden Runner + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + with: + egress-policy: audit + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + # see all the options at https://github.com/crowdin/github-action + - name: crowdin action + uses: crowdin/github-action@2d540f18b0a416b1fbf2ee5be35841bd380fc1da # v2.3.0 + with: + # do not upload anything - this is a one-way operation download + upload_sources: false + upload_translations: false + # the rest of this controls how the PR comes in with new translations + download_translations: true + localization_branch_name: chore/crowdin + create_pull_request: true + pull_request_title: '[automated]: crowdin sync' + pull_request_body: 'New Crowdin translations from the [Node.js Crowdin project](https://crowdin.com/project/nodejs-web)' + pull_request_labels: github_actions:pull-request + commit_message: 'chore: synced translations from crowdin [skip ci]' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # A numeric ID, found at https://crowdin.com/project/nodejs-web/tools/api + CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} + # Created from https://crowdin.com/settings#api-key logged in using nodejs-crowdin-bot + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} diff --git a/.github/workflows/translations-upload.yml b/.github/workflows/translations-upload.yml new file mode 100644 index 0000000000000..5344797cb67d8 --- /dev/null +++ b/.github/workflows/translations-upload.yml @@ -0,0 +1,41 @@ +# This action automates the upload of our source content to crowdin. +# See translations-sync.yml for the automation to download new translations on a schedule +# See translations-pr-lint-and-format.yml for quality control we conduct on ingress of new translations. +name: Crowdin Upload + +on: + push: + branches: [main] + +# Cancel any runs on the same branch +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + upload-to-crowdin: + runs-on: ubuntu-latest + + steps: + - name: Harden Runner + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + with: + egress-policy: audit + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + # see all the options at https://github.com/crowdin/github-action + - name: crowdin action + uses: crowdin/github-action@2d540f18b0a416b1fbf2ee5be35841bd380fc1da # v2.3.0 + with: + # only upload sources, ensuring this is a one-way operation + upload_sources: true + upload_translations: false + download_translations: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # A numeric ID, found at https://crowdin.com/project/nodejs-web/tools/api + CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} + # Created from https://crowdin.com/settings#api-key logged in using nodejs-crowdin-bot + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} diff --git a/TRANSLATION.md b/TRANSLATION.md index 8f5ccd89efaf3..fa36471837cc6 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -87,3 +87,12 @@ Translation Keys should not be translated during Unit Testing. If your Component - Unit Tests should not rely on text, titles, or string bags, as these texts will change arbitrarily and make the test suite fail. - In this case, you should test your component by aria-text, or other `aria-*` attributes or even by class names or other artifacts. - Visual Regression Testing is recommended to test how different languages and text appear within a Component. + +## Deploying Translations + +Translations are synced between Crowdin and the repository via GitHub Actions. + +- On every push to `main`, we upload any new source content. +- Via a cron schedule, and as needed manually by a collaborator, we download completed translations. + +Incoming translations are linted to ensure they come from crowdin, and are also formatted to adhere to our project settings. diff --git a/crowdin.yml b/crowdin.yml index 644c8d597bf99..e2c04f56dde08 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,8 +1,6 @@ -commit_message: 'chore: synced translations from crowdin [skip ci]' +project_id_env: 'CROWDIN_PROJECT_ID' +api_token_env: 'CROWDIN_PERSONAL_TOKEN' append_commit_message: false -pull_request_title: '[automated]: crowdin sync' -pull_request_labels: - - 'github_actions:pull-request' files: - source: /apps/site/pages/en/**/*.md translation: /apps/site/pages/%two_letters_code%/**/%original_file_name%