From 289da4528eceb9d4d096a79d7287438a17b85b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Thu, 27 Nov 2025 22:48:15 +0000 Subject: [PATCH] Implement argparse and output debug file --- .../release-notes/process_release_notes.py | 117 ++++++++++++++---- .../test_process_release_notes.py | 7 +- 2 files changed, 94 insertions(+), 30 deletions(-) diff --git a/.github/scripts/release-notes/process_release_notes.py b/.github/scripts/release-notes/process_release_notes.py index 6115535c82..25121cbe6f 100644 --- a/.github/scripts/release-notes/process_release_notes.py +++ b/.github/scripts/release-notes/process_release_notes.py @@ -2,19 +2,25 @@ import re import sys import subprocess import json +import argparse from typing import List, Tuple def extract_jira_tickets(line: str) -> List[str]: - # Find all Jira tickets in format ABC-123 (with any prefix/suffix) + """Find all Jira tickets in format ABC-123 (with any prefix/suffix)""" return re.findall(r'[A-Z]+-\d+', line) def extract_pr_numbers(line: str) -> List[str]: - # Match PR numbers from GitHub format (#123) + """Match PR numbers from GitHub format (#123)""" return re.findall(r'#(\d+)', line) -def extract_pr_url(line: str) -> List[str]: - """Match PR URL from GitHub format https://github.com/foo/bar/pull/123""" - return re.findall(r'https://github\.com/[\w-]+/[\w.-]+/pull/\d+', line) +def extract_pr_url(line: str) -> str: + """Match PR URL from GitHub format https://github.com/foo/bar/pull/123 + + Returns: + The first PR URL found in the line, or empty string if no URL is found + """ + matches = re.findall(r'https://github\.com/[\w-]+/[\w.-]+/pull/\d+', line) + return matches[0] if matches else "" def fetch_labels(github_pr_url: str) -> List[str]: """Fetch labels from a GitHub PR using the GitHub CLI.""" @@ -87,6 +93,7 @@ def process_file(input_file: str, release_app_label: str) -> Tuple[List[str], Li jira_tickets: List[str] = [] pr_numbers: List[str] = [] processed_lines: List[str] = [] + debug_lines: List[str] = [] #community_highlights: List[str] = [] print("Processing file: ", input_file) @@ -94,13 +101,18 @@ def process_file(input_file: str, release_app_label: str) -> Tuple[List[str], Li with open(input_file, 'r') as f: for line in f: line = line.strip() - should_process = line and not line.startswith('#') + should_process = line and line.startswith('* ') if should_process: pr_url = extract_pr_url(line) - pr_labels = fetch_labels(pr_url) - if should_skip_pr(release_app_label, pr_labels): - continue # skip the PR if it is not labeled with the app label + pr_labels = [] + + # Fetch labels from PR URL if available + if pr_url: + pr_labels = fetch_labels(pr_url) + if should_skip_pr(release_app_label, pr_labels): + debug_lines.append(f"{line} | skipped - labels: {pr_labels}") + continue # skip the PR if it is not labeled with the app label tickets = extract_jira_tickets(line) jira_tickets.extend(tickets) @@ -108,8 +120,13 @@ def process_file(input_file: str, release_app_label: str) -> Tuple[List[str], Li prs = extract_pr_numbers(line) pr_numbers.extend(prs) processed_lines.append(process_line(line)) + debug_lines.append(f"{line} | labels: {pr_labels}") else: processed_lines.append(line) + if line == "": + debug_lines.append("") + else: + debug_lines.append(f"{line} | skipped - processing") # Remove duplicates while preserving order @@ -119,12 +136,14 @@ def process_file(input_file: str, release_app_label: str) -> Tuple[List[str], Li print("Jira tickets:", ",".join(jira_tickets)) print("PR numbers:", ",".join(pr_numbers)) print("Finished processing file: ", input_file) - return jira_tickets, pr_numbers, processed_lines + return jira_tickets, pr_numbers, processed_lines, debug_lines -def save_results(jira_tickets: List[str], pr_numbers: List[str], processed_lines: List[str], +def save_results(jira_tickets: List[str], pr_numbers: List[str], processed_lines: List[str], debug_lines: List[str], jira_file: str = 'jira_tickets.txt', pr_file: str = 'pr_numbers.txt', - processed_file: str = 'processed_notes.txt') -> None: + processed_file: str = 'processed_notes.txt', + debug_file: str = 'processed_notes_debug.txt' + ) -> None: with open(jira_file, 'w') as f: f.write('\n'.join(jira_tickets)) @@ -134,20 +153,64 @@ def save_results(jira_tickets: List[str], pr_numbers: List[str], processed_lines with open(processed_file, 'w') as f: f.write('\n'.join(processed_lines)) + with open(debug_file, 'w') as f: + f.write('\n'.join(debug_lines)) + +def parse_args(): + """Parse command line arguments. + + Returns: + Parsed arguments namespace + """ + parser = argparse.ArgumentParser( + description='Process release notes by extracting Jira tickets and PR numbers, and cleaning up the text.' + ) + parser.add_argument( + 'release_app_label', + help='Filter PRs by app label (e.g., app:password-manager)' + ) + parser.add_argument( + 'input_file', + default='release_notes.txt', + help='Input file containing release notes (default: release_notes.txt)' + ) + parser.add_argument( + '--processed-filepath', + default='processed_notes.txt', + help='Output file for processed notes (default: processed_notes.txt)' + ) + parser.add_argument( + '--jira-filepath', + default='jira_tickets.txt', + help='Output file for Jira tickets (default: jira_tickets.txt)' + ) + parser.add_argument( + '--pr-filepath', + default='pr_numbers.txt', + help='Output file for PR numbers (default: pr_numbers.txt)' + ) + + parser.add_argument( + '--debug-filepath', + default='processed_notes_debug.txt', + help='Output file for debug notes (default: processed_notes_debug.txt)' + ) + return parser.parse_args() + if __name__ == '__main__': - input_file = 'release_notes.txt' - jira_file = 'jira_tickets.txt' - pr_file = 'pr_numbers.txt' - processed_file = 'processed_notes.txt' + args = parse_args() - if len(sys.argv) >= 2: - input_file = sys.argv[1] - if len(sys.argv) >= 3: - jira_file = sys.argv[2] - if len(sys.argv) >= 4: - pr_file = sys.argv[3] - if len(sys.argv) >= 5: - processed_file = sys.argv[4] - - jira_tickets, pr_numbers, processed_lines = process_file(input_file) - save_results(jira_tickets, pr_numbers, processed_lines, jira_file, pr_file, processed_file) + jira_tickets, pr_numbers, processed_lines, debug_lines = process_file( + args.input_file, + args.release_app_label + ) + save_results( + jira_tickets, + pr_numbers, + processed_lines, + debug_lines, + args.jira_filepath, + args.pr_filepath, + args.processed_filepath, + args.debug_filepath + ) diff --git a/.github/scripts/release-notes/test_process_release_notes.py b/.github/scripts/release-notes/test_process_release_notes.py index 03ae1d3dcb..56cb55c142 100644 --- a/.github/scripts/release-notes/test_process_release_notes.py +++ b/.github/scripts/release-notes/test_process_release_notes.py @@ -54,9 +54,10 @@ class TestProcessReleaseNotes(unittest.TestCase): def test_extract_pr_url(self): test_cases = [ - ("* Update SDK to 1.0.0-3436-2a00b727 by @bw-ghapp[bot] in https://github.com/bitwarden/android/pull/6042", ["https://github.com/bitwarden/android/pull/6042"]), - ("* Bump JUnit from 6.0.0 to 6.0.1 by SaintPatrick in https://github.com/bitwarden/android/pull/6149", ["https://github.com/bitwarden/android/pull/6149"]), - ("* [PM-26986] Hide select other account button if user has no other account by @aj-rosado in https://github.com/bitwarden/android/pull/6041", ["https://github.com/bitwarden/android/pull/6041"]), + ("* Update SDK to 1.0.0-3436-2a00b727 by @bw-ghapp[bot] in https://github.com/bitwarden/android/pull/6042", "https://github.com/bitwarden/android/pull/6042"), + ("* Bump JUnit from 6.0.0 to 6.0.1 by SaintPatrick in https://github.com/bitwarden/android/pull/6149", "https://github.com/bitwarden/android/pull/6149"), + ("* [PM-26986] Hide select other account button if user has no other account by @aj-rosado in https://github.com/bitwarden/android/pull/6041", "https://github.com/bitwarden/android/pull/6041"), + ("* No PR URL here", ""), ] for input_text, expected in test_cases: with self.subTest(input_text=input_text):