Skip to content

Commit 6313133

Browse files
Add sample workflows (#130)
* Add sample workflows * Bump to daily * Add TX workflow * cleanup * Changes * Clean up unused stuff * git rm files * Bump py version and style Co-authored-by: Rafael Fontenelle <[email protected]> --------- Co-authored-by: Rafael Fontenelle <[email protected]>
1 parent 551f593 commit 6313133

File tree

4 files changed

+263
-0
lines changed

4 files changed

+263
-0
lines changed

sample-workflows/po-lint.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Linting Workflow
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * *'
6+
push:
7+
branches:
8+
- '*'
9+
workflow_dispatch:
10+
11+
jobs:
12+
lint:
13+
runs-on: ubuntu-latest
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
version: [ '3.14' ]
18+
continue-on-error: true
19+
steps:
20+
- uses: actions/setup-python@master
21+
with:
22+
python-version: 3
23+
- run: pip install sphinx-lint
24+
- uses: actions/checkout@master
25+
with:
26+
ref: ${{ matrix.version }}
27+
- uses: rffontenelle/[email protected]
28+
- run: sphinx-lint

sample-workflows/test-build.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Test Build Workflow
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * *'
6+
push:
7+
branches:
8+
- '*'
9+
workflow_dispatch:
10+
11+
jobs:
12+
build-translation:
13+
runs-on: ubuntu-latest
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
version: [ '3.14' ]
18+
format: [ html, latex ]
19+
steps:
20+
- uses: actions/setup-python@master
21+
with:
22+
python-version: 3.12 # pinned for Sphinx 3.4.3 to build 3.10
23+
- uses: actions/checkout@master
24+
with:
25+
repository: python/cpython
26+
ref: ${{ matrix.version }}
27+
- run: make venv
28+
working-directory: ./Doc
29+
- uses: actions/checkout@master
30+
with:
31+
ref: ${{ matrix.version }}
32+
path: Doc/locales/XX/LC_MESSAGES
33+
- run: git pull
34+
working-directory: ./Doc/locales/XX/LC_MESSAGES
35+
- uses: sphinx-doc/[email protected]
36+
- run: make -e SPHINXOPTS="--color -D language='XX' -W --keep-going" ${{ matrix.format }}
37+
working-directory: ./Doc
38+
- uses: actions/upload-artifact@master
39+
if: success() || failure()
40+
with:
41+
name: build-${{ matrix.version }}-${{ matrix.format }}
42+
path: Doc/build/${{ matrix.format }}
43+
44+
output-pdf:
45+
runs-on: ubuntu-latest
46+
strategy:
47+
matrix:
48+
version: [ '3.14' ]
49+
needs: [ 'build-translation' ]
50+
steps:
51+
- uses: actions/download-artifact@master
52+
with:
53+
name: build-${{ matrix.version }}-latex
54+
- run: sudo apt-get update
55+
- run: sudo apt-get install -y latexmk texlive-xetex fonts-freefont-otf xindy
56+
- run: make
57+
- uses: actions/upload-artifact@master
58+
with:
59+
name: build-${{ matrix.version }}-pdf
60+
path: .

sample-workflows/transifex-pull.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Pull Translations from Transifex
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * *'
6+
push:
7+
branches:
8+
- '*'
9+
workflow_dispatch:
10+
11+
jobs:
12+
update-translation:
13+
runs-on: ubuntu-latest
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
version: [ '3.14' ]
18+
steps:
19+
- uses: styfle/cancel-workflow-action@main
20+
with:
21+
access_token: ${{ secrets.GITHUB_TOKEN }}
22+
- uses: actions/setup-python@master
23+
with:
24+
python-version: 3
25+
- name: Install Dependencies
26+
run: |
27+
sudo apt-get install -y gettext
28+
pip install requests cogapp polib transifex-python sphinx-intl blurb six
29+
curl -o- https://raw.githubusercontent.com/transifex/cli/master/install.sh | bash
30+
working-directory: /usr/local/bin
31+
- uses: actions/checkout@master
32+
with:
33+
ref: ${{ matrix.version }}
34+
fetch-depth: 0
35+
- run: curl https://raw.githubusercontent.com/python-docs-translations/transifex-automation/master/sample-workflows/transifex-util.py
36+
- run: ./manage_translation.py recreate_tx_config --language XX --project-slug python-newest --version 3.13
37+
env:
38+
TX_TOKEN: ${{ secrets.TX_TOKEN }}
39+
- run: ./manage_translation.py fetch --language XX --project-slug python-newest --version 3.13
40+
env:
41+
TX_TOKEN: ${{ secrets.TX_TOKEN }}
42+
- run: ./manage_translation.py delete_obsolete_files --language XX --project-slug python-newest --version 3.13
43+
- name: Set up Git
44+
run: |
45+
git config --local user.email [email protected]
46+
git config --local user.name "GitHub Action's update-translation job"
47+
- name: Filter files
48+
run: |
49+
! git diff -I'^"POT-Creation-Date: ' \
50+
-I'^"Language-Team: ' \
51+
-I'^# ' -I'^"Last-Translator: ' \
52+
--exit-code \
53+
&& echo "SIGNIFICANT_CHANGES=1" >> $GITHUB_ENV || exit 0
54+
- run: git add .
55+
- run: git commit -m 'Update translation from Transifex'
56+
if: env.SIGNIFICANT_CHANGES
57+
- uses: ad-m/github-push-action@master
58+
if: env.SIGNIFICANT_CHANGES
59+
with:
60+
branch: ${{ matrix.version }}
61+
github_token: ${{ secrets.GITHUB_TOKEN }}

sample-workflows/transifex-util.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/usr/bin/env python
2+
#
3+
# This python file contains utility scripts to manage Python docs translation
4+
# on Transifex.
5+
#
6+
# Inspired by django-docs-translations script by claudep.
7+
import configparser
8+
from argparse import ArgumentParser
9+
import os
10+
from contextlib import chdir
11+
from pathlib import Path
12+
from subprocess import call
13+
import sys
14+
from tempfile import TemporaryDirectory
15+
16+
from polib import pofile
17+
from transifex.api import transifex_api
18+
19+
20+
def fetch():
21+
"""
22+
Fetch translations from Transifex, remove source lines.
23+
"""
24+
if (code := call("tx --version", shell=True)) != 0:
25+
sys.stderr.write("The Transifex client app is required.\n")
26+
exit(code)
27+
lang = LANGUAGE
28+
_call(f'tx pull -l {lang} --minimum-perc=1 --force --skip')
29+
for file in Path().rglob('*.po'):
30+
_call(f'msgcat --no-location -o {file} {file}')
31+
32+
def _call(command: str):
33+
if (return_code := call(command, shell=True)) != 0:
34+
exit(return_code)
35+
36+
def recreate_tx_config():
37+
"""
38+
Regenerate Transifex client config for all resources.
39+
"""
40+
with TemporaryDirectory() as directory:
41+
with chdir(directory):
42+
_clone_cpython_repo(VERSION)
43+
_build_gettext()
44+
with chdir(Path(directory) / 'cpython/Doc/build'):
45+
_create_txconfig()
46+
_update_txconfig_resources()
47+
with open('.tx/config', 'r') as file:
48+
contents = file.read()
49+
contents = contents.replace('./<lang>/LC_MESSAGES/', '')
50+
with open('.tx/config', 'w') as file:
51+
file.write(contents)
52+
53+
def delete_obsolete_files():
54+
files_to_delete = list(_get_files_to_delete())
55+
if not files_to_delete:
56+
return
57+
else:
58+
for file in files_to_delete:
59+
print(f"Removing {file}")
60+
os.remove(file)
61+
_call(f'git rm --quiet "{file}"')
62+
63+
def _get_files_to_delete():
64+
with open('.tx/config') as config_file:
65+
config = config_file.read()
66+
for file in Path().rglob('*.po'):
67+
if os.fsdecode(file) not in config:
68+
yield os.fsdecode(file)
69+
70+
def _clone_cpython_repo(version: str):
71+
_call(f'git clone -b {version} --single-branch https://github.com/python/cpython.git --depth 1')
72+
73+
def _build_gettext():
74+
_call("make -C cpython/Doc/ gettext")
75+
76+
def _create_txconfig():
77+
_call('sphinx-intl create-txconfig')
78+
79+
def _update_txconfig_resources():
80+
_call(
81+
f'sphinx-intl update-txconfig-resources --transifex-organization-name python-doc '
82+
f'--transifex-project-name {PROJECT_SLUG} --locale-dir . --pot-dir gettext'
83+
)
84+
85+
def _get_tx_token() -> str:
86+
if os.path.exists('.tx/api-key'):
87+
with open('.tx/api-key') as f:
88+
return f.read()
89+
90+
config = configparser.ConfigParser()
91+
config.read(os.path.expanduser("~/.transifexrc"))
92+
try:
93+
return config["https://www.transifex.com"]["token"]
94+
except KeyError:
95+
pass
96+
97+
return os.getenv('TX_TOKEN', '')
98+
99+
if __name__ == "__main__":
100+
RUNNABLE_SCRIPTS = ('fetch', 'recreate_tx_config', 'delete_obsolete_files')
101+
102+
parser = ArgumentParser()
103+
parser.add_argument('cmd', choices=RUNNABLE_SCRIPTS)
104+
parser.add_argument('--language', required=True)
105+
parser.add_argument('--project-slug', required=True)
106+
parser.add_argument('--version', required=True)
107+
108+
options = parser.parse_args()
109+
110+
LANGUAGE = options.language
111+
PROJECT_SLUG = options.project_slug
112+
VERSION = options.version
113+
114+
globals()[options.cmd]()

0 commit comments

Comments
 (0)