diff --git a/.github/workflows/crowdin-download.yml b/.github/workflows/crowdin-download.yml new file mode 100644 index 00000000..0bdeb1db --- /dev/null +++ b/.github/workflows/crowdin-download.yml @@ -0,0 +1,89 @@ +name: Crowdin Download + +on: + schedule: + - cron: "0 3 * * 1" # Runs every Monday at 03:00 UTC + workflow_dispatch: + workflow_call: # Called by the release workflow so every release ships the latest translations + outputs: + commit: + description: Commit on main that contains the latest translations + value: ${{ jobs.download.outputs.commit }} + secrets: + CROWDIN_PERSONAL_TOKEN: + required: true + BOT_APP_PRIVATE_KEY: + required: true + +permissions: + contents: read + +jobs: + download: + runs-on: ubuntu-latest + concurrency: + group: crowdin-download + cancel-in-progress: false + outputs: + commit: ${{ steps.commit.outputs.commit }} + + steps: + # The checked out commit is pushed to main, so running from any other branch could publish unrelated commits + - name: Require the main branch + run: | + if [[ "$GITHUB_REF" != refs/heads/main ]]; then + echo "::error::Translations can only be downloaded from main." + exit 1 + fi + + - name: Checkout repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.sha }} + persist-credentials: false + + - name: Download translations + uses: crowdin/github-action@9c23991700c0ec5256fd41089b9d9d7d540e424e # v3.3.0 + with: + upload_sources: false + upload_translations: false + download_translations: true + push_translations: false + create_pull_request: false + crowdin_branch_name: "[pocket-id.pocket-id] main" + user: auto + env: + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} + + - name: Create bot app token + id: app-token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + client-id: ${{ vars.BOT_APP_CLIENT_ID }} + private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} + permission-contents: write + + - name: Commit translations to main + id: commit + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + APP_SLUG: ${{ steps.app-token.outputs.app-slug }} + run: | + # Attribute the commit to the app and authenticate the push with its installation token + bot_name="${APP_SLUG}[bot]" + bot_id=$(gh api "users/$bot_name" --jq .id) + git config user.name "Pocket ID Bot" + git config user.email "$bot_id+$bot_name@users.noreply.github.com" + gh auth setup-git + + # Only commit when Crowdin returned different translations + git add frontend/messages/*.json + if git diff --cached --quiet; then + echo "Translations are already up to date." >> "$GITHUB_STEP_SUMMARY" + else + git commit -m "chore(translations): update translations via Crowdin" + git push origin HEAD:refs/heads/main + echo "Committed updated translations to main." >> "$GITHUB_STEP_SUMMARY" + fi + + echo "commit=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/crowdin-upload.yml b/.github/workflows/crowdin-upload.yml new file mode 100644 index 00000000..1e1c7c81 --- /dev/null +++ b/.github/workflows/crowdin-upload.yml @@ -0,0 +1,38 @@ +name: Crowdin Upload + +on: + push: + branches: [main] + paths: + - frontend/messages/en.json + - crowdin.yml + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: crowdin-upload + cancel-in-progress: false + +jobs: + upload: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Upload sources + uses: crowdin/github-action@9c23991700c0ec5256fd41089b9d9d7d540e424e # v3.3.0 + with: + upload_sources: true + upload_translations: false + download_translations: false + push_translations: false + create_pull_request: false + crowdin_branch_name: "[pocket-id.pocket-id] main" + env: + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9faca116..547f4c9e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,8 +25,16 @@ defaults: shell: bash jobs: + translations: + name: Download translations + uses: ./.github/workflows/crowdin-download.yml + secrets: + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} + BOT_APP_PRIVATE_KEY: ${{ secrets.BOT_APP_PRIVATE_KEY }} + prepare: name: Prepare release + needs: translations runs-on: depot-ubuntu-latest outputs: tag: ${{ steps.version.outputs.tag }} @@ -40,10 +48,11 @@ jobs: exit 1 fi + # Release from the translations commit because it may have been added on top of the triggering commit - name: Checkout release source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - ref: ${{ github.sha }} + ref: ${{ needs.translations.outputs.commit }} fetch-depth: 0 persist-credentials: false @@ -66,7 +75,7 @@ jobs: echo "version=$version" >> "$GITHUB_OUTPUT" echo "tag=v$version" >> "$GITHUB_OUTPUT" - echo "Preparing release v$version from $GITHUB_SHA." >> "$GITHUB_STEP_SUMMARY" + echo "Preparing release v$version from $(git rev-parse HEAD)." >> "$GITHUB_STEP_SUMMARY" - name: Setup Vite+ if: steps.version.outputs.tag != '' diff --git a/crowdin.yml b/crowdin.yml index 938988bc..34e8fcb9 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,5 +1,8 @@ +project_id: "773504" +api_token_env: CROWDIN_PERSONAL_TOKEN +base_path: "." +preserve_hierarchy: true + files: - source: /frontend/messages/en.json translation: /%original_path%/%two_letters_code%.json -pull_request_title: 'chore(translations): update translations via Crowdin' -project_id: "773504" \ No newline at end of file