This is an automated email from the ASF dual-hosted git repository.
shahar1 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 04fd3a9b508 Handle multiple PR references in provider changelog
entries (#70358)
04fd3a9b508 is described below
commit 04fd3a9b508072bd9debba518340c41ae351af92
Author: Shahar Epstein <[email protected]>
AuthorDate: Fri Jul 24 16:19:09 2026 +0300
Handle multiple PR references in provider changelog entries (#70358)
Provider release issue generation was missing changelog bullets that
reference more than one PR, which hid substantial changes from contributor
testing checklists. This keeps release wave issue content aligned with
changelog intent by extracting every PR reference from each bullet and from
excluded changelog sections.
---
.../commands/release_management_commands.py | 20 ++++---
.../tests/test_release_management_commands.py | 69 ++++++++++++++++++++++
2 files changed, 80 insertions(+), 9 deletions(-)
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 abe7d924872..c308278d2d3 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 @@ MY_DIR_PATH = os.path.dirname(__file__)
# 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 3e735222c22..6c16bfa1c83 100644
--- a/dev/breeze/tests/test_release_management_commands.py
+++ b/dev/breeze/tests/test_release_management_commands.py
@@ -26,7 +26,9 @@ from airflow_breeze.commands.release_management_commands
import (
_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"),
[