From 30d3e001d06b50d83eb11b0b2d671e8beb219c89 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Wed, 24 Sep 2025 13:17:01 +0200 Subject: [PATCH 1/7] feat(toxgen): Remove merge conflict-prone last updated timestamp --- scripts/populate_tox/populate_tox.py | 37 ++++++++++------------------ scripts/populate_tox/tox.jinja | 2 -- tox.ini | 2 -- 3 files changed, 13 insertions(+), 28 deletions(-) diff --git a/scripts/populate_tox/populate_tox.py b/scripts/populate_tox/populate_tox.py index 070ce82492..6d983d7d86 100644 --- a/scripts/populate_tox/populate_tox.py +++ b/scripts/populate_tox/populate_tox.py @@ -8,6 +8,7 @@ import hashlib import json import os +import subprocess import sys import time from bisect import bisect_left @@ -509,9 +510,7 @@ def _render_dependencies(integration: str, releases: list[Version]) -> list[str] return rendered -def write_tox_file( - packages: dict, update_timestamp: bool, last_updated: datetime -) -> None: +def write_tox_file(packages: dict) -> None: template = ENV.get_template("tox.jinja") context = {"groups": {}} @@ -530,11 +529,6 @@ def write_tox_file( } ) - if update_timestamp: - context["updated"] = datetime.now(tz=timezone.utc).isoformat() - else: - context["updated"] = last_updated.isoformat() - rendered = template.render(context) with open(TOX_FILE, "w") as file: @@ -623,19 +617,16 @@ def get_file_hash() -> str: def get_last_updated() -> Optional[datetime]: - timestamp = None - - with open(TOX_FILE, "r") as f: - for line in f: - if line.startswith("# Last generated:"): - timestamp = datetime.fromisoformat(line.strip().split()[-1]) - break - - if timestamp is None: - print( - "Failed to find out when tox.ini was last generated; the timestamp seems to be missing from the file." + timestamp = ( + subprocess.run( + ["git", "log", "-1", "--pretty=%ct", "../tox.ini"], + capture_output=True, ) - + .stdout.decode("utf-8") + .strip() + ) + timestamp = datetime.fromtimestamp(int(timestamp), timezone.utc) + print(f"Last tox.ini update: {timestamp}") return timestamp @@ -675,7 +666,7 @@ def main(fail_on_changes: bool = False) -> None: print(f"Running in {'fail_on_changes' if fail_on_changes else 'normal'} mode.") last_updated = get_last_updated() if fail_on_changes: - # We need to make the script ignore any new releases after the `last_updated` + # We need to make the script ignore any new releases after the last updated # timestamp so that we don't fail CI on a PR just because a new package # version was released, leading to unrelated changes in tox.ini. print( @@ -769,9 +760,7 @@ def main(fail_on_changes: bool = False) -> None: if fail_on_changes: old_file_hash = get_file_hash() - write_tox_file( - packages, update_timestamp=not fail_on_changes, last_updated=last_updated - ) + write_tox_file(packages) # Sort the release cache file releases = [] diff --git a/scripts/populate_tox/tox.jinja b/scripts/populate_tox/tox.jinja index 9aa942ebe4..d87bcea810 100755 --- a/scripts/populate_tox/tox.jinja +++ b/scripts/populate_tox/tox.jinja @@ -9,8 +9,6 @@ # or in the script (if you want to change the auto-generated part). # The file (and all resulting CI YAMLs) then need to be regenerated via # "scripts/generate-test-files.sh". -# -# Last generated: {{ updated }} [tox] requires = diff --git a/tox.ini b/tox.ini index 7520a4cb1f..91dfc8abd8 100644 --- a/tox.ini +++ b/tox.ini @@ -9,8 +9,6 @@ # or in the script (if you want to change the auto-generated part). # The file (and all resulting CI YAMLs) then need to be regenerated via # "scripts/generate-test-files.sh". -# -# Last generated: 2025-09-24T08:25:49.003370+00:00 [tox] requires = From d2fbc9873a58823e83f0b8347977887a9ba4c3ac Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Wed, 24 Sep 2025 13:45:02 +0200 Subject: [PATCH 2/7] . --- scripts/populate_tox/populate_tox.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/scripts/populate_tox/populate_tox.py b/scripts/populate_tox/populate_tox.py index 6d983d7d86..5db2f5b11b 100644 --- a/scripts/populate_tox/populate_tox.py +++ b/scripts/populate_tox/populate_tox.py @@ -617,14 +617,13 @@ def get_file_hash() -> str: def get_last_updated() -> Optional[datetime]: - timestamp = ( - subprocess.run( - ["git", "log", "-1", "--pretty=%ct", "../tox.ini"], - capture_output=True, - ) - .stdout.decode("utf-8") - .strip() + timestamp = subprocess.run( + ["git", "log", "-1", "--pretty=%ct", "../tox.ini"], + capture_output=True, ) + print(timestamp) + timestamp = timestamp.stdout.decode("utf-8").strip() + print(timestamp) timestamp = datetime.fromtimestamp(int(timestamp), timezone.utc) print(f"Last tox.ini update: {timestamp}") return timestamp From 12e894244eed057bfa4faecee45b970a14d8d458 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Wed, 24 Sep 2025 14:45:32 +0200 Subject: [PATCH 3/7] . --- scripts/populate_tox/populate_tox.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/scripts/populate_tox/populate_tox.py b/scripts/populate_tox/populate_tox.py index 5db2f5b11b..f9245549fb 100644 --- a/scripts/populate_tox/populate_tox.py +++ b/scripts/populate_tox/populate_tox.py @@ -617,13 +617,19 @@ def get_file_hash() -> str: def get_last_updated() -> Optional[datetime]: + repo_root = subprocess.run( + ["git", "rev-parse", "--show-toplevel"], + capture_output=True, + text=True, + ).stdout.strip() + tox_ini_path = Path(repo_root) / "tox.ini" + timestamp = subprocess.run( - ["git", "log", "-1", "--pretty=%ct", "../tox.ini"], + ["git", "log", "-1", "--pretty=%ct", str(tox_ini_path)], capture_output=True, - ) - print(timestamp) - timestamp = timestamp.stdout.decode("utf-8").strip() - print(timestamp) + text=True, + ).stdout.strip() + timestamp = datetime.fromtimestamp(int(timestamp), timezone.utc) print(f"Last tox.ini update: {timestamp}") return timestamp From 199f3261df4d299049fa8d73c16a6b2c297d8b61 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Wed, 24 Sep 2025 14:57:53 +0200 Subject: [PATCH 4/7] . --- scripts/populate_tox/populate_tox.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/populate_tox/populate_tox.py b/scripts/populate_tox/populate_tox.py index f9245549fb..ef08862532 100644 --- a/scripts/populate_tox/populate_tox.py +++ b/scripts/populate_tox/populate_tox.py @@ -622,8 +622,9 @@ def get_last_updated() -> Optional[datetime]: capture_output=True, text=True, ).stdout.strip() + print(repo_root) tox_ini_path = Path(repo_root) / "tox.ini" - + print(tox_ini_path) timestamp = subprocess.run( ["git", "log", "-1", "--pretty=%ct", str(tox_ini_path)], capture_output=True, From 24993f485f2f9d9aabb8234e6e414b825a6bd20b Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Wed, 24 Sep 2025 15:00:06 +0200 Subject: [PATCH 5/7] . --- scripts/populate_tox/populate_tox.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/populate_tox/populate_tox.py b/scripts/populate_tox/populate_tox.py index ef08862532..664bde42a7 100644 --- a/scripts/populate_tox/populate_tox.py +++ b/scripts/populate_tox/populate_tox.py @@ -625,6 +625,13 @@ def get_last_updated() -> Optional[datetime]: print(repo_root) tox_ini_path = Path(repo_root) / "tox.ini" print(tox_ini_path) + a = subprocess.run( + ["git", "log", "-1", str(tox_ini_path)], + capture_output=True, + text=True, + ).stdout.strip() + print(a) + timestamp = subprocess.run( ["git", "log", "-1", "--pretty=%ct", str(tox_ini_path)], capture_output=True, From e52d67326f42b3748c44e042b0c831bd694824c3 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Wed, 24 Sep 2025 15:09:26 +0200 Subject: [PATCH 6/7] fetch all --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67b4fd3546..50ab1d39ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,6 +40,9 @@ jobs: steps: - uses: actions/checkout@v5.0.0 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 - uses: actions/setup-python@v6 with: python-version: 3.12 From 6765dd88e3f5ec22453b6ea45cdc7740700cd8f8 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Wed, 24 Sep 2025 15:11:47 +0200 Subject: [PATCH 7/7] . --- scripts/populate_tox/populate_tox.py | 10 +--------- scripts/populate_tox/releases.jsonl | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/scripts/populate_tox/populate_tox.py b/scripts/populate_tox/populate_tox.py index 664bde42a7..f13fa6d002 100644 --- a/scripts/populate_tox/populate_tox.py +++ b/scripts/populate_tox/populate_tox.py @@ -622,15 +622,7 @@ def get_last_updated() -> Optional[datetime]: capture_output=True, text=True, ).stdout.strip() - print(repo_root) tox_ini_path = Path(repo_root) / "tox.ini" - print(tox_ini_path) - a = subprocess.run( - ["git", "log", "-1", str(tox_ini_path)], - capture_output=True, - text=True, - ).stdout.strip() - print(a) timestamp = subprocess.run( ["git", "log", "-1", "--pretty=%ct", str(tox_ini_path)], @@ -639,7 +631,7 @@ def get_last_updated() -> Optional[datetime]: ).stdout.strip() timestamp = datetime.fromtimestamp(int(timestamp), timezone.utc) - print(f"Last tox.ini update: {timestamp}") + print(f"Last committed tox.ini update: {timestamp}") return timestamp diff --git a/scripts/populate_tox/releases.jsonl b/scripts/populate_tox/releases.jsonl index fa82e6b1cd..96eb2da8e0 100644 --- a/scripts/populate_tox/releases.jsonl +++ b/scripts/populate_tox/releases.jsonl @@ -107,7 +107,7 @@ {"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "Intended Audience :: Information Technology", "Intended Audience :: System Administrators", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Internet", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: HTTP Servers", "Topic :: Software Development", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Application Frameworks", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "litestar", "requires_python": "<4.0,>=3.8", "version": "2.6.4", "yanked": false}} {"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: System :: Logging"], "name": "loguru", "requires_python": "<4.0,>=3.5", "version": "0.7.3", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai", "requires_python": ">=3.7.1", "version": "1.0.1", "yanked": false}} -{"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai", "requires_python": ">=3.8", "version": "1.109.0", "yanked": false}} +{"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai", "requires_python": ">=3.8", "version": "1.109.1", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai", "requires_python": ">=3.7.1", "version": "1.37.2", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai", "requires_python": ">=3.8", "version": "1.73.0", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai-agents", "requires_python": ">=3.9", "version": "0.0.19", "yanked": false}}