1+ name : Sync with CPython
2+
3+ on :
4+ schedule :
5+ - cron : ' 0 4 * * *'
6+ workflow_dispatch :
7+ inputs :
8+ cpython_tag :
9+ description : ' CPython tag to sync against (e.g. v3.14.6)'
10+ required : false
11+ default : ' v3.14.6'
12+
13+ permissions :
14+ contents : write
15+ issues : write
16+
17+ concurrency :
18+ group : sync
19+ cancel-in-progress : false
20+
21+ jobs :
22+ sync :
23+ runs-on : ubuntu-latest
24+ steps :
25+ - name : Checkout translation repo
26+ uses : actions/checkout@v4
27+ with :
28+ fetch-depth : 0
29+
30+ - name : Set up Python
31+ uses : actions/setup-python@v4
32+ with :
33+ python-version : ' 3.12'
34+
35+ - name : Install gettext
36+ run : sudo apt-get install -y gettext
37+
38+ - name : Install Python dependencies
39+ run : pip install sphinx sphinx-intl
40+
41+ - name : Checkout CPython docs only (sparse)
42+ run : |
43+ git clone \
44+ --depth 1 \
45+ --filter=blob:none \
46+ --sparse \
47+ --branch ${{ github.event.inputs.cpython_tag || 'v3.14.6' }} \
48+ https://github.com/python/cpython.git \
49+ .cpython-src
50+ cd .cpython-src
51+ git sparse-checkout set Doc Include
52+
53+ - name : Install CPython doc dependencies
54+ run : |
55+ python -m venv .cpython-src/Doc/venv
56+ .cpython-src/Doc/venv/bin/pip install \
57+ -r .cpython-src/Doc/requirements.txt
58+
59+ - name : Build .pot templates
60+ run : |
61+ cd .cpython-src/Doc
62+ ./venv/bin/sphinx-build \
63+ -b gettext \
64+ . \
65+ ../../.pot-templates
66+
67+ - name : Merge .pot into .po files
68+ run : |
69+ find .pot-templates -name "*.pot" | while read f; do
70+ rel="${f#.pot-templates/}"
71+ po="${rel%.pot}.po"
72+ if [ -f "$po" ]; then
73+ msgmerge --update --backup=off --no-location "$po" "$f"
74+ fi
75+ done
76+
77+ - name : Ensure translation label exists
78+ env :
79+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
80+ run : |
81+ gh label create "translation" \
82+ --color "0075ca" \
83+ --description "Translation review needed" \
84+ --repo ${{ github.repository }} \
85+ 2>/dev/null || true
86+
87+ - name : Open issue for fuzzy strings
88+ env :
89+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
90+ CPYTHON_TAG : ${{ github.event.inputs.cpython_tag || 'v3.14.6' }}
91+ run : |
92+ tmpfile=$(mktemp)
93+ while IFS= read -r f; do
94+ fuzzy=$(msgattrib --only-fuzzy --no-obsolete "$f" 2>/dev/null)
95+ if [ -n "$fuzzy" ]; then
96+ entries=$(echo "$fuzzy" | awk '
97+ /^msgid / {
98+ first=$0; msg=$0"\n"; lines=1; incapture=1; next
99+ }
100+ incapture && /^"/ {
101+ msg = msg $0 "\n"; lines++; next
102+ }
103+ incapture && /^msgstr/ {
104+ incapture=0
105+ if (!(first == "msgid \"\"" && lines==1)) {
106+ printf "- %s\n", msg
107+ }
108+ next
109+ }
110+ ')
111+ count=$(echo "$entries" | grep -c '^- ' || echo 0)
112+ if [ "$count" -gt 0 ]; then
113+ echo "### $f ($count fuzzy)" >> "$tmpfile"
114+ echo "$entries" | head -20 >> "$tmpfile"
115+ echo "" >> "$tmpfile"
116+ fi
117+ fi
118+ done < <(find . -name "*.po" \
119+ -not -path "./.git/*" \
120+ -not -path "./.cpython-src/*" \
121+ -not -path "./.pot-templates/*")
122+ if [ -s "$tmpfile" ]; then
123+ gh issue create \
124+ --title "🔍 Fuzzy strings need review after CPython sync ($(date +%Y-%m-%d))" \
125+ --body "$(cat "$tmpfile")
126+
127+ Triggered by sync with \`$CPYTHON_TAG\`." \
128+ --label "translation" \
129+ --repo ${{ github.repository }}
130+ fi
131+ rm -f "$tmpfile"
132+
133+ - name : Validate .po files
134+ run : |
135+ tmpfile=$(mktemp)
136+ find . -name "*.po" \
137+ -not -path "./.git/*" \
138+ -not -path "./.cpython-src/*" \
139+ -not -path "./.pot-templates/*" | while read f; do
140+ msgfmt --check "$f" -o /dev/null || echo "FAIL: $f" >> "$tmpfile"
141+ done
142+ if [ -s "$tmpfile" ]; then
143+ cat "$tmpfile"
144+ rm -f "$tmpfile"
145+ exit 1
146+ fi
147+ rm -f "$tmpfile"
148+
149+ - name : Clean up scratch files
150+ run : rm -rf .cpython-src .pot-templates
151+
152+ - name : Commit if changed
153+ run : |
154+ git config user.name "github-actions[bot]"
155+ 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; }
162+ git commit -m \
163+ "chore: sync msgids with CPython ${{ github.event.inputs.cpython_tag || 'v3.14.6' }}"
164+ git push
0 commit comments