trigger #121
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Translation Runner | |
| on: | |
| issue_comment: | |
| types: [created] | |
| jobs: | |
| translate: | |
| if: github.event.issue.pull_request && startsWith(github.event.comment.body, '/translate') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - name: Get list of docs-maintainers | |
| run: | | |
| DOC_MEMBERSHIP_PAT=${{ secrets.DOC_MEMBERSHIP_PAT || secrets.GITHUB_TOKEN }} | |
| DOCS_MAINTAINERS=$(curl -s -H "Authorization: token $DOC_MEMBERSHIP_PAT" \ | |
| "https://api.github.com/orgs/starrocks/teams/docs-maintainer/members" | jq -r '.[].login') | |
| echo "$DOCS_MAINTAINERS" > allowlisted_users.txt | |
| - name: Verify approver membership | |
| id: verify-approver | |
| run: | | |
| APPROVER="${{ github.event.comment.user.login }}" | |
| if grep -q --line-regexp "$APPROVER" allowlisted_users.txt; then | |
| echo "is_allowlisted=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "::error::User $APPROVER is not authorized." | |
| exit 1 | |
| fi | |
| - name: Acknowledge Command | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| github.rest.reactions.createForIssueComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: context.payload.comment.id, | |
| content: 'eyes' | |
| }); | |
| # NEW STEP: Adds the direct link to the running workflow | |
| - name: Post Run Link | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; | |
| const newBody = context.payload.comment.body + `\n\n**Maintainer:** monitor the translation in the [GitHub Actions tab](${runUrl})`; | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: context.payload.comment.id, | |
| body: newBody | |
| }); | |
| - name: Get PR Information | |
| id: pr_data | |
| run: | | |
| PR_JSON=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | |
| "${{ github.event.issue.pull_request.url }}") | |
| # NEW: Get the exact SHA of the base | |
| echo "base_sha=$(echo $PR_JSON | jq -r '.base.sha')" >> $GITHUB_OUTPUT | |
| echo "base_ref=$(echo $PR_JSON | jq -r '.base.ref')" >> $GITHUB_OUTPUT | |
| echo "head_ref=$(echo $PR_JSON | jq -r '.head.ref')" >> $GITHUB_OUTPUT | |
| echo "head_repo_name=$(echo $PR_JSON | jq -r '.head.repo.full_name')" >> $GITHUB_OUTPUT | |
| - name: Checkout PR (Untrusted Content) | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| repository: ${{ steps.pr_data.outputs.head_repo_name }} | |
| ref: ${{ steps.pr_data.outputs.head_ref }} | |
| path: pr_code | |
| fetch-depth: 0 | |
| - name: Fetch Upstream Base | |
| run: | | |
| cd pr_code | |
| git remote add upstream https://github.com/${{ github.repository }}.git | |
| git fetch upstream ${{ steps.pr_data.outputs.base_sha }} | |
| - name: Checkout Trusted Tools | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: StarRocks/markdown-translator | |
| ref: 'v1.0.3' | |
| path: trusted_tools | |
| - name: Get Changed Files | |
| id: changed-files | |
| uses: tj-actions/changed-files@v44 | |
| with: | |
| path: pr_code | |
| base_sha: ${{ steps.pr_data.outputs.base_sha }} | |
| json: true | |
| - name: Get Checkbox State | |
| id: get_checks | |
| uses: actions/github-script@v7 | |
| with: | |
| result-encoding: string | |
| script: | | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, | |
| }); | |
| const report = comments.find(c => c.body.includes('### 🌎 Translation Required?')); | |
| return report ? report.body : ''; | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '24' | |
| - name: Install Prerequisites for Translation | |
| run: | | |
| cd trusted_tools | |
| npm install | |
| - name: Run Translations | |
| env: | |
| GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }} | |
| BODY: ${{ steps.get_checks.outputs.result }} | |
| FILES_JSON: ${{ steps.changed-files.outputs.all_changed_files }} | |
| run: | | |
| for SOURCE_FILE in $(echo "$FILES_JSON" | sed 's/\\"/"/g' | jq -r '.[]'); do | |
| if [[ "$SOURCE_FILE" =~ ^docs/(en|zh|ja)/ ]]; then | |
| SRC=$(echo $SOURCE_FILE | cut -d'/' -f2) | |
| for LANG in ja zh en; do | |
| if [ "$SRC" == "$LANG" ]; then continue; fi | |
| FULL_LANG=$(echo $LANG | sed 's/ja/Japanese/;s/zh/Chinese/;s/en/English/') | |
| INDIVIDUAL_STR=" [x] **$LANG** for \`$SOURCE_FILE\`" | |
| if [[ "$BODY" == *"$INDIVIDUAL_STR"* ]]; then | |
| echo "🚀 Starting translation for $SOURCE_FILE to $LANG" | |
| DEST_FILE=$(echo "$SOURCE_FILE" | sed "s|docs/$SRC/|docs/$LANG/|") | |
| node trusted_tools/bin/cli.js translate --input "pr_code/$SOURCE_FILE" --language $LANG --source $SRC --output "pr_code/$DEST_FILE" | |
| fi | |
| done | |
| fi | |
| done | |
| # Post the report to the PR | |
| - name: Post Translation Report | |
| if: always() # Run even if translation failed | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| // The python script writes to the root of the runner's workspace | |
| const summaryPath = 'translation_summary.md'; | |
| if (fs.existsSync(summaryPath)) { | |
| const summary = fs.readFileSync(summaryPath, 'utf8'); | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: summary | |
| }); | |
| } else { | |
| console.log("No summary file found."); | |
| } | |
| - name: Commit and Push | |
| run: | | |
| cd pr_code | |
| git config --global user.name "docs-automation[bot]" | |
| git config --global user.email "docs-automation[bot]@starrocks.io" | |
| if [[ -n $(git status --porcelain docs/) ]]; then | |
| git add docs/ | |
| git commit -m "docs: automated translation via Gemini" | |
| # ------------------------------------------------------------------ | |
| # CRITICAL AUTH FIX: Use PAT to push to Fork | |
| # This injects the PAT into the remote URL so we can write to the user's repo | |
| # ------------------------------------------------------------------ | |
| git remote set-url origin https://x-access-token:${{ secrets.DOC_MEMBERSHIP_PAT }}@github.com/${{ steps.pr_data.outputs.head_repo_name }}.git | |
| # Fetch the specific branch and rebase to ensure a clean history | |
| git fetch origin ${{ steps.pr_data.outputs.head_ref }} | |
| git rebase origin/${{ steps.pr_data.outputs.head_ref }} | |
| # Push changes | |
| git push origin HEAD:refs/heads/${{ steps.pr_data.outputs.head_ref }} | |
| else | |
| echo "No translation changes to commit." | |
| fi |