From cd3b33eebc9e852cba93eb0d7577da01a28820de Mon Sep 17 00:00:00 2001 From: qiancai Date: Wed, 12 Nov 2025 14:07:16 +0800 Subject: [PATCH 1/2] Create sync-doc-pr-zh-to-en.yml --- .github/workflows/sync-doc-pr-zh-to-en.yml | 167 +++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 .github/workflows/sync-doc-pr-zh-to-en.yml diff --git a/.github/workflows/sync-doc-pr-zh-to-en.yml b/.github/workflows/sync-doc-pr-zh-to-en.yml new file mode 100644 index 0000000000000..e318f84238a5d --- /dev/null +++ b/.github/workflows/sync-doc-pr-zh-to-en.yml @@ -0,0 +1,167 @@ +name: Sync Docs Changes from ZH PR to EN PR + +on: + workflow_dispatch: + inputs: + source_pr_url: + description: 'Source PR URL (Chinese docs repository)' + required: true + type: string + default: '' + target_pr_url: + description: 'Target PR URL (English docs repository)' + required: true + type: string + default: '' + ai_provider: + description: 'AI Provider to use for translation' + required: false + type: choice + options: + - deepseek + - gemini + default: 'gemini' + +jobs: + sync-docs: + runs-on: ubuntu-latest + + steps: + - name: Checkout current repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + + - name: Checkout ai-pr-translator repository + uses: actions/checkout@v4 + with: + repository: "qiancai/ai-pr-translator" + ref: "main" + path: "ai-pr-translator" + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.9' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r ai-pr-translator/scripts/requirements.txt + + - name: Extract PR information + id: extract_info + run: | + # Extract source repo info + SOURCE_URL="${{ github.event.inputs.source_pr_url }}" + SOURCE_OWNER=$(echo $SOURCE_URL | cut -d'/' -f4) + SOURCE_REPO=$(echo $SOURCE_URL | cut -d'/' -f5) + SOURCE_PR=$(echo $SOURCE_URL | cut -d'/' -f7) + + # Extract target repo info + TARGET_URL="${{ github.event.inputs.target_pr_url }}" + TARGET_OWNER=$(echo $TARGET_URL | cut -d'/' -f4) + TARGET_REPO=$(echo $TARGET_URL | cut -d'/' -f5) + TARGET_PR=$(echo $TARGET_URL | cut -d'/' -f7) + + echo "source_owner=${SOURCE_OWNER}" >> $GITHUB_OUTPUT + echo "source_repo=${SOURCE_REPO}" >> $GITHUB_OUTPUT + echo "source_pr=${SOURCE_PR}" >> $GITHUB_OUTPUT + echo "target_owner=${TARGET_OWNER}" >> $GITHUB_OUTPUT + echo "target_repo=${TARGET_REPO}" >> $GITHUB_OUTPUT + echo "target_pr=${TARGET_PR}" >> $GITHUB_OUTPUT + + echo "Source: ${SOURCE_OWNER}/${SOURCE_REPO}#${SOURCE_PR}" + echo "Target: ${TARGET_OWNER}/${TARGET_REPO}#${TARGET_PR}" + + - name: Get target PR branch info + id: target_branch + run: | + # Get target PR information including head repository + PR_INFO=$(curl -s \ + -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/${{ steps.extract_info.outputs.target_owner }}/${{ steps.extract_info.outputs.target_repo }}/pulls/${{ steps.extract_info.outputs.target_pr }}") + + TARGET_BRANCH=$(echo "$PR_INFO" | jq -r '.head.ref') + HEAD_REPO=$(echo "$PR_INFO" | jq -r '.head.repo.full_name') + + echo "target_branch=${TARGET_BRANCH}" >> $GITHUB_OUTPUT + echo "head_repo=${HEAD_REPO}" >> $GITHUB_OUTPUT + echo "Target branch: ${TARGET_BRANCH}" + echo "Head repository: ${HEAD_REPO}" + + - name: Clone target repository + run: | + # Clone the head repository (where the PR branch is) + git clone https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ steps.target_branch.outputs.head_repo }}.git target_repo + cd target_repo + git checkout ${{ steps.target_branch.outputs.target_branch }} + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Run sync script + id: sync_script + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DEEPSEEK_API_TOKEN: ${{ secrets.DEEPSEEK_API_TOKEN }} + GEMINI_API_TOKEN: ${{ secrets.GEMINI_API_TOKEN }} + SOURCE_PR_URL: ${{ github.event.inputs.source_pr_url }} + TARGET_PR_URL: ${{ github.event.inputs.target_pr_url }} + AI_PROVIDER: ${{ github.event.inputs.ai_provider }} + TARGET_REPO_PATH: ${{ github.workspace }}/target_repo + run: | + cd ai-pr-translator/scripts + if python main_workflow.py; then + echo "sync_success=true" >> $GITHUB_OUTPUT + echo "āœ… Sync script completed successfully" + else + echo "sync_success=false" >> $GITHUB_OUTPUT + echo "āŒ Sync script failed" + exit 1 + fi + + - name: Commit and push changes + if: steps.sync_script.outputs.sync_success == 'true' + run: | + cd target_repo + git add . + if git diff --staged --quiet; then + echo "No changes to commit" + else + git commit -m "Auto-sync: Update English docs from Chinese PR ${{ github.event.inputs.source_pr_url }} + + Synced from: ${{ github.event.inputs.source_pr_url }} + Target PR: ${{ github.event.inputs.target_pr_url }} + AI Provider: ${{ github.event.inputs.ai_provider }} + + Co-authored-by: github-actions[bot] " + + git push origin ${{ steps.target_branch.outputs.target_branch }} + echo "Changes pushed to target PR branch: ${{ steps.target_branch.outputs.target_branch }}" + fi + + - name: Add success comment to target PR + if: steps.sync_script.outputs.sync_success == 'true' + run: | + # Add a comment to the target PR about the sync success + curl -X POST \ + -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/${{ steps.extract_info.outputs.target_owner }}/${{ steps.extract_info.outputs.target_repo }}/issues/${{ steps.extract_info.outputs.target_pr }}/comments" \ + -d "{ + \"body\": \"šŸ¤– **Auto-sync completed successfully**\\n\\nšŸ“„ **Source PR**: ${{ github.event.inputs.source_pr_url }}\\nšŸŽÆ **Target PR**: ${{ github.event.inputs.target_pr_url }}\\nāœ… English documentation has been updated based on Chinese documentation changes.\\n\\n_This comment was generated automatically by the sync workflow._\" + }" + + - name: Add failure comment to target PR + if: steps.sync_script.outputs.sync_success == 'false' + run: | + # Add a comment to the target PR about the sync failure + curl -X POST \ + -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/${{ steps.extract_info.outputs.target_owner }}/${{ steps.extract_info.outputs.target_repo }}/issues/${{ steps.extract_info.outputs.target_pr }}/comments" \ + -d "{ + \"body\": \"šŸ¤– **Auto-sync failed**\\n\\nšŸ“„ **Source PR**: ${{ github.event.inputs.source_pr_url }}\\nšŸŽÆ **Target PR**: ${{ github.event.inputs.target_pr_url }}\\nāŒ The sync process encountered an error. Please check the workflow logs for details.\\n\\n_This comment was generated automatically by the sync workflow._\" + }" From 5544bc5729b6c91ae31f58c887c6ceed1b1284eb Mon Sep 17 00:00:00 2001 From: qiancai Date: Wed, 12 Nov 2025 15:03:56 +0800 Subject: [PATCH 2/2] Update sync-doc-pr-zh-to-en.yml --- .github/workflows/sync-doc-pr-zh-to-en.yml | 138 ++++++++++++--------- 1 file changed, 78 insertions(+), 60 deletions(-) diff --git a/.github/workflows/sync-doc-pr-zh-to-en.yml b/.github/workflows/sync-doc-pr-zh-to-en.yml index e318f84238a5d..af8b4db17d612 100644 --- a/.github/workflows/sync-doc-pr-zh-to-en.yml +++ b/.github/workflows/sync-doc-pr-zh-to-en.yml @@ -46,58 +46,64 @@ jobs: python-version: '3.9' - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r ai-pr-translator/scripts/requirements.txt + run: pip install -r ai-pr-translator/scripts/requirements.txt - name: Extract PR information id: extract_info + env: + SOURCE_URL: ${{ github.event.inputs.source_pr_url }} + TARGET_URL: ${{ github.event.inputs.target_pr_url }} run: | - # Extract source repo info - SOURCE_URL="${{ github.event.inputs.source_pr_url }}" - SOURCE_OWNER=$(echo $SOURCE_URL | cut -d'/' -f4) - SOURCE_REPO=$(echo $SOURCE_URL | cut -d'/' -f5) - SOURCE_PR=$(echo $SOURCE_URL | cut -d'/' -f7) + if [[ ! "$SOURCE_URL" =~ ^https://github\.com/[^/]+/[^/]+/pull/[0-9]+$ ]]; then + echo "āŒ Invalid source PR URL format"; exit 1 + fi + if [[ ! "$TARGET_URL" =~ ^https://github\.com/[^/]+/[^/]+/pull/[0-9]+$ ]]; then + echo "āŒ Invalid target PR URL format"; exit 1 + fi - # Extract target repo info - TARGET_URL="${{ github.event.inputs.target_pr_url }}" - TARGET_OWNER=$(echo $TARGET_URL | cut -d'/' -f4) - TARGET_REPO=$(echo $TARGET_URL | cut -d'/' -f5) - TARGET_PR=$(echo $TARGET_URL | cut -d'/' -f7) + SOURCE_OWNER=$(echo "$SOURCE_URL" | cut -d'/' -f4) + SOURCE_REPO=$(echo "$SOURCE_URL" | cut -d'/' -f5) + SOURCE_PR=$(echo "$SOURCE_URL" | cut -d'/' -f7) + TARGET_OWNER=$(echo "$TARGET_URL" | cut -d'/' -f4) + TARGET_REPO=$(echo "$TARGET_URL" | cut -d'/' -f5) + TARGET_PR=$(echo "$TARGET_URL" | cut -d'/' -f7) - echo "source_owner=${SOURCE_OWNER}" >> $GITHUB_OUTPUT - echo "source_repo=${SOURCE_REPO}" >> $GITHUB_OUTPUT - echo "source_pr=${SOURCE_PR}" >> $GITHUB_OUTPUT - echo "target_owner=${TARGET_OWNER}" >> $GITHUB_OUTPUT - echo "target_repo=${TARGET_REPO}" >> $GITHUB_OUTPUT - echo "target_pr=${TARGET_PR}" >> $GITHUB_OUTPUT + { + echo "source_owner<> $GITHUB_OUTPUT echo "Source: ${SOURCE_OWNER}/${SOURCE_REPO}#${SOURCE_PR}" echo "Target: ${TARGET_OWNER}/${TARGET_REPO}#${TARGET_PR}" - name: Get target PR branch info id: target_branch + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TARGET_OWNER: ${{ steps.extract_info.outputs.target_owner }} + TARGET_REPO: ${{ steps.extract_info.outputs.target_repo }} + TARGET_PR: ${{ steps.extract_info.outputs.target_pr }} run: | - # Get target PR information including head repository - PR_INFO=$(curl -s \ - -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ - -H "Accept: application/vnd.github.v3+json" \ - "https://api.github.com/repos/${{ steps.extract_info.outputs.target_owner }}/${{ steps.extract_info.outputs.target_repo }}/pulls/${{ steps.extract_info.outputs.target_pr }}") - + PR_INFO=$(curl -s -H "Authorization: token ${GH_TOKEN}" -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/${TARGET_OWNER}/${TARGET_REPO}/pulls/${TARGET_PR}") TARGET_BRANCH=$(echo "$PR_INFO" | jq -r '.head.ref') HEAD_REPO=$(echo "$PR_INFO" | jq -r '.head.repo.full_name') - echo "target_branch=${TARGET_BRANCH}" >> $GITHUB_OUTPUT echo "head_repo=${HEAD_REPO}" >> $GITHUB_OUTPUT - echo "Target branch: ${TARGET_BRANCH}" - echo "Head repository: ${HEAD_REPO}" + echo "Target branch: ${TARGET_BRANCH}, Head repo: ${HEAD_REPO}" - name: Clone target repository + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + HEAD_REPO: ${{ steps.target_branch.outputs.head_repo }} + TARGET_BRANCH: ${{ steps.target_branch.outputs.target_branch }} run: | - # Clone the head repository (where the PR branch is) - git clone https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ steps.target_branch.outputs.head_repo }}.git target_repo - cd target_repo - git checkout ${{ steps.target_branch.outputs.target_branch }} + git clone "https://x-access-token:${GITHUB_TOKEN}@github.com/${HEAD_REPO}.git" target_repo + cd target_repo && git checkout "$TARGET_BRANCH" git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" @@ -124,44 +130,56 @@ jobs: - name: Commit and push changes if: steps.sync_script.outputs.sync_success == 'true' + env: + SOURCE_PR_URL: ${{ github.event.inputs.source_pr_url }} + TARGET_PR_URL: ${{ github.event.inputs.target_pr_url }} + AI_PROVIDER: ${{ github.event.inputs.ai_provider }} + TARGET_BRANCH: ${{ steps.target_branch.outputs.target_branch }} run: | - cd target_repo - git add . - if git diff --staged --quiet; then - echo "No changes to commit" + cd target_repo && git add . + if ! git diff --staged --quiet; then + printf "Auto-sync: Update English docs from Chinese PR\n\nSynced from: %s\nTarget PR: %s\nAI Provider: %s\n\nCo-authored-by: github-actions[bot] " \ + "$SOURCE_PR_URL" "$TARGET_PR_URL" "$AI_PROVIDER" | git commit -F - + git push origin "$TARGET_BRANCH" + echo "Changes pushed to $TARGET_BRANCH" else - git commit -m "Auto-sync: Update English docs from Chinese PR ${{ github.event.inputs.source_pr_url }} - - Synced from: ${{ github.event.inputs.source_pr_url }} - Target PR: ${{ github.event.inputs.target_pr_url }} - AI Provider: ${{ github.event.inputs.ai_provider }} - - Co-authored-by: github-actions[bot] " - - git push origin ${{ steps.target_branch.outputs.target_branch }} - echo "Changes pushed to target PR branch: ${{ steps.target_branch.outputs.target_branch }}" + echo "No changes to commit" fi - name: Add success comment to target PR if: steps.sync_script.outputs.sync_success == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SOURCE_PR_URL: ${{ github.event.inputs.source_pr_url }} + TARGET_PR_URL: ${{ github.event.inputs.target_pr_url }} + TARGET_OWNER: ${{ steps.extract_info.outputs.target_owner }} + TARGET_REPO: ${{ steps.extract_info.outputs.target_repo }} + TARGET_PR: ${{ steps.extract_info.outputs.target_pr }} run: | - # Add a comment to the target PR about the sync success - curl -X POST \ - -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + BODY=$(printf '%s\n\n%s\n%s\n%s\n\n%s' "**Auto-sync completed successfully**" \ + "**Source PR**: ${SOURCE_PR_URL}" "**Target PR**: ${TARGET_PR_URL}" \ + "English documentation has been updated based on Chinese documentation changes." ) + PAYLOAD=$(jq -n --arg body "$BODY" '{body: $body}') + curl -X POST -H "Authorization: token ${GITHUB_TOKEN}" \ -H "Accept: application/vnd.github.v3+json" \ - "https://api.github.com/repos/${{ steps.extract_info.outputs.target_owner }}/${{ steps.extract_info.outputs.target_repo }}/issues/${{ steps.extract_info.outputs.target_pr }}/comments" \ - -d "{ - \"body\": \"šŸ¤– **Auto-sync completed successfully**\\n\\nšŸ“„ **Source PR**: ${{ github.event.inputs.source_pr_url }}\\nšŸŽÆ **Target PR**: ${{ github.event.inputs.target_pr_url }}\\nāœ… English documentation has been updated based on Chinese documentation changes.\\n\\n_This comment was generated automatically by the sync workflow._\" - }" + "https://api.github.com/repos/${TARGET_OWNER}/${TARGET_REPO}/issues/${TARGET_PR}/comments" \ + -d "$PAYLOAD" - name: Add failure comment to target PR if: steps.sync_script.outputs.sync_success == 'false' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SOURCE_PR_URL: ${{ github.event.inputs.source_pr_url }} + TARGET_PR_URL: ${{ github.event.inputs.target_pr_url }} + TARGET_OWNER: ${{ steps.extract_info.outputs.target_owner }} + TARGET_REPO: ${{ steps.extract_info.outputs.target_repo }} + TARGET_PR: ${{ steps.extract_info.outputs.target_pr }} run: | - # Add a comment to the target PR about the sync failure - curl -X POST \ - -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + BODY=$(printf '%s\n\n%s\n%s\n%s\n\n%s' "**Auto-sync failed**" \ + "**Source PR**: ${SOURCE_PR_URL}" "**Target PR**: ${TARGET_PR_URL}" \ + "The sync process encountered an error. Please check the workflow logs for details.") + PAYLOAD=$(jq -n --arg body "$BODY" '{body: $body}') + curl -X POST -H "Authorization: token ${GITHUB_TOKEN}" \ -H "Accept: application/vnd.github.v3+json" \ - "https://api.github.com/repos/${{ steps.extract_info.outputs.target_owner }}/${{ steps.extract_info.outputs.target_repo }}/issues/${{ steps.extract_info.outputs.target_pr }}/comments" \ - -d "{ - \"body\": \"šŸ¤– **Auto-sync failed**\\n\\nšŸ“„ **Source PR**: ${{ github.event.inputs.source_pr_url }}\\nšŸŽÆ **Target PR**: ${{ github.event.inputs.target_pr_url }}\\nāŒ The sync process encountered an error. Please check the workflow logs for details.\\n\\n_This comment was generated automatically by the sync workflow._\" - }" + "https://api.github.com/repos/${TARGET_OWNER}/${TARGET_REPO}/issues/${TARGET_PR}/comments" \ + -d "$PAYLOAD"