name: 'Extract and upload translations' on: workflow_dispatch: workflow_call: push: branches: ['main'] concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: extract_translations: name: Extract and upload translations runs-on: ubuntu-latest environment: Translations permissions: contents: write pull-requests: write steps: - name: Checkout uses: actions/checkout@v4 - uses: ./.github/actions/node-install - name: Extract translations run: npm run translate:extract - name: Commit changes and push to reserved branch env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail BRANCH="chore/extract-translations" git config --global user.name 'github-actions' git config --global user.email 'github-actions@documenso.com' git fetch origin # Create branch locally (always reset to main) git checkout -B "$BRANCH" origin/main # Stage translation output git add packages/lib/translations # If no changes, exit early if git diff --staged --quiet; then echo "No translation changes found." exit 0 fi # Commit fresh snapshot git commit -m "chore: extract translations" # Force push reserved branch git push origin "$BRANCH" --force # Does a PR already exist? EXISTING_PR=$(gh pr list \ --state open \ --head "$BRANCH" \ --json number \ --jq '.[0].number // empty') if [ -z "$EXISTING_PR" ]; then echo "No existing PR — creating new one." gh pr create \ --title "chore: extract translations" \ --body "Automated translation extraction" \ --base main \ --head "$BRANCH" else echo "PR #$EXISTING_PR already exists — not creating a new one." fi - name: Compile translations id: compile_translations run: npm run translate:compile -- -- --strict continue-on-error: true - name: Upload missing translations if: ${{ steps.compile_translations.outcome == 'failure' }} uses: crowdin/github-action@v2 with: upload_sources: true upload_translations: true download_translations: false localization_branch_name: chore/translations env: # A numeric ID, found at https://crowdin.com/project//tools/api CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} # Visit https://crowdin.com/settings#api-key to create this token CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}