From 610cdeba8507b9d3ecb7d6536731de51440820ae Mon Sep 17 00:00:00 2001 From: Sepehr Rasouli Date: Mon, 17 Aug 2026 07:40:26 +0330 Subject: [PATCH 1/4] Add documentation build workflow --- .github/workflows/build-docs-workflow.yml | 60 +++++++++++++++++++++ .github/workflows/comment-docs-preview.yml | 62 ++++++++++++++++++++++ Makefile | 2 +- 3 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build-docs-workflow.yml create mode 100644 .github/workflows/comment-docs-preview.yml diff --git a/.github/workflows/build-docs-workflow.yml b/.github/workflows/build-docs-workflow.yml new file mode 100644 index 000000000..484deee59 --- /dev/null +++ b/.github/workflows/build-docs-workflow.yml @@ -0,0 +1,60 @@ +# .github/workflows/build-docs-preview.yml +name: Build Docs Preview + +on: + pull_request: + paths: + - '**/*.po' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout CPython + uses: actions/checkout@v4 + with: + repository: python/cpython + ref: v3.14.6 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.12' + + - name: Setup virtual environment + run: make venv + working-directory: ./Doc + + - name: Checkout translation files (this PR's branch) + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} # <-- the PR's actual commit + path: Doc/locales/fa/LC_MESSAGES + + - name: Install gettext + run: sudo apt-get install -y gettext + + - name: Compile .po files to .mo + run: | + find Doc/locales/fa/LC_MESSAGES -name "*.po" | while read f; do + msgfmt "$f" -o "${f%.po}.mo" + done + + - name: Build documentation + id: build + run: | + set +e + make -e SPHINXOPTS="--color -D language='fa' -D gettext_allow_fuzzy_translations=1 --keep-going" html 2>&1 | tee build.log + echo "exit_code=${PIPESTATUS[0]}" >> $GITHUB_OUTPUT + working-directory: ./Doc + + - name: Save PR number + run: echo "${{ github.event.pull_request.number }}" > pr_number.txt + + - name: Upload build result + uses: actions/upload-artifact@v4 + with: + name: build-result + path: | + build.log + pr_number.txt \ No newline at end of file diff --git a/.github/workflows/comment-docs-preview.yml b/.github/workflows/comment-docs-preview.yml new file mode 100644 index 000000000..607213b73 --- /dev/null +++ b/.github/workflows/comment-docs-preview.yml @@ -0,0 +1,62 @@ +# .github/workflows/comment-docs-preview.yml +name: Comment Docs Build Status + +on: + workflow_run: + workflows: ["Build Docs Preview"] + types: + - completed + +jobs: + comment: + runs-on: ubuntu-latest + permissions: + pull-requests: write + + steps: + - name: Download build result + uses: actions/download-artifact@v4 + with: + name: build-result + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + + - name: Read PR number + id: pr + run: echo "number=$(cat pr_number.txt)" >> $GITHUB_OUTPUT + + - name: Read build log + id: log + run: | + # Grab the last 20 lines so the comment isn't massive + LOG=$(tail -20 build.log) + # GitHub Actions has a specific way to handle multiline strings + echo "content<> $GITHUB_OUTPUT + echo "$LOG" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Post comment + uses: actions/github-script@v7 + with: + script: | + const success = '${{ github.event.workflow_run.conclusion }}' === 'success'; + const icon = success ? '✅' : '❌'; + const status = success ? 'succeeded' : 'failed'; + + const body = `### ${icon} Docs build ${status} + +
+ Build log (last 20 lines) + + \`\`\` + ${{ steps.log.outputs.content }} + \`\`\` + +
`; + + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: ${{ steps.pr.outputs.number }}, + body: body + }); \ No newline at end of file diff --git a/Makefile b/Makefile index 6a1c5a63d..93a3acfab 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ CPYTHON_CURRENT_COMMIT := d26c2fe7a2833606b3fb8d9789149d8696978d86 LANGUAGE := fa -BRANCH := 3.13 +BRANCH := 3.14 EXCLUDED := \ whatsnew/2.?.po \ From 6c4d29f3e3797795c5235c043479c652b906d411 Mon Sep 17 00:00:00 2001 From: Sepehr Rasouli Date: Mon, 17 Aug 2026 07:47:05 +0330 Subject: [PATCH 2/4] Update yml file --- .github/workflows/comment-docs-preview.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/comment-docs-preview.yml b/.github/workflows/comment-docs-preview.yml index 607213b73..ad65ecf3a 100644 --- a/.github/workflows/comment-docs-preview.yml +++ b/.github/workflows/comment-docs-preview.yml @@ -21,9 +21,12 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} + - name: Debug artifact contents # <-- add this temporarily + run: find . -type f | head -30 + - name: Read PR number id: pr - run: echo "number=$(cat pr_number.txt)" >> $GITHUB_OUTPUT + run: echo "number=$(find . -name "pr_number.txt" | head -1 | xargs cat)" >> $GITHUB_OUTPUT - name: Read build log id: log From ac779c1a41872b78d988bd45aade5cd941f6335d Mon Sep 17 00:00:00 2001 From: Sepehr Rasouli Date: Mon, 17 Aug 2026 07:51:14 +0330 Subject: [PATCH 3/4] Add documentation preview workflow for PRs changing .po files --- .github/workflows/build-and-deploy.yml | 39 +++---- ...cs-workflow.yml => build-docs-preview.yml} | 27 ++++- .github/workflows/comment-docs-preview.yml | 104 ++++++++++++++++-- .github/workflows/sync-with-cpython.yml | 29 +++-- 4 files changed, 154 insertions(+), 45 deletions(-) rename .github/workflows/{build-docs-workflow.yml => build-docs-preview.yml} (57%) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 6f5b9cfd7..9b4203a5c 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -2,16 +2,14 @@ name: Build and Deploy to GitHub Pages on: schedule: - - cron: '0 2 * * *' + - cron: '0 2 * * *' push: branches: - 3.14 workflow_dispatch: permissions: - contents: read - pages: write - id-token: write + contents: write concurrency: group: "pages" @@ -26,16 +24,16 @@ jobs: with: repository: python/cpython ref: v3.14.6 - + - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.12' - + - name: Setup virtual environment run: make venv working-directory: ./Doc - + - name: Checkout translation files uses: actions/checkout@v4 with: @@ -52,26 +50,15 @@ jobs: - name: Setup problem matcher uses: sphinx-doc/github-problem-matcher@v1.1 - + - name: Build documentation run: make -e SPHINXOPTS="--color -D language='fa' -D gettext_allow_fuzzy_translations=1 --keep-going" html working-directory: ./Doc - - - name: Setup Pages - uses: actions/configure-pages@v4 - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: Doc/build/html - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 + - name: Deploy to gh-pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: Doc/build/html + keep_files: true + enable_jekyll: false \ No newline at end of file diff --git a/.github/workflows/build-docs-workflow.yml b/.github/workflows/build-docs-preview.yml similarity index 57% rename from .github/workflows/build-docs-workflow.yml rename to .github/workflows/build-docs-preview.yml index 484deee59..6d5efd026 100644 --- a/.github/workflows/build-docs-workflow.yml +++ b/.github/workflows/build-docs-preview.yml @@ -28,7 +28,7 @@ jobs: - name: Checkout translation files (this PR's branch) uses: actions/checkout@v4 with: - ref: ${{ github.event.pull_request.head.sha }} # <-- the PR's actual commit + ref: ${{ github.event.pull_request.head.sha }} path: Doc/locales/fa/LC_MESSAGES - name: Install gettext @@ -48,6 +48,22 @@ jobs: echo "exit_code=${PIPESTATUS[0]}" >> $GITHUB_OUTPUT working-directory: ./Doc + - name: Patch HTML static paths + # Sphinx builds _static paths as relative (e.g. ../../_static/), + # which breaks when served from a subdirectory like /previews/12/. + # We rewrite them to absolute URLs so CSS/JS load correctly + # regardless of which subdirectory the HTML file is in. + run: | + BASE="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/previews/${{ github.event.pull_request.number }}" + find Doc/build/html -name "*.html" | while read f; do + sed -i 's|||g' "$f" + sed -i "s|href=\"\(\.\./\)*_static/|href=\"$BASE/_static/|g" "$f" + sed -i "s|src=\"\(\.\./\)*_static/|src=\"$BASE/_static/|g" "$f" + done + + - name: Move log to root + run: mv Doc/build.log build.log + - name: Save PR number run: echo "${{ github.event.pull_request.number }}" > pr_number.txt @@ -57,4 +73,11 @@ jobs: name: build-result path: | build.log - pr_number.txt \ No newline at end of file + pr_number.txt + + - name: Upload HTML preview + uses: actions/upload-artifact@v4 + with: + name: docs-html + path: Doc/build/html/ + retention-days: 7 \ No newline at end of file diff --git a/.github/workflows/comment-docs-preview.yml b/.github/workflows/comment-docs-preview.yml index ad65ecf3a..b01754d5f 100644 --- a/.github/workflows/comment-docs-preview.yml +++ b/.github/workflows/comment-docs-preview.yml @@ -6,14 +6,44 @@ on: workflows: ["Build Docs Preview"] types: - completed + pull_request: + types: + - closed + paths: + - '**/*.po' jobs: comment: + if: github.event_name == 'workflow_run' runs-on: ubuntu-latest permissions: pull-requests: write + contents: write + actions: read steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Ensure gh-pages branch exists + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + if ! git ls-remote --exit-code --heads origin gh-pages; then + echo "gh-pages branch not found, creating it..." + git checkout --orphan gh-pages + git rm -rf . + echo "# Doc Previews" > README.md + git add README.md + git commit -m "chore: initialize gh-pages branch" + git push origin gh-pages + git checkout - + else + echo "gh-pages branch already exists, skipping." + fi + - name: Download build result uses: actions/download-artifact@v4 with: @@ -21,8 +51,13 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} - - name: Debug artifact contents # <-- add this temporarily - run: find . -type f | head -30 + - name: Download HTML preview + uses: actions/download-artifact@v4 + with: + name: docs-html + path: html-preview/ + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} - name: Read PR number id: pr @@ -31,13 +66,20 @@ jobs: - name: Read build log id: log run: | - # Grab the last 20 lines so the comment isn't massive - LOG=$(tail -20 build.log) - # GitHub Actions has a specific way to handle multiline strings + LOG=$(find . -name "build.log" | head -1 | xargs tail -20) echo "content<> $GITHUB_OUTPUT echo "$LOG" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT + - name: Deploy preview to gh-pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./html-preview + destination_dir: previews/${{ steps.pr.outputs.number }} + keep_files: true + enable_jekyll: false + - name: Post comment uses: actions/github-script@v7 with: @@ -45,9 +87,15 @@ jobs: const success = '${{ github.event.workflow_run.conclusion }}' === 'success'; const icon = success ? '✅' : '❌'; const status = success ? 'succeeded' : 'failed'; + const prNumber = ${{ steps.pr.outputs.number }}; + const owner = context.repo.owner; + const repo = context.repo.repo; + const previewUrl = `https://${owner}.github.io/${repo}/previews/${prNumber}/index.html`; const body = `### ${icon} Docs build ${status} + ${success ? `📖 **[Preview the docs](${previewUrl})**` : ''} +
Build log (last 20 lines) @@ -58,8 +106,44 @@ jobs:
`; github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: ${{ steps.pr.outputs.number }}, - body: body - }); \ No newline at end of file + owner, + repo, + issue_number: prNumber, + body + }); + + cleanup: + if: github.event_name == 'pull_request' && github.event.action == 'closed' + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Check if gh-pages exists + id: check + run: | + if git ls-remote --exit-code --heads https://github.com/${{ github.repository }}.git gh-pages; then + echo "exists=true" >> $GITHUB_OUTPUT + else + echo "exists=false" >> $GITHUB_OUTPUT + fi + + - name: Checkout gh-pages + if: steps.check.outputs.exists == 'true' + uses: actions/checkout@v4 + with: + ref: gh-pages + + - name: Remove preview folder + if: steps.check.outputs.exists == 'true' + run: | + PR=${{ github.event.pull_request.number }} + if [ -d "previews/$PR" ]; then + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git rm -rf "previews/$PR" + git commit -m "chore: remove preview for PR #$PR" + git push + else + echo "No preview folder found for PR #$PR, nothing to clean up." + fi \ No newline at end of file diff --git a/.github/workflows/sync-with-cpython.yml b/.github/workflows/sync-with-cpython.yml index db5e19e08..2433581e0 100644 --- a/.github/workflows/sync-with-cpython.yml +++ b/.github/workflows/sync-with-cpython.yml @@ -70,7 +70,7 @@ jobs: rel="${f#.pot-templates/}" po="${rel%.pot}.po" if [ -f "$po" ]; then - msgmerge --update --backup=off --no-location "$po" "$f" + msgmerge --update --backup=off --no-location --no-wrap "$po" "$f" fi done @@ -149,16 +149,31 @@ jobs: - name: Clean up scratch files run: rm -rf .cpython-src .pot-templates + - name: Stage changes + run: git add --all + + - name: Unstage POT-Creation-Date-only changes + run: | + git diff --staged --name-only | while read f; do + if git diff --staged -U0 -- "$f" \ + | grep '^[+-]' \ + | grep -v '^[+-][+-][+-]' \ + | grep -qv 'POT-Creation-Date'; then + : # has real changes, keep staged + else + git restore --staged "$f" + git restore "$f" + fi + done + - name: Commit if changed run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add --all - git diff --staged -U0 \ - | grep '^[+-]' \ - | grep -v '^[+-][+-][+-]' \ - | grep -qv 'POT-Creation-Date' \ - || { echo "Only POT-Creation-Date changed, skipping commit."; exit 0; } + if git diff --staged --quiet; then + echo "Nothing to commit, skipping." + exit 0 + fi git commit -m \ "chore: sync msgids with CPython ${{ github.event.inputs.cpython_tag || 'v3.14.6' }}" git push \ No newline at end of file From 33e01df503cc622cbb15f31d19edff8bbc8f128a Mon Sep 17 00:00:00 2001 From: Sepehr Rasouli Date: Tue, 18 Aug 2026 07:49:15 +0330 Subject: [PATCH 4/4] Make build-docs-preview workflow run on every change to the PR --- .github/workflows/build-docs-preview.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/build-docs-preview.yml b/.github/workflows/build-docs-preview.yml index 6d5efd026..fa8dd4147 100644 --- a/.github/workflows/build-docs-preview.yml +++ b/.github/workflows/build-docs-preview.yml @@ -3,9 +3,16 @@ name: Build Docs Preview on: pull_request: + types: + - opened + - synchronize paths: - '**/*.po' +concurrency: + group: docs-preview-${{ github.event.pull_request.number }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest