Update create-release.py to find github issues without the full url (#13150)

Blue committed Jun 20, 2025 at 14:17 UTC 902848b76bcdcf55438ba99e584d852f48c03859
1 file changed +28 -2
tools/devops/create-release.py
+28 -2
@@ -6,6 +6,7 @@ import sys
6 import re
7 import os
8 import backoff
9 +import functools
10 from git import Repo
11 from urllib.parse import urlparse
12
@@ -45,6 +46,12 @@ def main(version: str, previous: str, max_message_lines: int, publish: bool, ass
46 if pr_description is not None:
47 issues = issues.union(find_github_issues(pr_description))
48
49 + if github_token is not None:
50 + issues = filter_github_issues(issues, github_token)
51 +
52 + if len(issues) > 1:
53 + print(f'WARNING: found more than 1 github issues in message: {message}. Issues: {issues}', file=sys.stderr)
54 +
55 message = e.message[:-1] if e.message.endswith('\n') else e.message
56
57 # Shrink the message if it's too long
@@ -103,17 +110,36 @@ def get_previous_release(version: tuple) -> str:
110 return '.'.join(str(e) for e in max(previous_versions))
111
112 def find_github_issues(message: str):
113 + # Look for urls first
114 urls = [urlparse(e) for e in re.findall(r"https?://[^\s^\)]+", message)]
115
116 issue_urls = [e for e in urls if e.hostname == 'github.com' and e.path.lower().startswith('/microsoft/wsl/issues/')]
117
118 issues = set(['#' + e.path.split('/')[-1] for e in issue_urls])
119
112 - if len(issues) > 1:
113 - print(f'WARNING: found more than 1 github issues in message: {message}. Issues: {issues}', file=sys.stderr)
120 + # Then add issue numbers
121 + for e in re.findall(r"#\d+", message):
122 + issues.add(e)
123
124 return issues
125
126 +def filter_github_issues(issues: list, token: str) -> list:
127 +
128 + @functools.cache
129 + def is_pr(number: str):
130 + headers = {
131 + 'Accept': 'application/vnd.github+json',
132 + 'Authorization': 'Bearer ' + token,
133 + 'X-GitHub-Api-Version': '2022-11-28'
134 + }
135 +
136 + response = requests.get(f'https://api.github.com/repos/microsoft/wsl/issues/{number}', timeout=30, headers=headers)
137 + response.raise_for_status()
138 +
139 + return response.json().get('pull_request') is not None
140 +
141 + return [e for e in issues if not is_pr(e.replace('#', ''))]
142 +
143
144 def get_change_list(version: str, previous: str, fetch: bool) -> list:
145 repo = Repo('.')