Skip to content

Commit a70c200

Browse files
committed
feat: Automatic README, pyproject updater for supported Python versions
1 parent 0cdd5d7 commit a70c200

File tree

5 files changed

+201
-9
lines changed

5 files changed

+201
-9
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
name: Update README and pyproject.toml with supported versions
2+
3+
on:
4+
workflow_dispatch:
5+
schedule:
6+
- cron: '0 6 * * 1' # Weekly on Monday at 6 AM UTC (after main builds)
7+
workflow_run:
8+
workflows: ["platforms-dispatches"]
9+
types: [completed]
10+
branches: [main]
11+
12+
jobs:
13+
update-readme:
14+
name: Update README with current supported versions
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
with:
21+
token: ${{ secrets.GITHUB_TOKEN }}
22+
23+
- name: Setup Python
24+
uses: actions/setup-python@v5
25+
with:
26+
python-version: '3.13'
27+
28+
- name: Install dependencies
29+
run: |
30+
python -m pip install --upgrade pip
31+
python -m pip install requests python-dateutil
32+
33+
- name: Generate supported versions
34+
id: generate
35+
run: |
36+
python supported_versions.py ${{ secrets.IDF_VERSIONS_TXT }}
37+
# Capture the supported Python versions for PR description
38+
PYTHON_VERSIONS=$(jq -c '.supported_python' supported_versions.json)
39+
echo "supported_python=$PYTHON_VERSIONS" >> $GITHUB_OUTPUT
40+
41+
- name: Update README and pyproject.toml with supported Python versions
42+
run: |
43+
python update_python_versions.py
44+
45+
- name: Check for changes
46+
id: changes
47+
run: |
48+
if git diff --quiet README.md pyproject.toml; then
49+
echo "has_changes=false" >> $GITHUB_OUTPUT
50+
echo "No changes detected in README.md or pyproject.toml"
51+
else
52+
echo "has_changes=true" >> $GITHUB_OUTPUT
53+
echo "Changes detected:"
54+
git diff README.md pyproject.toml
55+
fi
56+
57+
- name: Create Pull Request
58+
if: steps.changes.outputs.has_changes == 'true'
59+
uses: peter-evans/create-pull-request@v6
60+
with:
61+
token: ${{ secrets.GITHUB_TOKEN }}
62+
commit-message: |
63+
Update README and pyproject.toml with current supported Python versions
64+
65+
Auto-updated by update-readme workflow based on current ESP-IDF and Python support lifecycle.
66+
67+
Changes:
68+
- Updated supported Python versions in README.md based on dynamic version detection
69+
- Updated ruff target-version and mypy python_version in pyproject.toml
70+
- Python versions are determined by ESP-IDF lifecycle and Python EOL dates
71+
title: "📝 Update README and pyproject.toml with current supported Python versions"
72+
body: |
73+
## Summary
74+
This PR automatically updates README.md and pyproject.toml with the current supported Python versions based on our dynamic version detection system.
75+
76+
## Changes Made
77+
- ✅ Updated "Supported Python versions" section in README.md
78+
- ✅ Updated ruff `target-version` in pyproject.toml
79+
- ✅ Updated mypy `python_version` in pyproject.toml
80+
- 🔄 Based on ESP-IDF lifecycle and Python EOL dates
81+
- 🤖 Generated by automated workflow
82+
83+
## Python Versions Updated
84+
The following Python versions are currently supported:
85+
```
86+
${{ steps.generate.outputs.supported_python }}
87+
```
88+
89+
## Verification
90+
- [ ] Python versions in README match our build matrix
91+
- [ ] pyproject.toml ruff target-version uses oldest Python version
92+
- [ ] pyproject.toml mypy python_version uses oldest Python version
93+
- [ ] No other sections of files were modified
94+
- [ ] All supported versions are actively maintained
95+
96+
---
97+
98+
> **Note**: This PR was automatically created by the [update-python-versions workflow](.github/workflows/update-python-versions.yml).
99+
> The Python versions are dynamically determined based on ESP-IDF support lifecycle.
100+
branch: update/readme-python-versions
101+
delete-branch: true
102+
assignees: ${{ github.actor }}
103+
reviewers: jakub-kocka
104+
labels: |
105+
documentation
106+
automated
107+
python-versions

.pre-commit-config.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ repos:
2020
- id: check-executables-have-shebangs
2121
- id: mixed-line-ending
2222
args: ['-f=lf']
23-
- id: double-quote-string-fixer
2423
- id: check-yaml
2524

2625
- repo: https://github.com/astral-sh/ruff-pre-commit

README.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,25 @@ Supported architectures:
1313
- ARM64
1414

1515
Supported Python versions:
16-
* 3.8
17-
* 3.9
18-
* 3.10
19-
* 3.11
20-
* 3.12
2116
* 3.13
17+
* 3.12
18+
* 3.11
19+
* 3.10
20+
* 3.9
21+
* 3.8
2222

2323
> [!NOTE]
24-
> This list of supported Python versions is automatically updated by [update_readme_versions.py](./update_readme_versions.py) script and [update-readme.yml](./.github/workflows/update-readme.yml) workflow.
24+
> This list of supported Python versions is automatically updated by [update_python_versions.py](./update_python_versions.py) script and [update-python-versions.yml](./.github/workflows/update-python-versions.yml) workflow.
2525
2626
For each `release` branch of [ESP-IDF] which is not EOL and [ESP-IDF] `master` branch, all the requirements and constraints files are automatically downloaded and wheels are built and uploaded.
2727

2828

2929
## Completely Automated
3030
This repository has been completely automated. All the supported versions of [ESP-IDF] and Python versions are fetch and resolved automatically. The implementation of this logic is in the [supported_versions.py](./supported_versions.py) script and [get-supported-versions.yml](./.github/workflows/get-supported-versions.yml) workflow.
3131

32-
### Supported versions action
32+
Also `README.md` file and `pyproject.toml` is automatically updated with the script `update_python_versions.py` and `update-python-versions.yml` workflow.
33+
34+
### Supported Versions Action
3335
This workflow is reusable action and it is possible to be called in other projects - it will generate `supported_versions.json` file with the following structure, which can be parsed and used in caller workflow to avoid developer interaction of changing the supported versions.
3436

3537
{

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@
1313
disallow_incomplete_defs = false # Disallows defining functions with incomplete type annotations
1414
disallow_untyped_defs = false # Disallows defining functions without type annotations or with incomplete type annotations
1515
ignore_missing_imports = true # Suppress error messages about imports that cannot be resolved
16-
python_version = "3.9" # Specifies the Python version used to parse and check the target program
16+
python_version = "3.8" # Specifies the Python version used to parse and check the target program
1717
warn_no_return = true # Shows errors for missing return statements on some execution paths
1818
warn_return_any = true # Shows a warning when returning a value with type Any from a function declared with a non- Any return type

update_python_versions.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""
4+
Script to update README.md and pyproject.toml with dynamically detected supported Python versions.
5+
"""
6+
7+
import json
8+
import re
9+
10+
11+
def update_python_versions():
12+
"""Update Python versions in README.md and pyproject.toml based on supported_versions.json"""
13+
14+
try:
15+
with open("supported_versions.json", "r") as f:
16+
versions_data = json.load(f)
17+
except FileNotFoundError:
18+
raise SystemExit("Error: supported_versions.json not found. Run supported_versions.py first.")
19+
20+
supported_python = versions_data.get("supported_python", [])
21+
if not supported_python:
22+
raise SystemExit("Error: No supported Python versions found in JSON.")
23+
24+
oldest_python = versions_data.get("oldest_supported_python", "")
25+
if not oldest_python:
26+
raise SystemExit("Error: No oldest supported Python version found in JSON.")
27+
28+
changes_made = []
29+
30+
# Update README.md
31+
try:
32+
with open("README.md", "r") as f:
33+
readme_content = f.read()
34+
except FileNotFoundError:
35+
raise SystemExit("Error: README.md not found.")
36+
37+
new_python_section = []
38+
for version in supported_python:
39+
new_python_section.append(f"* {version}")
40+
new_python_lines = "\n".join(new_python_section)
41+
42+
# Use regex to find and replace the Python versions section
43+
pattern = r"(Supported Python versions:\n)((?:\* \d+\.\d+\n)*)"
44+
replacement = f"\\1{new_python_lines}\n"
45+
new_readme = re.sub(pattern, replacement, readme_content)
46+
47+
if new_readme != readme_content:
48+
with open("README.md", "w") as f:
49+
f.write(new_readme)
50+
changes_made.append("README.md")
51+
52+
# Update pyproject.toml
53+
try:
54+
with open("pyproject.toml", "r") as f:
55+
pyproject_content = f.read()
56+
except FileNotFoundError:
57+
raise SystemExit("Error: pyproject.toml not found.")
58+
59+
# Update ruff target-version (e.g., "py38")
60+
py_version_compact = f"py{oldest_python.replace('.', '')}"
61+
ruff_pattern = r'(target-version\s*=\s*["\'])py\d+(["\'])'
62+
new_pyproject = re.sub(ruff_pattern, f"\\g<1>{py_version_compact}\\g<2>", pyproject_content)
63+
64+
# Update mypy python_version (e.g., "3.8")
65+
mypy_pattern = r'(python_version\s*=\s*["\'])\d+\.\d+(["\'])'
66+
new_pyproject = re.sub(mypy_pattern, f"\\g<1>{oldest_python}\\g<2>", new_pyproject)
67+
68+
if new_pyproject != pyproject_content:
69+
with open("pyproject.toml", "w") as f:
70+
f.write(new_pyproject)
71+
changes_made.append("pyproject.toml")
72+
73+
if not changes_made:
74+
print("ℹ️ No changes needed - Python versions are already up to date.")
75+
return False
76+
77+
files_updated = " and ".join(changes_made)
78+
print(f"✅ Updated {files_updated}")
79+
print(f" Supported versions: {', '.join(supported_python)}")
80+
print(f" Oldest supported Python version: {oldest_python}")
81+
return True
82+
83+
84+
update_python_versions()

0 commit comments

Comments
 (0)