diff --git a/.github/workflows/docs-pr.translate.yaml b/.github/workflows/docs-pr.translate.yaml index e54f97aee2..eea2a40647 100644 --- a/.github/workflows/docs-pr.translate.yaml +++ b/.github/workflows/docs-pr.translate.yaml @@ -22,9 +22,11 @@ jobs: - name: Parse PR input id: pr uses: actions/github-script@v7 + env: + PR_INPUT: ${{ inputs.pr }} with: script: | - const raw = core.getInput('pr'); + const raw = process.env.PR_INPUT || ''; if (!raw || raw.trim() === '') { throw new Error('PR input is required.'); } @@ -61,11 +63,14 @@ jobs: - name: Collect changed documentation files id: collect uses: actions/github-script@v7 + env: + PR_NUMBER: ${{ steps.pr.outputs.pr_number }} with: script: | - const prNumber = parseInt('${{ steps.pr.outputs.pr_number }}', 10); + const rawPrNumber = process.env.PR_NUMBER || ''; + const prNumber = Number.parseInt(rawPrNumber, 10); if (!prNumber) { - throw new Error('PR number is missing.'); + throw new Error(`PR number is missing or invalid: "${rawPrNumber}"`); } const isDoc = (path) => @@ -120,14 +125,21 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + ref: main - - name: Checkout PR revision + - name: Populate PR content if: steps.collect.outputs.has_inputs == 'true' + env: + PR: ${{ steps.pr.outputs.pr_number }} + INPUT_FILES: ${{ steps.collect.outputs.input_files }} run: | set -euo pipefail - PR=${{ steps.pr.outputs.pr_number }} - git fetch origin pull/${PR}/head - git checkout -B translation-source-${PR} FETCH_HEAD + git fetch --no-tags --depth=1 origin pull/${PR}/head:refs/remotes/origin/pr-${PR} + for file in $INPUT_FILES; do + clean_path=${file#./} + mkdir -p "$(dirname "$clean_path")" + git show origin/pr-${PR}:"$clean_path" > "$clean_path" + done - name: Snapshot existing translation branches if: steps.collect.outputs.has_inputs == 'true' @@ -171,6 +183,77 @@ jobs: echo "branch=" >> "$GITHUB_OUTPUT" fi + - name: Annotate translation PR + if: steps.branch.outputs.branch != '' + uses: actions/github-script@v7 + env: + SOURCE_PR: ${{ steps.pr.outputs.pr_number }} + SOURCE_PR_URL: ${{ steps.pr.outputs.html_url }} + REMOVED_FILES: ${{ steps.collect.outputs.removed_cn }} + with: + script: | + const branch = '${{ steps.branch.outputs.branch }}'; + if (!branch) { + core.info('No translation branch detected, skipping annotation.'); + return; + } + + const owner = context.repo.owner; + const repo = context.repo.repo; + + const prs = await github.paginate(github.rest.pulls.list, { + owner, + repo, + head: `${owner}:${branch}`, + state: 'open', + per_page: 100, + }); + + if (prs.length === 0) { + core.warning(`Unable to find translation PR for branch ${branch}`); + return; + } + + const translationPr = prs[0]; + const sourcePrNumber = process.env.SOURCE_PR; + const sourcePrUrl = process.env.SOURCE_PR_URL; + + const removedFilesRaw = (process.env.REMOVED_FILES || '').trim(); + const removedFilesList = removedFilesRaw + ? removedFilesRaw.split(/\s+/).map((file) => `- \`${file}\``).join('\n') + : '- *(none)*'; + + const annotationBlock = [ + '---', + '### 🔗 Source Pull Request', + `- PR #${sourcePrNumber}`, + `- ${sourcePrUrl}`, + '', + '### 🗑️ Synchronized CN Deletions', + removedFilesList, + '---', + ].join('\n'); + + let updatedBody = translationPr.body || ''; + + const marker = '\n---\n### 🔗 Source Pull Request'; + if (updatedBody.includes(marker)) { + updatedBody = updatedBody.replace(/---\n### 🔗 Source Pull Request[\s\S]*?---/m, annotationBlock); + } else { + updatedBody = `${updatedBody.trim()}\n\n${annotationBlock}`.trim(); + } + + const updatedTitle = translationPr.title.includes(`#${sourcePrNumber}`) + ? translationPr.title + : `${translationPr.title} (from #${sourcePrNumber})`; + + await github.rest.pulls.update({ + owner, + repo, + pull_number: translationPr.number, + title: updatedTitle, + body: updatedBody, + }); - name: Apply deletions to translation branch if: > steps.collect.outputs.has_inputs == 'true' && @@ -184,6 +267,10 @@ jobs: git fetch origin "$TRANSLATION_BRANCH" git checkout "$TRANSLATION_BRANCH" + if command -v sudo >/dev/null 2>&1; then + sudo chown -R "$(id -u)":"$(id -g)" .git docs || true + fi + for file in $REMOVED_FILES; do if [ -f "$file" ]; then rm -f "$file"