From 43e1bcf9164d97397958ba0a2a023bcff53d5428 Mon Sep 17 00:00:00 2001 From: Priya Sundaram Date: Sat, 29 Aug 2026 07:21:14 +0000 Subject: [PATCH 1/2] Accept .lock files (uv.lock) in changed-file validation Lock files such as uv.lock are committed to keep CI reproducible. A transitive dependency bump (e.g. bumping the pinned typing-extensions so the build passes on a new Python) lives only in uv.lock, which the file extension check previously rejected as an invalid file. Add .lock to the accepted extensions so those PRs are allowed, with a test covering it. --- algorithms_keeper/parser/python_parser.py | 3 +++ tests/test_parser.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/algorithms_keeper/parser/python_parser.py b/algorithms_keeper/parser/python_parser.py index 61cebb9..4e7d485 100644 --- a/algorithms_keeper/parser/python_parser.py +++ b/algorithms_keeper/parser/python_parser.py @@ -72,6 +72,9 @@ class PythonParser(BaseFilesParser): ".csv", ".json", ".txt", + # Lock files (e.g. ``uv.lock``, ``poetry.lock``) are committed to keep CI + # reproducible; a transitive dependency bump lives only here, so allow it. + ".lock", # Good old Python file ".py", *DOCS_EXTENSIONS, diff --git a/tests/test_parser.py b/tests/test_parser.py index 6cf830e..805eee2 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -56,6 +56,8 @@ def test_contains_testfile(parser: PythonParser, expected: int) -> None: get_parser("test/test.html, test/test.cpp, test/test.py"), "test/test.html, test/test.cpp", ), + # Lock files are committed for reproducible CI, so they are valid. + (get_parser("uv.lock, sol1.py"), ""), ), ) def test_validate_extension(parser: PythonParser, expected: str) -> None: From 2a90ee60d164089c4809676779cf15d8ba8292fa Mon Sep 17 00:00:00 2001 From: priya-sundaram-dev Date: Wed, 2 Sep 2026 11:48:46 +0000 Subject: [PATCH 2/2] Accept Dockerfile filename and pin CI to Python 3.11 - parser: accept extension-less files whose name is in ACCEPTED_FILENAMES (Dockerfile), alongside the existing .lock support, so container/build tooling PRs are not rejected as invalid. Adds tests. - ci: fixit 0.1.4 imports the stdlib distutils removed in Python 3.12; pin setup-python to 3.11 so the test job can collect and run again. --- .github/workflows/main.yml | 4 +++- algorithms_keeper/parser/files_parser.py | 8 +++++++- algorithms_keeper/parser/python_parser.py | 3 +++ tests/test_parser.py | 3 +++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a617a99..2d35aaf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,9 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.x" + # fixit 0.1.4 imports the stdlib ``distutils`` module, which was removed + # in Python 3.12. Pin to 3.11 until the fixit pin is upgraded. + python-version: "3.11" - uses: actions/cache@v3 with: path: | diff --git a/algorithms_keeper/parser/files_parser.py b/algorithms_keeper/parser/files_parser.py index f99da1a..4cb3f8e 100644 --- a/algorithms_keeper/parser/files_parser.py +++ b/algorithms_keeper/parser/files_parser.py @@ -23,6 +23,9 @@ class BaseFilesParser: DOCS_EXTENSIONS: Collection[str] = () ACCEPTED_EXTENSIONS: Collection[str] = () + # Extension-less filenames that are nonetheless valid (e.g. ``Dockerfile``). + ACCEPTED_FILENAMES: Collection[str] = () + def __init__( self, pr_files: Iterable[File], @@ -46,12 +49,15 @@ def validate_extension(self) -> str: `ACCEPTED_EXTENSIONS` constant. NOTE: Extensionless files will be considered valid only if it is present in - the ".github" directory. Eg: ".github/CODEOWNERS" + the ".github" directory (eg: ".github/CODEOWNERS") or if its name is listed in + ``ACCEPTED_FILENAMES`` (eg: "Dockerfile"). """ invalid_filepath = [] for file in self.pr_files: filepath = file.path if not filepath.suffix: + if filepath.name in self.ACCEPTED_FILENAMES: + continue if ".github" not in filepath.parts: if filepath.parent.name: # noqa: SIM114 invalid_filepath.append(file.name) diff --git a/algorithms_keeper/parser/python_parser.py b/algorithms_keeper/parser/python_parser.py index 4e7d485..6b44a23 100644 --- a/algorithms_keeper/parser/python_parser.py +++ b/algorithms_keeper/parser/python_parser.py @@ -80,6 +80,9 @@ class PythonParser(BaseFilesParser): *DOCS_EXTENSIONS, ) + # Extension-less files whose exact name is accepted (container/build tooling). + ACCEPTED_FILENAMES: tuple[str, ...] = ("Dockerfile",) + def __init__( self, pr_files: Iterable[File], diff --git a/tests/test_parser.py b/tests/test_parser.py index 805eee2..923c825 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -58,6 +58,9 @@ def test_contains_testfile(parser: PythonParser, expected: int) -> None: ), # Lock files are committed for reproducible CI, so they are valid. (get_parser("uv.lock, sol1.py"), ""), + # ``Dockerfile`` is an accepted extension-less filename. + (get_parser("Dockerfile, sol1.py"), ""), + (get_parser(".devcontainer/Dockerfile"), ""), ), ) def test_validate_extension(parser: PythonParser, expected: str) -> None: