From b36e14708c035fda483866d3b8eff78fc432e20c Mon Sep 17 00:00:00 2001 From: Nicholas Felt Date: Wed, 13 Nov 2024 11:47:22 -0800 Subject: [PATCH] Group Python version updates for Dockerfiles and pyproject.toml together (#213) * refactor: Combine docker RUN commands * refactor: Remove python version restraint from exported requirements files since it isn't necessary * chore: Update renovate configuration to group Python version updates together for Dockerfiles and the pyproject.toml file --- .github/renovate.json | 22 ++- .../requirements.txt | 36 ++--- .../Dockerfile | 4 +- .../Dockerfile | 4 +- .../requirements.txt | 126 +++++++++--------- pyproject.toml | 11 +- ..._python_version_condition_from_req_file.py | 32 +++++ 7 files changed, 144 insertions(+), 91 deletions(-) create mode 100644 scripts/remove_python_version_condition_from_req_file.py diff --git a/.github/renovate.json b/.github/renovate.json index 73dc217e..d1e82788 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -12,9 +12,10 @@ "packageRules": [ { "additionalBranchPrefix": "{{#if (equals manager 'github-actions')}}gh-actions{{else}}{{categories}}{{/if}}-deps/", - "description": "Set the branch prefix and minimum release age for all updates", - "matchPackageNames": [ - "*" + "description": "Set the branch prefix and minimum release age for all updates except the main Python version", + "matchDepNames": [ + "*", + "!python" ], "minimumReleaseAge": "5 days" }, @@ -133,6 +134,21 @@ "matchPackageNames": [ "*" ] + }, + { + "additionalBranchPrefix": "", + "commitMessageSuffix": " in all dependant actions", + "description": "Group together all Python (official) version updates", + "groupName": "python version", + "matchDepNames": [ + "python" + ], + "matchManagers": [ + "dockerfile", + "poetry" + ], + "semanticCommitScope": "python-version", + "semanticCommitType": "chore" } ], "platformCommit": "enabled", diff --git a/actions/create_unique_testpypi_version/requirements.txt b/actions/create_unique_testpypi_version/requirements.txt index 1442da84..0e135bf9 100644 --- a/actions/create_unique_testpypi_version/requirements.txt +++ b/actions/create_unique_testpypi_version/requirements.txt @@ -1,18 +1,18 @@ -annotated-types==0.7.0 ; python_version >= "3.12" and python_version < "3.13" -attrs==24.2.0 ; python_version >= "3.12" and python_version < "3.13" -beautifulsoup4==4.12.3 ; python_version >= "3.12" and python_version < "3.13" -certifi==2024.8.30 ; python_version >= "3.12" and python_version < "3.13" -charset-normalizer==3.4.0 ; python_version >= "3.12" and python_version < "3.13" -idna==3.10 ; python_version >= "3.12" and python_version < "3.13" -mailbits==0.2.1 ; python_version >= "3.12" and python_version < "3.13" -packaging==24.1 ; python_version >= "3.12" and python_version < "3.13" -poetry-core==1.9.1 ; python_version >= "3.12" and python_version < "3.13" -pydantic==2.9.2 ; python_version >= "3.12" and python_version < "3.13" -pydantic-core==2.23.4 ; python_version >= "3.12" and python_version < "3.13" -pypi-simple==1.6.1 ; python_version >= "3.12" and python_version < "3.13" -requests==2.32.3 ; python_version >= "3.12" and python_version < "3.13" -soupsieve==2.6 ; python_version >= "3.12" and python_version < "3.13" -tomli==2.0.2 ; python_version >= "3.12" and python_version < "3.13" -tomli-w==1.1.0 ; python_version >= "3.12" and python_version < "3.13" -typing-extensions==4.12.2 ; python_version >= "3.12" and python_version < "3.13" -urllib3==2.2.3 ; python_version >= "3.12" and python_version < "3.13" +annotated-types==0.7.0 +attrs==24.2.0 +beautifulsoup4==4.12.3 +certifi==2024.8.30 +charset-normalizer==3.4.0 +idna==3.10 +mailbits==0.2.1 +packaging==24.1 +poetry-core==1.9.1 +pydantic==2.9.2 +pydantic-core==2.23.4 +pypi-simple==1.6.1 +requests==2.32.3 +soupsieve==2.6 +tomli==2.0.2 +tomli-w==1.1.0 +typing-extensions==4.12.2 +urllib3==2.2.3 diff --git a/actions/find_unreleased_changelog_items/Dockerfile b/actions/find_unreleased_changelog_items/Dockerfile index e851d99d..c382ef2c 100644 --- a/actions/find_unreleased_changelog_items/Dockerfile +++ b/actions/find_unreleased_changelog_items/Dockerfile @@ -7,8 +7,8 @@ COPY main.py /main.py # Install dependencies RUN apk update && \ apk add --no-cache git && \ - rm -rf /var/cache/apk/* -RUN python -m pip install --no-cache-dir --requirement /requirements.txt + rm -rf /var/cache/apk/* && \ + python -m pip install --no-cache-dir --requirement /requirements.txt # Run the Python script as the entrypoint CMD ["python", "-u", "/main.py"] diff --git a/actions/update_development_dependencies/Dockerfile b/actions/update_development_dependencies/Dockerfile index e851d99d..c382ef2c 100644 --- a/actions/update_development_dependencies/Dockerfile +++ b/actions/update_development_dependencies/Dockerfile @@ -7,8 +7,8 @@ COPY main.py /main.py # Install dependencies RUN apk update && \ apk add --no-cache git && \ - rm -rf /var/cache/apk/* -RUN python -m pip install --no-cache-dir --requirement /requirements.txt + rm -rf /var/cache/apk/* && \ + python -m pip install --no-cache-dir --requirement /requirements.txt # Run the Python script as the entrypoint CMD ["python", "-u", "/main.py"] diff --git a/actions/update_development_dependencies/requirements.txt b/actions/update_development_dependencies/requirements.txt index 0f8fb130..8e3a8cf2 100644 --- a/actions/update_development_dependencies/requirements.txt +++ b/actions/update_development_dependencies/requirements.txt @@ -1,63 +1,63 @@ -annotated-types==0.7.0 ; python_version >= "3.12" and python_version < "3.13" -attrs==24.2.0 ; python_version >= "3.12" and python_version < "3.13" -beautifulsoup4==4.12.3 ; python_version >= "3.12" and python_version < "3.13" -build==1.2.2.post1 ; python_version >= "3.12" and python_version < "3.13" -cachecontrol[filecache]==0.14.1 ; python_version >= "3.12" and python_version < "3.13" -certifi==2024.8.30 ; python_version >= "3.12" and python_version < "3.13" -cffi==1.17.1 ; python_version >= "3.12" and python_version < "3.13" and (sys_platform == "darwin" or sys_platform == "linux") and (sys_platform == "darwin" or platform_python_implementation != "PyPy") -cfgv==3.4.0 ; python_version >= "3.12" and python_version < "3.13" -charset-normalizer==3.4.0 ; python_version >= "3.12" and python_version < "3.13" -cleo==2.1.0 ; python_version >= "3.12" and python_version < "3.13" -click==8.1.7 ; python_version >= "3.12" and python_version < "3.13" -colorama==0.4.6 ; python_version >= "3.12" and python_version < "3.13" and (os_name == "nt" or platform_system == "Windows") -crashtest==0.4.1 ; python_version >= "3.12" and python_version < "3.13" -cryptography==43.0.3 ; python_version >= "3.12" and python_version < "3.13" and sys_platform == "linux" -distlib==0.3.9 ; python_version >= "3.12" and python_version < "3.13" -distro==1.9.0 ; python_version >= "3.12" and python_version < "3.13" -dulwich==0.21.7 ; python_version >= "3.12" and python_version < "3.13" -fastjsonschema==2.20.0 ; python_version >= "3.12" and python_version < "3.13" -filelock==3.16.1 ; python_version >= "3.12" and python_version < "3.13" -identify==2.6.1 ; python_version >= "3.12" and python_version < "3.13" -idna==3.10 ; python_version >= "3.12" and python_version < "3.13" -installer==0.7.0 ; python_version >= "3.12" and python_version < "3.13" -jaraco-classes==3.4.0 ; python_version >= "3.12" and python_version < "3.13" -jeepney==0.8.0 ; python_version >= "3.12" and python_version < "3.13" and sys_platform == "linux" -keyring==24.3.1 ; python_version >= "3.12" and python_version < "3.13" -mailbits==0.2.1 ; python_version >= "3.12" and python_version < "3.13" -maison==2.0.0 ; python_version >= "3.12" and python_version < "3.13" -more-itertools==10.5.0 ; python_version >= "3.12" and python_version < "3.13" -msgpack==1.1.0 ; python_version >= "3.12" and python_version < "3.13" -nodeenv==1.9.1 ; python_version >= "3.12" and python_version < "3.13" -packaging==24.1 ; python_version >= "3.12" and python_version < "3.13" -pexpect==4.9.0 ; python_version >= "3.12" and python_version < "3.13" -pkginfo==1.11.2 ; python_version >= "3.12" and python_version < "3.13" -platformdirs==4.3.6 ; python_version >= "3.12" and python_version < "3.13" -poetry==1.8.4 ; python_version >= "3.12" and python_version < "3.13" -poetry-core==1.9.1 ; python_version >= "3.12" and python_version < "3.13" -poetry-plugin-export==1.8.0 ; python_version >= "3.12" and python_version < "3.13" -pre-commit==4.0.1 ; python_version >= "3.12" and python_version < "3.13" -ptyprocess==0.7.0 ; python_version >= "3.12" and python_version < "3.13" -pycparser==2.22 ; python_version >= "3.12" and python_version < "3.13" and (sys_platform == "darwin" or sys_platform == "linux") and (sys_platform == "darwin" or platform_python_implementation != "PyPy") -pydantic==2.9.2 ; python_version >= "3.12" and python_version < "3.13" -pydantic-core==2.23.4 ; python_version >= "3.12" and python_version < "3.13" -pypi-simple==1.6.1 ; python_version >= "3.12" and python_version < "3.13" -pyproject-hooks==1.2.0 ; python_version >= "3.12" and python_version < "3.13" -pywin32-ctypes==0.2.3 ; python_version >= "3.12" and python_version < "3.13" and sys_platform == "win32" -pyyaml==6.0.2 ; python_version >= "3.12" and python_version < "3.13" -rapidfuzz==3.10.1 ; python_version >= "3.12" and python_version < "3.13" -requests==2.32.3 ; python_version >= "3.12" and python_version < "3.13" -requests-toolbelt==1.0.0 ; python_version >= "3.12" and python_version < "3.13" -ruyaml==0.91.0 ; python_version >= "3.12" and python_version < "3.13" -secretstorage==3.3.3 ; python_version >= "3.12" and python_version < "3.13" and sys_platform == "linux" -setuptools==75.3.0 ; python_version >= "3.12" and python_version < "3.13" -shellingham==1.5.4 ; python_version >= "3.12" and python_version < "3.13" -soupsieve==2.6 ; python_version >= "3.12" and python_version < "3.13" -toml==0.10.2 ; python_version >= "3.12" and python_version < "3.13" -toml-sort==0.23.1 ; python_version >= "3.12" and python_version < "3.13" -tomlkit==0.13.2 ; python_version >= "3.12" and python_version < "3.13" -trove-classifiers==2024.10.21.16 ; python_version >= "3.12" and python_version < "3.13" -typing-extensions==4.12.2 ; python_version >= "3.12" and python_version < "3.13" -urllib3==2.2.3 ; python_version >= "3.12" and python_version < "3.13" -virtualenv==20.27.1 ; python_version >= "3.12" and python_version < "3.13" -xattr==1.1.0 ; python_version >= "3.12" and python_version < "3.13" and sys_platform == "darwin" -yamlfix==1.17.0 ; python_version >= "3.12" and python_version < "3.13" +annotated-types==0.7.0 +attrs==24.2.0 +beautifulsoup4==4.12.3 +build==1.2.2.post1 +cachecontrol[filecache]==0.14.1 +certifi==2024.8.30 +cffi==1.17.1 ; (sys_platform == "darwin" or sys_platform == "linux") and (sys_platform == "darwin" or platform_python_implementation != "PyPy") +cfgv==3.4.0 +charset-normalizer==3.4.0 +cleo==2.1.0 +click==8.1.7 +colorama==0.4.6 ; (os_name == "nt" or platform_system == "Windows") +crashtest==0.4.1 +cryptography==43.0.3 ; sys_platform == "linux" +distlib==0.3.9 +distro==1.9.0 +dulwich==0.21.7 +fastjsonschema==2.20.0 +filelock==3.16.1 +identify==2.6.1 +idna==3.10 +installer==0.7.0 +jaraco-classes==3.4.0 +jeepney==0.8.0 ; sys_platform == "linux" +keyring==24.3.1 +mailbits==0.2.1 +maison==2.0.0 +more-itertools==10.5.0 +msgpack==1.1.0 +nodeenv==1.9.1 +packaging==24.1 +pexpect==4.9.0 +pkginfo==1.11.2 +platformdirs==4.3.6 +poetry==1.8.4 +poetry-core==1.9.1 +poetry-plugin-export==1.8.0 +pre-commit==4.0.1 +ptyprocess==0.7.0 +pycparser==2.22 ; (sys_platform == "darwin" or sys_platform == "linux") and (sys_platform == "darwin" or platform_python_implementation != "PyPy") +pydantic==2.9.2 +pydantic-core==2.23.4 +pypi-simple==1.6.1 +pyproject-hooks==1.2.0 +pywin32-ctypes==0.2.3 ; sys_platform == "win32" +pyyaml==6.0.2 +rapidfuzz==3.10.1 +requests==2.32.3 +requests-toolbelt==1.0.0 +ruyaml==0.91.0 +secretstorage==3.3.3 ; sys_platform == "linux" +setuptools==75.3.0 +shellingham==1.5.4 +soupsieve==2.6 +toml==0.10.2 +toml-sort==0.23.1 +tomlkit==0.13.2 +trove-classifiers==2024.10.21.16 +typing-extensions==4.12.2 +urllib3==2.2.3 +virtualenv==20.27.1 +xattr==1.1.0 ; sys_platform == "darwin" +yamlfix==1.17.0 diff --git a/pyproject.toml b/pyproject.toml index d4b5972d..7f0de117 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,8 @@ exclude_lines = [ fail_under = 100 include_namespace_packages = true omit = [ - "contributor_setup.py" + "contributor_setup.py", + "remove_python_version_condition_from_req_file.py" ] show_missing = true skip_empty = true @@ -55,7 +56,7 @@ poetry-plugin-export = "1.8.0" poetry-pre-commit-plugin = "^0.1.2" pre-commit = "4.0.1" pylint = "3.3.1" -pyright = {extras = ["nodejs"], version = "^1.1.387"} +pyright = {extras = ["nodejs"], version = "1.1.387"} tox = "^4.18.0" tox-gh-actions = "^3.2.0" @@ -279,7 +280,7 @@ setenv = # Skip pre-commit checks that are not needed SKIP = file-contents-sorter commands_pre = - python -m poetry install + python -m poetry install --sync commands = !tests: pre-commit run --all-files pytest -vv -k "not test_docs" --showlocals --cov --junitxml={tox_root}/.results_{envname}/results.xml --cov-report=term --cov-report=xml:{tox_root}/.coverage_{envname}.xml --cov-report=html:{tox_root}/.results_{envname}/html --self-contained-html --html={tox_root}/.results_{envname}/results.html @@ -307,9 +308,13 @@ commands = [testenv:export-reqs] commands = poetry export --without-hashes --without-urls --all-extras --only=actions-create_unique_testpypi_version --output=actions/create_unique_testpypi_version/requirements.txt + python scripts/remove_python_version_condition_from_req_file.py actions/create_unique_testpypi_version/requirements.txt poetry export --without-hashes --without-urls --all-extras --only=actions-find_unreleased_changelog_items --output=actions/find_unreleased_changelog_items/requirements.txt + python scripts/remove_python_version_condition_from_req_file.py actions/find_unreleased_changelog_items/requirements.txt poetry export --without-hashes --without-urls --all-extras --only=actions-update_development_dependencies --output=actions/update_development_dependencies/requirements.txt + python scripts/remove_python_version_condition_from_req_file.py actions/update_development_dependencies/requirements.txt - pre-commit run -a requirements-txt-fixer + - pre-commit run -a trailing-whitespace - pre-commit run -a end-of-file-fixer """ diff --git a/scripts/remove_python_version_condition_from_req_file.py b/scripts/remove_python_version_condition_from_req_file.py new file mode 100644 index 00000000..ad425d95 --- /dev/null +++ b/scripts/remove_python_version_condition_from_req_file.py @@ -0,0 +1,32 @@ +"""Remove the Python version restraint from a requirements file.""" + +from __future__ import annotations + +import argparse +import re + +from pathlib import Path + +# Regular expression to match only the python_version constraints +PYTHON_VERSION_PATTERN = re.compile(r"python_version.*?(\sand\s*|$)") + +if __name__ == "__main__": # pragma: no cover + parser = argparse.ArgumentParser( + description="Remove python_version constraints from a requirements file." + ) + parser.add_argument("file_path", type=Path, help="Path to the requirements file.") + args = parser.parse_args() + file_path = Path(args.file_path) + # Read the file content + lines = file_path.read_text(encoding="utf-8").splitlines() + # Remove python_version constraints + updated_lines: list[str] = [] + for line in lines: + # Remove python_version constraints + updated_line = PYTHON_VERSION_PATTERN.sub("", line).strip() + # Remove trailing ';' if the line ends with it + if updated_line.endswith(";"): + updated_line = updated_line[:-1].strip() + updated_lines.append(updated_line) + # Write the updated content back to the file + file_path.write_text("\n".join(updated_lines) + "\n", encoding="utf-8")