name: Merge translations on: workflow_dispatch: workflow_call: secrets: PUSH_O_MATIC_APP_ID: required: true PUSH_O_MATIC_APP_KEY: required: true WEBLATE_TOKEN: required: true inputs: skip: description: 'Skip translations' required: false type: boolean permissions: {} env: WEBLATE_HOST: 'https://hosted.weblate.org' WEBLATE_COMPONENT: 'immich/immich' jobs: merge: runs-on: ubuntu-latest permissions: pull-requests: write steps: - name: Find translation PR id: find_pr if: ${{ inputs.skip != true }} env: GH_TOKEN: ${{ github.token }} run: | set -euo pipefail PR=$(gh pr list --repo $GITHUB_REPOSITORY --author weblate --json number,mergeable) echo "$PR" PR_NUMBER=$(echo "$PR" | jq ' if length == 1 then .[0].number else error("Expected exactly 1 entry, got \(length)") end ' 2>&1) || exit 1 echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT echo "Selected PR $PR_NUMBER" if ! echo "$PR" | jq -e '.[0].mergeable == "MERGEABLE"'; then echo "PR is not mergeable" exit 1 fi - name: Generate a token id: generate_token if: ${{ inputs.skip != true }} uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Lock weblate if: ${{ inputs.skip != true }} env: WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }} run: | curl --fail-with-body -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/lock/" -d lock=true - name: Commit translations if: ${{ inputs.skip != true }} env: WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }} run: | curl --fail-with-body -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/repository/" -d operation=commit curl --fail-with-body -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/repository/" -d operation=push - name: Merge PR id: merge_pr if: ${{ inputs.skip != true }} env: GH_TOKEN: ${{ steps.generate_token.outputs.token }} PR_NUMBER: ${{ steps.find_pr.outputs.PR_NUMBER }} run: | set -euo pipefail REVIEW_ID=$(gh api -X POST "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/reviews" --field event='APPROVE' --field body='Automatically merging translations PR' \ | jq '.id') echo "REVIEW_ID=$REVIEW_ID" >> $GITHUB_OUTPUT gh pr merge "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --auto --squash - name: Wait for PR to merge if: ${{ inputs.skip != true }} env: GH_TOKEN: ${{ steps.generate_token.outputs.token }} PR_NUMBER: ${{ steps.find_pr.outputs.PR_NUMBER }} REVIEW_ID: ${{ steps.merge_pr.outputs.REVIEW_ID }} run: | # So we clean up no matter what set +e for i in {1..100}; do if gh pr view "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --json state | jq -e '.state == "MERGED"'; then echo "PR merged" exit 0 else echo "PR not merged yet, waiting..." sleep 6 fi done echo "PR did not merge in time" gh api -X PUT "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/reviews/$REVIEW_ID/dismissals" --field message='Merge attempt timed out' --field event='DISMISS' gh pr merge "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --disable-auto exit 1 - name: Unlock weblate if: ${{ inputs.skip != true }} env: WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }} run: | curl --fail-with-body -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/lock/" -d lock=false - name: Report success run: | echo "Workflow completed successfully (or was skipped)"