diff --git a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py index abe7d9248725c..c308278d2d3b2 100644 --- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py +++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py @@ -255,6 +255,7 @@ # always correct regardless of how breeze is launched. SOURCE_DIR_PATH = str(AIRFLOW_ROOT_PATH) PR_PATTERN = re.compile(r".*\(#([0-9]+)\)") +PR_REFERENCE_PATTERN = re.compile(r"#([0-9]+)") ISSUE_MATCH_IN_BODY = re.compile(r" #([0-9]+)[^0-9]") # Release-management commits (provider documentation / release preparation) are pure # release-process noise: they are not user-facing changes and existing providers already @@ -2611,8 +2612,8 @@ def get_suffix_from_package_in_dist(dist_files: list[str], package: str) -> str def get_prs_for_package(provider_id: str, current_release_version: str | None = None) -> list[int]: - pr_matcher = re.compile(r".*\(#([0-9]*)\)``$") - prs = [] + prs: list[int] = [] + seen_prs: set[int] = set() if current_release_version is None: provider_yaml_dict = get_provider_distributions_metadata().get(provider_id) if not provider_yaml_dict: @@ -2636,9 +2637,12 @@ def get_prs_for_package(provider_id: str, current_release_version: str | None = if line.startswith(".. Below changes are excluded from the changelog"): # The reminder of PRs is not important skipping it break - match_result = pr_matcher.match(line.strip()) - if match_result: - prs.append(int(match_result.group(1))) + if line.lstrip().startswith("*"): + for pr_match in PR_REFERENCE_PATTERN.findall(line): + pr_number = int(pr_match) + if pr_number not in seen_prs: + seen_prs.add(pr_number) + prs.append(pr_number) return prs @@ -2732,7 +2736,6 @@ def get_commented_out_prs_from_provider_changelogs() -> list[int]: Returns list of PRs that are commented out in the changelog. :return: list of PR numbers that appear only in comments in changelog.rst files in "providers" dir """ - pr_matcher = re.compile(r".*\(#([0-9]+)\).*") commented_prs = set() # Get all provider distributions @@ -2770,9 +2773,8 @@ def get_commented_out_prs_from_provider_changelogs() -> list[int]: # Extract PRs from excluded sections if in_excluded_section and line.strip().startswith("*"): - match_result = pr_matcher.search(line) - if match_result: - commented_prs.add(int(match_result.group(1))) + for pr_match in PR_REFERENCE_PATTERN.findall(line): + commented_prs.add(int(pr_match)) return sorted(commented_prs) diff --git a/dev/breeze/tests/test_release_management_commands.py b/dev/breeze/tests/test_release_management_commands.py index 3e735222c22e3..6c16bfa1c83c5 100644 --- a/dev/breeze/tests/test_release_management_commands.py +++ b/dev/breeze/tests/test_release_management_commands.py @@ -26,7 +26,9 @@ _ensure_default_python_for_reproducible_client, _is_initial_provider_release, _should_include_provider_in_issue, + get_commented_out_prs_from_provider_changelogs, get_package_version_possibly_from_stable_txt, + get_prs_for_package, get_prs_from_git_log_for_new_provider, get_suffix_from_package_in_dist, is_package_in_dist, @@ -101,6 +103,73 @@ def test_get_prs_from_git_log_for_new_provider(monkeypatch): assert prs == [68400, 68345, 67999, 67080] +def test_get_prs_for_package_extracts_multiple_prs_per_line(tmp_path: Path, monkeypatch): + changelog = tmp_path / "changelog.rst" + changelog.write_text( + "\n".join( + [ + "1.15.0", + "......", + "", + "Features", + "~~~~~~~~", + "", + "* ``Add Kafka Event Producer publishing DagRun and TaskInstance state-change events (#68082, #70014)``", + "* ``Add Amazon MSK IAM (OAUTHBEARER) support to Apache Kafka provider (#69427)``", + "", + ".. Below changes are excluded from the changelog. Move them to", + " appropriate section above if needed. Do not delete the lines(!):", + " * ``Release prep commit (#99999)``", + "", + "1.14.0", + "......", + ] + ) + ) + monkeypatch.setattr( + "airflow_breeze.commands.release_management_commands.get_provider_details", + lambda provider_id: SimpleNamespace(changelog_path=changelog), + ) + + prs = get_prs_for_package("apache.kafka", current_release_version="1.15.0") + + assert prs == [68082, 70014, 69427] + + +def test_get_commented_out_prs_extracts_multiple_prs_per_line(tmp_path: Path, monkeypatch): + changelog = tmp_path / "changelog.rst" + changelog.write_text( + "\n".join( + [ + "1.15.0", + "......", + "", + "Features", + "~~~~~~~~", + "", + "* ``Visible change (#11111)``", + "", + ".. Below changes are excluded from the changelog. Move them to", + " appropriate section above if needed. Do not delete the lines(!):", + " * ``Internal change (#22222, #33333)``", + "", + ] + ) + ) + monkeypatch.setattr( + "airflow_breeze.commands.release_management_commands.get_provider_distributions_metadata", + lambda: {"apache.kafka": {}}, + ) + monkeypatch.setattr( + "airflow_breeze.commands.release_management_commands.get_provider_details", + lambda provider_id: SimpleNamespace(changelog_path=changelog), + ) + + prs = get_commented_out_prs_from_provider_changelogs() + + assert prs == [22222, 33333] + + @pytest.mark.parametrize( ("subject", "is_release_commit"), [