Sync with CPython #2
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: Sync with CPython | |
| on: | |
| schedule: | |
| - cron: '0 4 * * *' | |
| workflow_dispatch: | |
| inputs: | |
| cpython_tag: | |
| description: 'CPython tag to sync against (e.g. v3.14.6)' | |
| required: false | |
| default: 'v3.14.6' | |
| permissions: | |
| contents: write | |
| issues: write | |
| concurrency: | |
| group: sync | |
| cancel-in-progress: false | |
| jobs: | |
| sync: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout translation repo | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.12' | |
| - name: Install gettext | |
| run: sudo apt-get install -y gettext | |
| - name: Install Python dependencies | |
| run: pip install sphinx sphinx-intl | |
| - name: Checkout CPython docs only (sparse) | |
| run: | | |
| git clone \ | |
| --depth 1 \ | |
| --filter=blob:none \ | |
| --sparse \ | |
| --branch ${{ github.event.inputs.cpython_tag || 'v3.14.6' }} \ | |
| https://github.com/python/cpython.git \ | |
| .cpython-src | |
| cd .cpython-src | |
| git sparse-checkout set Doc Include | |
| - name: Install CPython doc dependencies | |
| run: | | |
| python -m venv .cpython-src/Doc/venv | |
| .cpython-src/Doc/venv/bin/pip install \ | |
| -r .cpython-src/Doc/requirements.txt | |
| - name: Build .pot templates | |
| run: | | |
| cd .cpython-src/Doc | |
| ./venv/bin/sphinx-build \ | |
| -b gettext \ | |
| . \ | |
| ../../.pot-templates | |
| - name: Merge .pot into .po files | |
| run: | | |
| find .pot-templates -name "*.pot" | while read f; do | |
| rel="${f#.pot-templates/}" | |
| po="${rel%.pot}.po" | |
| if [ -f "$po" ]; then | |
| msgmerge --update --backup=off --no-location --no-wrap "$po" "$f" | |
| fi | |
| done | |
| - name: Ensure translation label exists | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh label create "translation" \ | |
| --color "0075ca" \ | |
| --description "Translation review needed" \ | |
| --repo ${{ github.repository }} \ | |
| 2>/dev/null || true | |
| - name: Open issue for fuzzy strings | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| CPYTHON_TAG: ${{ github.event.inputs.cpython_tag || 'v3.14.6' }} | |
| run: | | |
| tmpfile=$(mktemp) | |
| while IFS= read -r f; do | |
| fuzzy=$(msgattrib --only-fuzzy --no-obsolete "$f" 2>/dev/null) | |
| if [ -n "$fuzzy" ]; then | |
| entries=$(echo "$fuzzy" | awk ' | |
| /^msgid / { | |
| first=$0; msg=$0"\n"; lines=1; incapture=1; next | |
| } | |
| incapture && /^"/ { | |
| msg = msg $0 "\n"; lines++; next | |
| } | |
| incapture && /^msgstr/ { | |
| incapture=0 | |
| if (!(first == "msgid \"\"" && lines==1)) { | |
| printf "- %s\n", msg | |
| } | |
| next | |
| } | |
| ') | |
| count=$(echo "$entries" | grep -c '^- ' || echo 0) | |
| if [ "$count" -gt 0 ]; then | |
| echo "### $f ($count fuzzy)" >> "$tmpfile" | |
| echo "$entries" | head -20 >> "$tmpfile" | |
| echo "" >> "$tmpfile" | |
| fi | |
| fi | |
| done < <(find . -name "*.po" \ | |
| -not -path "./.git/*" \ | |
| -not -path "./.cpython-src/*" \ | |
| -not -path "./.pot-templates/*") | |
| if [ -s "$tmpfile" ]; then | |
| gh issue create \ | |
| --title "🔍 Fuzzy strings need review after CPython sync ($(date +%Y-%m-%d))" \ | |
| --body "$(cat "$tmpfile") | |
| Triggered by sync with \`$CPYTHON_TAG\`." \ | |
| --label "translation" \ | |
| --repo ${{ github.repository }} | |
| fi | |
| rm -f "$tmpfile" | |
| - name: Validate .po files | |
| run: | | |
| tmpfile=$(mktemp) | |
| find . -name "*.po" \ | |
| -not -path "./.git/*" \ | |
| -not -path "./.cpython-src/*" \ | |
| -not -path "./.pot-templates/*" | while read f; do | |
| msgfmt --check "$f" -o /dev/null || echo "FAIL: $f" >> "$tmpfile" | |
| done | |
| if [ -s "$tmpfile" ]; then | |
| cat "$tmpfile" | |
| rm -f "$tmpfile" | |
| exit 1 | |
| fi | |
| rm -f "$tmpfile" | |
| - 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" | |
| 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 |