Skip to content

Commit ac779c1

Browse files
committed
Add documentation preview workflow for PRs changing .po files
1 parent 6c4d29f commit ac779c1

4 files changed

Lines changed: 154 additions & 45 deletions

File tree

.github/workflows/build-and-deploy.yml

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@ name: Build and Deploy to GitHub Pages
22

33
on:
44
schedule:
5-
- cron: '0 2 * * *'
5+
- cron: '0 2 * * *'
66
push:
77
branches:
88
- 3.14
99
workflow_dispatch:
1010

1111
permissions:
12-
contents: read
13-
pages: write
14-
id-token: write
12+
contents: write
1513

1614
concurrency:
1715
group: "pages"
@@ -26,16 +24,16 @@ jobs:
2624
with:
2725
repository: python/cpython
2826
ref: v3.14.6
29-
27+
3028
- name: Set up Python
3129
uses: actions/setup-python@v4
3230
with:
3331
python-version: '3.12'
34-
32+
3533
- name: Setup virtual environment
3634
run: make venv
3735
working-directory: ./Doc
38-
36+
3937
- name: Checkout translation files
4038
uses: actions/checkout@v4
4139
with:
@@ -52,26 +50,15 @@ jobs:
5250
5351
- name: Setup problem matcher
5452
uses: sphinx-doc/github-problem-matcher@v1.1
55-
53+
5654
- name: Build documentation
5755
run: make -e SPHINXOPTS="--color -D language='fa' -D gettext_allow_fuzzy_translations=1 --keep-going" html
5856
working-directory: ./Doc
59-
60-
- name: Setup Pages
61-
uses: actions/configure-pages@v4
62-
63-
- name: Upload artifact
64-
uses: actions/upload-pages-artifact@v3
65-
with:
66-
path: Doc/build/html
6757

68-
deploy:
69-
environment:
70-
name: github-pages
71-
url: ${{ steps.deployment.outputs.page_url }}
72-
runs-on: ubuntu-latest
73-
needs: build
74-
steps:
75-
- name: Deploy to GitHub Pages
76-
id: deployment
77-
uses: actions/deploy-pages@v4
58+
- name: Deploy to gh-pages
59+
uses: peaceiris/actions-gh-pages@v4
60+
with:
61+
github_token: ${{ secrets.GITHUB_TOKEN }}
62+
publish_dir: Doc/build/html
63+
keep_files: true
64+
enable_jekyll: false
Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
- name: Checkout translation files (this PR's branch)
2929
uses: actions/checkout@v4
3030
with:
31-
ref: ${{ github.event.pull_request.head.sha }} # <-- the PR's actual commit
31+
ref: ${{ github.event.pull_request.head.sha }}
3232
path: Doc/locales/fa/LC_MESSAGES
3333

3434
- name: Install gettext
@@ -48,6 +48,22 @@ jobs:
4848
echo "exit_code=${PIPESTATUS[0]}" >> $GITHUB_OUTPUT
4949
working-directory: ./Doc
5050

51+
- name: Patch HTML static paths
52+
# Sphinx builds _static paths as relative (e.g. ../../_static/),
53+
# which breaks when served from a subdirectory like /previews/12/.
54+
# We rewrite them to absolute URLs so CSS/JS load correctly
55+
# regardless of which subdirectory the HTML file is in.
56+
run: |
57+
BASE="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/previews/${{ github.event.pull_request.number }}"
58+
find Doc/build/html -name "*.html" | while read f; do
59+
sed -i 's|<base href="[^"]*">||g' "$f"
60+
sed -i "s|href=\"\(\.\./\)*_static/|href=\"$BASE/_static/|g" "$f"
61+
sed -i "s|src=\"\(\.\./\)*_static/|src=\"$BASE/_static/|g" "$f"
62+
done
63+
64+
- name: Move log to root
65+
run: mv Doc/build.log build.log
66+
5167
- name: Save PR number
5268
run: echo "${{ github.event.pull_request.number }}" > pr_number.txt
5369

@@ -57,4 +73,11 @@ jobs:
5773
name: build-result
5874
path: |
5975
build.log
60-
pr_number.txt
76+
pr_number.txt
77+
78+
- name: Upload HTML preview
79+
uses: actions/upload-artifact@v4
80+
with:
81+
name: docs-html
82+
path: Doc/build/html/
83+
retention-days: 7

.github/workflows/comment-docs-preview.yml

Lines changed: 94 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,58 @@ on:
66
workflows: ["Build Docs Preview"]
77
types:
88
- completed
9+
pull_request:
10+
types:
11+
- closed
12+
paths:
13+
- '**/*.po'
914

1015
jobs:
1116
comment:
17+
if: github.event_name == 'workflow_run'
1218
runs-on: ubuntu-latest
1319
permissions:
1420
pull-requests: write
21+
contents: write
22+
actions: read
1523

1624
steps:
25+
- name: Checkout repo
26+
uses: actions/checkout@v4
27+
with:
28+
fetch-depth: 0
29+
30+
- name: Ensure gh-pages branch exists
31+
run: |
32+
git config user.name "github-actions[bot]"
33+
git config user.email "github-actions[bot]@users.noreply.github.com"
34+
if ! git ls-remote --exit-code --heads origin gh-pages; then
35+
echo "gh-pages branch not found, creating it..."
36+
git checkout --orphan gh-pages
37+
git rm -rf .
38+
echo "# Doc Previews" > README.md
39+
git add README.md
40+
git commit -m "chore: initialize gh-pages branch"
41+
git push origin gh-pages
42+
git checkout -
43+
else
44+
echo "gh-pages branch already exists, skipping."
45+
fi
46+
1747
- name: Download build result
1848
uses: actions/download-artifact@v4
1949
with:
2050
name: build-result
2151
github-token: ${{ secrets.GITHUB_TOKEN }}
2252
run-id: ${{ github.event.workflow_run.id }}
2353

24-
- name: Debug artifact contents # <-- add this temporarily
25-
run: find . -type f | head -30
54+
- name: Download HTML preview
55+
uses: actions/download-artifact@v4
56+
with:
57+
name: docs-html
58+
path: html-preview/
59+
github-token: ${{ secrets.GITHUB_TOKEN }}
60+
run-id: ${{ github.event.workflow_run.id }}
2661

2762
- name: Read PR number
2863
id: pr
@@ -31,23 +66,36 @@ jobs:
3166
- name: Read build log
3267
id: log
3368
run: |
34-
# Grab the last 20 lines so the comment isn't massive
35-
LOG=$(tail -20 build.log)
36-
# GitHub Actions has a specific way to handle multiline strings
69+
LOG=$(find . -name "build.log" | head -1 | xargs tail -20)
3770
echo "content<<EOF" >> $GITHUB_OUTPUT
3871
echo "$LOG" >> $GITHUB_OUTPUT
3972
echo "EOF" >> $GITHUB_OUTPUT
4073
74+
- name: Deploy preview to gh-pages
75+
uses: peaceiris/actions-gh-pages@v4
76+
with:
77+
github_token: ${{ secrets.GITHUB_TOKEN }}
78+
publish_dir: ./html-preview
79+
destination_dir: previews/${{ steps.pr.outputs.number }}
80+
keep_files: true
81+
enable_jekyll: false
82+
4183
- name: Post comment
4284
uses: actions/github-script@v7
4385
with:
4486
script: |
4587
const success = '${{ github.event.workflow_run.conclusion }}' === 'success';
4688
const icon = success ? '✅' : '❌';
4789
const status = success ? 'succeeded' : 'failed';
90+
const prNumber = ${{ steps.pr.outputs.number }};
91+
const owner = context.repo.owner;
92+
const repo = context.repo.repo;
93+
const previewUrl = `https://${owner}.github.io/${repo}/previews/${prNumber}/index.html`;
4894
4995
const body = `### ${icon} Docs build ${status}
5096
97+
${success ? `📖 **[Preview the docs](${previewUrl})**` : ''}
98+
5199
<details>
52100
<summary>Build log (last 20 lines)</summary>
53101
@@ -58,8 +106,44 @@ jobs:
58106
</details>`;
59107
60108
github.rest.issues.createComment({
61-
owner: context.repo.owner,
62-
repo: context.repo.repo,
63-
issue_number: ${{ steps.pr.outputs.number }},
64-
body: body
65-
});
109+
owner,
110+
repo,
111+
issue_number: prNumber,
112+
body
113+
});
114+
115+
cleanup:
116+
if: github.event_name == 'pull_request' && github.event.action == 'closed'
117+
runs-on: ubuntu-latest
118+
permissions:
119+
contents: write
120+
121+
steps:
122+
- name: Check if gh-pages exists
123+
id: check
124+
run: |
125+
if git ls-remote --exit-code --heads https://github.com/${{ github.repository }}.git gh-pages; then
126+
echo "exists=true" >> $GITHUB_OUTPUT
127+
else
128+
echo "exists=false" >> $GITHUB_OUTPUT
129+
fi
130+
131+
- name: Checkout gh-pages
132+
if: steps.check.outputs.exists == 'true'
133+
uses: actions/checkout@v4
134+
with:
135+
ref: gh-pages
136+
137+
- name: Remove preview folder
138+
if: steps.check.outputs.exists == 'true'
139+
run: |
140+
PR=${{ github.event.pull_request.number }}
141+
if [ -d "previews/$PR" ]; then
142+
git config user.name "github-actions[bot]"
143+
git config user.email "github-actions[bot]@users.noreply.github.com"
144+
git rm -rf "previews/$PR"
145+
git commit -m "chore: remove preview for PR #$PR"
146+
git push
147+
else
148+
echo "No preview folder found for PR #$PR, nothing to clean up."
149+
fi

.github/workflows/sync-with-cpython.yml

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ jobs:
7070
rel="${f#.pot-templates/}"
7171
po="${rel%.pot}.po"
7272
if [ -f "$po" ]; then
73-
msgmerge --update --backup=off --no-location "$po" "$f"
73+
msgmerge --update --backup=off --no-location --no-wrap "$po" "$f"
7474
fi
7575
done
7676
@@ -149,16 +149,31 @@ jobs:
149149
- name: Clean up scratch files
150150
run: rm -rf .cpython-src .pot-templates
151151

152+
- name: Stage changes
153+
run: git add --all
154+
155+
- name: Unstage POT-Creation-Date-only changes
156+
run: |
157+
git diff --staged --name-only | while read f; do
158+
if git diff --staged -U0 -- "$f" \
159+
| grep '^[+-]' \
160+
| grep -v '^[+-][+-][+-]' \
161+
| grep -qv 'POT-Creation-Date'; then
162+
: # has real changes, keep staged
163+
else
164+
git restore --staged "$f"
165+
git restore "$f"
166+
fi
167+
done
168+
152169
- name: Commit if changed
153170
run: |
154171
git config user.name "github-actions[bot]"
155172
git config user.email "github-actions[bot]@users.noreply.github.com"
156-
git add --all
157-
git diff --staged -U0 \
158-
| grep '^[+-]' \
159-
| grep -v '^[+-][+-][+-]' \
160-
| grep -qv 'POT-Creation-Date' \
161-
|| { echo "Only POT-Creation-Date changed, skipping commit."; exit 0; }
173+
if git diff --staged --quiet; then
174+
echo "Nothing to commit, skipping."
175+
exit 0
176+
fi
162177
git commit -m \
163178
"chore: sync msgids with CPython ${{ github.event.inputs.cpython_tag || 'v3.14.6' }}"
164179
git push

0 commit comments

Comments
 (0)