diff --git a/script/helpers.py b/script/helpers.py index 11549808ff..8132ee49e5 100644 --- a/script/helpers.py +++ b/script/helpers.py @@ -558,8 +558,9 @@ def _get_changed_files_github_actions() -> list[str] | None: try: return _get_changed_files_from_command(cmd) except Exception as e: - # If it fails due to the 300 file limit, use the API method - if "maximum" in str(e) and "files" in str(e): + # If it fails due to a diff limit (300 files or 20000 lines), + # use the API method which only returns filenames + if "diff exceeded the maximum" in str(e): cmd = [ "gh", "api", diff --git a/tests/script/test_helpers.py b/tests/script/test_helpers.py index a07e56cea5..2c3ae95655 100644 --- a/tests/script/test_helpers.py +++ b/tests/script/test_helpers.py @@ -244,6 +244,44 @@ def test_get_changed_files_github_actions_pull_request_large_pr( assert result == expected_files +def test_get_changed_files_github_actions_pull_request_large_diff( + monkeypatch: MonkeyPatch, +) -> None: + """Test _get_changed_files_github_actions fallback for PRs with >20000 diff lines.""" + monkeypatch.setenv("GITHUB_EVENT_NAME", "pull_request") + + expected_files = ["file1.py", "file2.cpp"] + + with ( + patch("helpers._get_pr_number_from_github_env", return_value="17909"), + patch("helpers._get_changed_files_from_command") as mock_get, + ): + # First call fails with too many diff lines error, second succeeds with API method + mock_get.side_effect = [ + Exception( + "could not find pull request diff: HTTP 406: Sorry, " + "the diff exceeded the maximum number of lines (20000)" + ), + expected_files, + ] + + result = _get_changed_files_github_actions() + + assert mock_get.call_count == 2 + mock_get.assert_any_call(["gh", "pr", "diff", "17909", "--name-only"]) + mock_get.assert_any_call( + [ + "gh", + "api", + "repos/esphome/esphome/pulls/17909/files", + "--paginate", + "--jq", + ".[].filename", + ] + ) + assert result == expected_files + + def test_get_changed_files_github_actions_pull_request_other_error( monkeypatch: MonkeyPatch, ) -> None: