Skip to content

Commit 805dfc4

Browse files
authored
feat: create script to update versions automatically (#132)
* feat: create script to update versions automaticlly * chore: use full commit SHA hash for this dependency * fix: update update_versions.py * fix: update update_versions.py
1 parent cb96c23 commit 805dfc4

File tree

5 files changed

+268
-91
lines changed

5 files changed

+268
-91
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: Update Tool Versions
2+
3+
on:
4+
schedule:
5+
# Run every Monday at 2 AM UTC
6+
- cron: '0 2 * * 1'
7+
workflow_dispatch: # Allow manual trigger
8+
9+
jobs:
10+
update-versions:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v4
16+
with:
17+
token: ${{ secrets.GITHUB_TOKEN }}
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v4
21+
with:
22+
python-version: '3.11'
23+
24+
- name: Update versions
25+
run: |
26+
python3 scripts/update_versions.py
27+
28+
- name: Check for changes
29+
id: verify-changed-files
30+
run: |
31+
if [ -n "$(git status --porcelain)" ]; then
32+
echo "changed=true" >> $GITHUB_OUTPUT
33+
else
34+
echo "changed=false" >> $GITHUB_OUTPUT
35+
fi
36+
37+
- name: Get latest versions for PR description
38+
if: steps.verify-changed-files.outputs.changed == 'true'
39+
id: get-versions
40+
run: |
41+
CLANG_FORMAT_VERSION=$(python3 -c 'from cpp_linter_hooks.versions import CLANG_FORMAT_VERSIONS; print(CLANG_FORMAT_VERSIONS[-1])')
42+
CLANG_TIDY_VERSION=$(python3 -c 'from cpp_linter_hooks.versions import CLANG_TIDY_VERSIONS; print(CLANG_TIDY_VERSIONS[-1])')
43+
echo "clang_format_version=$CLANG_FORMAT_VERSION" >> $GITHUB_OUTPUT
44+
echo "clang_tidy_version=$CLANG_TIDY_VERSION" >> $GITHUB_OUTPUT
45+
46+
- name: Create Pull Request
47+
if: steps.verify-changed-files.outputs.changed == 'true'
48+
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
49+
with:
50+
token: ${{ secrets.GITHUB_TOKEN }}
51+
commit-message: |
52+
chore: update clang-format and clang-tidy versions
53+
54+
- Updated versions automatically from PyPI
55+
title: "chore: update tool versions to latest"
56+
body: |
57+
## 🔄 Automated Version Update
58+
59+
This PR updates the hardcoded versions for clang-format and clang-tidy tools to the latest available versions from PyPI.
60+
61+
### 📦 Updated Versions
62+
- **clang-format**: `${{ steps.get-versions.outputs.clang_format_version }}`
63+
- **clang-tidy**: `${{ steps.get-versions.outputs.clang_tidy_version }}`
64+
65+
### 🤖 Automation Details
66+
- This update was triggered automatically by the scheduled workflow
67+
- Versions are fetched from the official PyPI APIs
68+
- Only stable versions (no pre-releases) are included
69+
70+
### ✅ What's Changed
71+
- Updated `cpp_linter_hooks/versions.py` with latest tool versions
72+
- No breaking changes expected
73+
- Maintains backward compatibility
74+
75+
### 🔍 Review Checklist
76+
- [ ] Verify the new versions are stable releases
77+
- [ ] Check that no pre-release versions were included
78+
- [ ] Confirm the version format matches expectations
79+
80+
---
81+
82+
*This PR was created automatically by the `update-versions.yml` workflow.*
83+
branch: update-tool-versions
84+
delete-branch: true
85+
base: main
86+
labels: dependencies

cpp_linter_hooks/util.py

Lines changed: 2 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
except ModuleNotFoundError:
1111
import tomli as tomllib
1212

13+
from cpp_linter_hooks.versions import CLANG_FORMAT_VERSIONS, CLANG_TIDY_VERSIONS
14+
1315
LOG = logging.getLogger(__name__)
1416

1517

@@ -32,95 +34,6 @@ def get_version_from_dependency(tool: str) -> Optional[str]:
3234
DEFAULT_CLANG_TIDY_VERSION = get_version_from_dependency("clang-tidy")
3335

3436

35-
# https://pypi.org/pypi/clang-format/json
36-
CLANG_FORMAT_VERSIONS = [
37-
"6.0.1",
38-
"7.1.0",
39-
"8.0.1",
40-
"9.0.0",
41-
"10.0.1",
42-
"10.0.1.1",
43-
"11.0.1",
44-
"11.0.1.1",
45-
"11.0.1.2",
46-
"11.1.0",
47-
"11.1.0.1",
48-
"11.1.0.2",
49-
"12.0.1",
50-
"12.0.1.1",
51-
"12.0.1.2",
52-
"13.0.0",
53-
"13.0.1",
54-
"13.0.1.1",
55-
"14.0.0",
56-
"14.0.1",
57-
"14.0.3",
58-
"14.0.4",
59-
"14.0.5",
60-
"14.0.6",
61-
"15.0.4",
62-
"15.0.6",
63-
"15.0.7",
64-
"16.0.0",
65-
"16.0.1",
66-
"16.0.2",
67-
"16.0.3",
68-
"16.0.4",
69-
"16.0.5",
70-
"16.0.6",
71-
"17.0.1",
72-
"17.0.2",
73-
"17.0.3",
74-
"17.0.4",
75-
"17.0.5",
76-
"17.0.6",
77-
"18.1.0",
78-
"18.1.1",
79-
"18.1.2",
80-
"18.1.3",
81-
"18.1.4",
82-
"18.1.5",
83-
"18.1.6",
84-
"18.1.7",
85-
"18.1.8",
86-
"19.1.0",
87-
"19.1.1",
88-
"19.1.2",
89-
"19.1.3",
90-
"19.1.4",
91-
"19.1.5",
92-
"19.1.6",
93-
"19.1.7",
94-
"20.1.0",
95-
"20.1.3",
96-
"20.1.4",
97-
"20.1.5",
98-
"20.1.6",
99-
"20.1.7",
100-
"20.1.8",
101-
"21.1.0",
102-
"21.1.1",
103-
"21.1.2",
104-
]
105-
106-
# https://pypi.org/pypi/clang-tidy/json
107-
CLANG_TIDY_VERSIONS = [
108-
"13.0.1.1",
109-
"14.0.6",
110-
"15.0.2",
111-
"15.0.2.1",
112-
"16.0.4",
113-
"17.0.1",
114-
"18.1.1",
115-
"18.1.8",
116-
"19.1.0",
117-
"19.1.0.1",
118-
"20.1.0",
119-
"21.1.0",
120-
"21.1.1",
121-
]
122-
123-
12437
def _resolve_version(versions: List[str], user_input: Optional[str]) -> Optional[str]:
12538
"""Resolve the latest matching version based on user input and available versions."""
12639
if user_input is None:

cpp_linter_hooks/versions.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
"""
2+
Version management for clang-format and clang-tidy.
3+
4+
This module provides hardcoded version lists that are updated periodically via GitHub Actions.
5+
"""
6+
7+
# Updated automatically by GitHub Actions - DO NOT EDIT MANUALLY
8+
CLANG_FORMAT_VERSIONS = [
9+
"6.0.1",
10+
"7.1.0",
11+
"8.0.1",
12+
"9.0.0",
13+
"10.0.1",
14+
"10.0.1.1",
15+
"11.0.1",
16+
"11.0.1.1",
17+
"11.0.1.2",
18+
"11.1.0",
19+
"11.1.0.1",
20+
"11.1.0.2",
21+
"12.0.1",
22+
"12.0.1.1",
23+
"12.0.1.2",
24+
"13.0.0",
25+
"13.0.1",
26+
"13.0.1.1",
27+
"14.0.0",
28+
"14.0.1",
29+
"14.0.3",
30+
"14.0.4",
31+
"14.0.5",
32+
"14.0.6",
33+
"15.0.4",
34+
"15.0.6",
35+
"15.0.7",
36+
"16.0.0",
37+
"16.0.1",
38+
"16.0.2",
39+
"16.0.3",
40+
"16.0.4",
41+
"16.0.5",
42+
"16.0.6",
43+
"17.0.1",
44+
"17.0.2",
45+
"17.0.3",
46+
"17.0.4",
47+
"17.0.5",
48+
"17.0.6",
49+
"18.1.0",
50+
"18.1.1",
51+
"18.1.2",
52+
"18.1.3",
53+
"18.1.4",
54+
"18.1.5",
55+
"18.1.6",
56+
"18.1.7",
57+
"18.1.8",
58+
"19.1.0",
59+
"19.1.1",
60+
"19.1.2",
61+
"19.1.3",
62+
"19.1.4",
63+
"19.1.5",
64+
"19.1.6",
65+
"19.1.7",
66+
"20.1.0",
67+
"20.1.3",
68+
"20.1.4",
69+
"20.1.5",
70+
"20.1.6",
71+
"20.1.7",
72+
"20.1.8",
73+
"21.1.0",
74+
"21.1.1",
75+
"21.1.2",
76+
]
77+
78+
# Updated automatically by GitHub Actions - DO NOT EDIT MANUALLY
79+
CLANG_TIDY_VERSIONS = [
80+
"13.0.1.1",
81+
"14.0.6",
82+
"15.0.2",
83+
"15.0.2.1",
84+
"16.0.4",
85+
"17.0.1",
86+
"18.1.1",
87+
"18.1.8",
88+
"19.1.0",
89+
"19.1.0.1",
90+
"20.1.0",
91+
"21.1.0",
92+
"21.1.1",
93+
]

scripts/update_versions.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to update clang-format and clang-tidy versions from PyPI API.
4+
5+
Usage:
6+
python scripts/update_versions.py
7+
"""
8+
9+
import json
10+
import urllib.request
11+
from pathlib import Path
12+
import re
13+
from typing import List
14+
15+
16+
def fetch_versions_from_pypi(package_name: str) -> List[str]:
17+
"""Fetch available versions for a package from PyPI API."""
18+
url = f"https://pypi.org/pypi/{package_name}/json"
19+
try:
20+
with urllib.request.urlopen(url, timeout=10) as response:
21+
data = json.loads(response.read())
22+
versions = list(data["releases"].keys())
23+
# Filter out pre-release versions using proper regex patterns
24+
pre_release_pattern = re.compile(
25+
r".*(alpha|beta|rc|dev|a\d+|b\d+).*", re.IGNORECASE
26+
)
27+
stable_versions = [v for v in versions if not pre_release_pattern.match(v)]
28+
return sorted(stable_versions, key=lambda x: tuple(map(int, x.split("."))))
29+
except Exception as e:
30+
print(f"Failed to fetch versions for {package_name}: {e}")
31+
return []
32+
33+
34+
def update_versions_file():
35+
"""Update the versions.py file with latest versions from PyPI."""
36+
clang_format_versions = fetch_versions_from_pypi("clang-format")
37+
clang_tidy_versions = fetch_versions_from_pypi("clang-tidy")
38+
39+
if not clang_format_versions or not clang_tidy_versions:
40+
print("Failed to fetch versions from PyPI")
41+
return False
42+
43+
versions_file = Path(__file__).parent.parent / "cpp_linter_hooks" / "versions.py"
44+
45+
with open(versions_file, "r") as f:
46+
content = f.read()
47+
48+
# Update clang-format versions
49+
clang_format_list = (
50+
"[\n" + "\n".join(f' "{v}",' for v in clang_format_versions) + "\n]"
51+
)
52+
content = re.sub(
53+
r"(CLANG_FORMAT_VERSIONS = )\[[^\]]*\]",
54+
rf"\1{clang_format_list}",
55+
content,
56+
flags=re.DOTALL,
57+
)
58+
59+
# Update clang-tidy versions
60+
clang_tidy_list = (
61+
"[\n" + "\n".join(f' "{v}",' for v in clang_tidy_versions) + "\n]"
62+
)
63+
content = re.sub(
64+
r"(CLANG_TIDY_VERSIONS = )\[[^\]]*\]",
65+
rf"\1{clang_tidy_list}",
66+
content,
67+
flags=re.DOTALL,
68+
)
69+
70+
with open(versions_file, "w") as f:
71+
f.write(content)
72+
73+
print("Updated versions:")
74+
print(
75+
f" clang-format: {len(clang_format_versions)} versions (latest: {clang_format_versions[-1]})"
76+
)
77+
print(
78+
f" clang-tidy: {len(clang_tidy_versions)} versions (latest: {clang_tidy_versions[-1]})"
79+
)
80+
81+
return True
82+
83+
84+
if __name__ == "__main__":
85+
success = update_versions_file()
86+
exit(0 if success else 1)

tests/test_util.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@
99
_resolve_version,
1010
_install_tool,
1111
_resolve_install,
12-
CLANG_FORMAT_VERSIONS,
13-
CLANG_TIDY_VERSIONS,
1412
DEFAULT_CLANG_FORMAT_VERSION,
1513
DEFAULT_CLANG_TIDY_VERSION,
1614
)
15+
from cpp_linter_hooks.versions import CLANG_FORMAT_VERSIONS, CLANG_TIDY_VERSIONS
1716

1817

1918
VERSIONS = [None, "20"]

0 commit comments

Comments
 (0)