Skip to content

Commit e027fab

Browse files
committed
Add temporary Phase 9 validation workflow
1 parent 0e360cb commit e027fab

1 file changed

Lines changed: 146 additions & 0 deletions

File tree

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
name: Apply Phase 9 pandas updates
2+
3+
on:
4+
push:
5+
branches:
6+
- phase-09-pandas-tabular-data-contracts
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
sync-and-validate:
13+
if: github.event.head_commit.message != 'Synchronize Phase 9 pandas navigation'
14+
runs-on: ubuntu-24.04
15+
timeout-minutes: 15
16+
17+
steps:
18+
- name: Check out branch
19+
uses: actions/checkout@v6
20+
with:
21+
ref: phase-09-pandas-tabular-data-contracts
22+
fetch-depth: 0
23+
24+
- name: Set up Python
25+
uses: actions/setup-python@v6
26+
with:
27+
python-version: '3.13'
28+
29+
- name: Synchronize Phase 9 navigation
30+
run: python scripts/sync_phase09_pandas_navigation.py
31+
32+
- name: Install external-library dependencies
33+
run: python -m pip install --disable-pip-version-check -r requirements-external.txt
34+
35+
- name: Show dependency versions
36+
run: |
37+
python --version
38+
python -c "import pandas as pd; print('pandas', pd.__version__)"
39+
40+
- name: Verify pandas version contract
41+
run: |
42+
python - <<'PY'
43+
import pandas as pd
44+
45+
major, minor, *_ = (int(part) for part in pd.__version__.split('.') if part.isdigit())
46+
if (major, minor) != (3, 0):
47+
raise SystemExit(f'Expected pandas 3.0.x, found {pd.__version__}')
48+
print(f'Validated pandas {pd.__version__} against the 3.0.x contract.')
49+
PY
50+
51+
- name: Verify multilingual pandas Python block parity
52+
run: |
53+
python - <<'PY'
54+
import re
55+
from pathlib import Path
56+
57+
paths = [
58+
Path('external-libraries/01-pandas/README.md'),
59+
Path('external-libraries/01-pandas/README.pt-BR.md'),
60+
Path('external-libraries/01-pandas/README.es.md'),
61+
]
62+
pattern = re.compile(r'```python\n(.*?)```', re.DOTALL)
63+
blocks = [pattern.findall(path.read_text(encoding='utf-8')) for path in paths]
64+
if not blocks[0]:
65+
raise SystemExit('No pandas Python blocks found.')
66+
if not (blocks[0] == blocks[1] == blocks[2]):
67+
raise SystemExit('Pandas Python fenced blocks differ across EN/PT-BR/ES.')
68+
sections = [
69+
len(re.findall(r'^## \d+\.', path.read_text(encoding='utf-8'), re.MULTILINE))
70+
for path in paths
71+
]
72+
if sections != [65, 65, 65]:
73+
raise SystemExit(f'Expected 65 numbered sections per language, found {sections}')
74+
print(f'Validated {len(blocks[0])} identical Python blocks and 65 sections per language.')
75+
PY
76+
77+
- name: Compile Python files
78+
run: python -m compileall -q -x '(^|/)\.git/' .
79+
80+
- name: Run repository tests
81+
run: python -m unittest discover -s tests -p 'test_*.py'
82+
83+
- name: Run approved examples
84+
run: python scripts/run_examples.py
85+
86+
- name: Verify pandas example outputs
87+
run: |
88+
python - <<'PY'
89+
import subprocess
90+
import sys
91+
92+
expected = {
93+
'external-libraries/01-pandas/examples/dataframe_basics.py': (
94+
"shape: (3, 4)\n"
95+
"columns: ['product', 'units', 'unit_price', 'total']\n"
96+
"grand total: 8660.00\n"
97+
),
98+
'external-libraries/01-pandas/examples/filter_and_assign.py': (
99+
"[{'order_id': 101, 'priority': 'normal'}, {'order_id': 103, 'priority': 'high'}, "
100+
"{'order_id': 104, 'priority': 'normal'}]\n"
101+
),
102+
'external-libraries/01-pandas/examples/groupby_summary.py': (
103+
"[{'category': 'books', 'total_amount': 75.0, 'transaction_count': 2}, "
104+
"{'category': 'games', 'total_amount': 200.0, 'transaction_count': 2}, "
105+
"{'category': 'office', 'total_amount': 25.0, 'transaction_count': 1}]\n"
106+
),
107+
'external-libraries/01-pandas/examples/merge_tables.py': (
108+
"[{'order_id': 1, 'customer': 'Aster', 'amount': 50.0}, "
109+
"{'order_id': 2, 'customer': 'Boreal', 'amount': 80.0}, "
110+
"{'order_id': 3, 'customer': 'Aster', 'amount': 30.0}]\n"
111+
),
112+
'external-libraries/01-pandas/examples/csv_pipeline.py': (
113+
"rows: 2\ntotal: 370.50\nsaved: paid_orders.csv\n"
114+
),
115+
}
116+
117+
for path, wanted in expected.items():
118+
completed = subprocess.run(
119+
[sys.executable, path],
120+
check=True,
121+
capture_output=True,
122+
text=True,
123+
)
124+
if completed.stdout != wanted:
125+
raise SystemExit(
126+
f'Unexpected output for {path}:\n{completed.stdout!r}\nExpected:\n{wanted!r}'
127+
)
128+
print('Validated exact output for all five pandas examples.')
129+
PY
130+
131+
- name: Check internal links
132+
run: python scripts/check_internal_links.py
133+
134+
- name: Validate repository structure
135+
run: python scripts/validate_repository_structure.py
136+
137+
- name: Check diff whitespace
138+
run: git diff --check
139+
140+
- name: Commit synchronized navigation
141+
run: |
142+
git config user.name "Ramon Rodriguez"
143+
git config user.email "ramoncorreka@hotmail.com"
144+
git add README.md docs external-libraries standard-library
145+
git commit -m "Synchronize Phase 9 pandas navigation"
146+
git push origin HEAD:phase-09-pandas-tabular-data-contracts

0 commit comments

Comments
 (0)