Skip to content

Commit b0bd50f

Browse files
authored
Add documentation preview workflow (#41)
* Add documentation build workflow * Update yml file * Add documentation preview workflow for PRs changing .po files * Make build-docs-preview workflow run on every change to the PR
1 parent c8f001a commit b0bd50f

5 files changed

Lines changed: 275 additions & 34 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: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# .github/workflows/build-docs-preview.yml
2+
name: Build Docs Preview
3+
4+
on:
5+
pull_request:
6+
types:
7+
- opened
8+
- synchronize
9+
paths:
10+
- '**/*.po'
11+
12+
concurrency:
13+
group: docs-preview-${{ github.event.pull_request.number }}
14+
cancel-in-progress: true
15+
16+
jobs:
17+
build:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout CPython
21+
uses: actions/checkout@v4
22+
with:
23+
repository: python/cpython
24+
ref: v3.14.6
25+
26+
- name: Set up Python
27+
uses: actions/setup-python@v4
28+
with:
29+
python-version: '3.12'
30+
31+
- name: Setup virtual environment
32+
run: make venv
33+
working-directory: ./Doc
34+
35+
- name: Checkout translation files (this PR's branch)
36+
uses: actions/checkout@v4
37+
with:
38+
ref: ${{ github.event.pull_request.head.sha }}
39+
path: Doc/locales/fa/LC_MESSAGES
40+
41+
- name: Install gettext
42+
run: sudo apt-get install -y gettext
43+
44+
- name: Compile .po files to .mo
45+
run: |
46+
find Doc/locales/fa/LC_MESSAGES -name "*.po" | while read f; do
47+
msgfmt "$f" -o "${f%.po}.mo"
48+
done
49+
50+
- name: Build documentation
51+
id: build
52+
run: |
53+
set +e
54+
make -e SPHINXOPTS="--color -D language='fa' -D gettext_allow_fuzzy_translations=1 --keep-going" html 2>&1 | tee build.log
55+
echo "exit_code=${PIPESTATUS[0]}" >> $GITHUB_OUTPUT
56+
working-directory: ./Doc
57+
58+
- name: Patch HTML static paths
59+
# Sphinx builds _static paths as relative (e.g. ../../_static/),
60+
# which breaks when served from a subdirectory like /previews/12/.
61+
# We rewrite them to absolute URLs so CSS/JS load correctly
62+
# regardless of which subdirectory the HTML file is in.
63+
run: |
64+
BASE="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/previews/${{ github.event.pull_request.number }}"
65+
find Doc/build/html -name "*.html" | while read f; do
66+
sed -i 's|<base href="[^"]*">||g' "$f"
67+
sed -i "s|href=\"\(\.\./\)*_static/|href=\"$BASE/_static/|g" "$f"
68+
sed -i "s|src=\"\(\.\./\)*_static/|src=\"$BASE/_static/|g" "$f"
69+
done
70+
71+
- name: Move log to root
72+
run: mv Doc/build.log build.log
73+
74+
- name: Save PR number
75+
run: echo "${{ github.event.pull_request.number }}" > pr_number.txt
76+
77+
- name: Upload build result
78+
uses: actions/upload-artifact@v4
79+
with:
80+
name: build-result
81+
path: |
82+
build.log
83+
pr_number.txt
84+
85+
- name: Upload HTML preview
86+
uses: actions/upload-artifact@v4
87+
with:
88+
name: docs-html
89+
path: Doc/build/html/
90+
retention-days: 7
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# .github/workflows/comment-docs-preview.yml
2+
name: Comment Docs Build Status
3+
4+
on:
5+
workflow_run:
6+
workflows: ["Build Docs Preview"]
7+
types:
8+
- completed
9+
pull_request:
10+
types:
11+
- closed
12+
paths:
13+
- '**/*.po'
14+
15+
jobs:
16+
comment:
17+
if: github.event_name == 'workflow_run'
18+
runs-on: ubuntu-latest
19+
permissions:
20+
pull-requests: write
21+
contents: write
22+
actions: read
23+
24+
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+
47+
- name: Download build result
48+
uses: actions/download-artifact@v4
49+
with:
50+
name: build-result
51+
github-token: ${{ secrets.GITHUB_TOKEN }}
52+
run-id: ${{ github.event.workflow_run.id }}
53+
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 }}
61+
62+
- name: Read PR number
63+
id: pr
64+
run: echo "number=$(find . -name "pr_number.txt" | head -1 | xargs cat)" >> $GITHUB_OUTPUT
65+
66+
- name: Read build log
67+
id: log
68+
run: |
69+
LOG=$(find . -name "build.log" | head -1 | xargs tail -20)
70+
echo "content<<EOF" >> $GITHUB_OUTPUT
71+
echo "$LOG" >> $GITHUB_OUTPUT
72+
echo "EOF" >> $GITHUB_OUTPUT
73+
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+
83+
- name: Post comment
84+
uses: actions/github-script@v7
85+
with:
86+
script: |
87+
const success = '${{ github.event.workflow_run.conclusion }}' === 'success';
88+
const icon = success ? '✅' : '❌';
89+
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`;
94+
95+
const body = `### ${icon} Docs build ${status}
96+
97+
${success ? `📖 **[Preview the docs](${previewUrl})**` : ''}
98+
99+
<details>
100+
<summary>Build log (last 20 lines)</summary>
101+
102+
\`\`\`
103+
${{ steps.log.outputs.content }}
104+
\`\`\`
105+
106+
</details>`;
107+
108+
github.rest.issues.createComment({
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

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
CPYTHON_CURRENT_COMMIT := d26c2fe7a2833606b3fb8d9789149d8696978d86
2323
LANGUAGE := fa
24-
BRANCH := 3.13
24+
BRANCH := 3.14
2525

2626
EXCLUDED := \
2727
whatsnew/2.?.po \

0 commit comments

Comments
 (0)