diff --git a/prprocessor/__main__.py b/prprocessor/__main__.py index fad7ccf..921ed8b 100644 --- a/prprocessor/__main__.py +++ b/prprocessor/__main__.py @@ -76,6 +76,7 @@ class Config: refs: set = field(default_factory=set) version_prefix: Optional[str] = None apply_labels: bool = True + link_to_redmine: bool = False # This should be handled cleaner @@ -83,7 +84,8 @@ class Config: CONFIG = { repo: Config(project=config.get('redmine'), required=config.get('redmine_required', False), refs=set(config.get('refs', [])), - version_prefix=config.get('redmine_version_prefix')) + version_prefix=config.get('redmine_version_prefix'), + link_to_redmine=config.get('link_to_redmine', False)) for repo, config in yaml.safe_load(config_fp).items() } @@ -144,6 +146,15 @@ async def update_pr_labels(pull_request: Mapping, labels_to_add: Iterable[Label] await asyncio.gather(*tasks) +async def post_pr_comment(pull_request: Mapping, comment: str) -> None: + github_api = RUNTIME_CONTEXT.app_installation_client + + url = pull_request['comments_url'] + data = {'body': comment} + + await github_api.post(url, data=data) + + async def get_commits_from_pull_request(pull_request: Mapping) -> AsyncGenerator[Commit, None]: github_api = RUNTIME_CONTEXT.app_installation_client items = await github_api.getitem(pull_request['commits_url']) @@ -219,7 +230,7 @@ async def get_issues_from_pr(pull_request: Mapping) -> tuple[IssueValidation, Co return verify_issues(config, issue_ids), invalid_commits -async def run_pull_request_check(pull_request: Mapping, check_run=None) -> bool: +async def run_pull_request_check(pull_request: Mapping, check_run=None) -> tuple[bool, IssueValidation, Collection]: github_api = RUNTIME_CONTEXT.app_installation_client check_run = await set_check_in_progress(pull_request, check_run) @@ -293,7 +304,7 @@ async def run_pull_request_check(pull_request: Mapping, check_run=None) -> bool: }, ) - return conclusion == 'success' + return (conclusion == 'success', issue_results, invalid_commits) async def update_redmine_on_issues(pull_request: Mapping, issues: Iterable[Issue]) -> None: @@ -337,13 +348,19 @@ async def update_redmine_on_issues(pull_request: Mapping, issues: Iterable[Issue @process_event_actions('pull_request', {'opened', 'ready_for_review', 'reopened', 'synchronize'}) @process_webhook_payload async def on_pr_modified(*, action: str, pull_request: Mapping, **_kw) -> None: - commits_valid_style = await run_pull_request_check(pull_request) + commits_valid_style, issue_results, _ = await run_pull_request_check(pull_request) try: config = get_config(pull_request['base']['repo']['full_name']) except UnconfiguredRepository: return + if config.link_to_redmine: + if action == 'opened' and issue_results.valid_issues and not pr_is_cherry_pick(pull_request): + issues = '\n* '.join(format_redmine_issues(issue_results.valid_issues)) + comment = f'Issues: \n* {issues}' + await post_pr_comment(pull_request, comment) + if not config.apply_labels: return diff --git a/prprocessor/config/repos.yaml b/prprocessor/config/repos.yaml index aa65bf8..0c941f1 100644 --- a/prprocessor/config/repos.yaml +++ b/prprocessor/config/repos.yaml @@ -4,6 +4,7 @@ # redmine_required: enforce commit message format to include Redmine ticket number (default: false) # refs: optional list of Redmine projects that commits here can "refs" (default: []) # branches: list of primary development branches, else uses repo default +# link_to_redmine: Add comment with Issue number if present (default: false) --- ekohl/gh-test-env: redmine: pr-processor-test @@ -13,6 +14,7 @@ ekohl/gh-test-env: theforeman/foreman: redmine: foreman redmine_required: true + link_to_redmine: true theforeman/foreman_ansible: redmine: ansible redmine_required: true @@ -25,9 +27,11 @@ theforeman/foreman_bootdisk: theforeman/foreman_discovery: redmine: discovery redmine_version_prefix: "Discovery Plugin " + link_to_redmine: true theforeman/foreman-discovery-image: redmine: discovery redmine_version_prefix: "Discovery Image " + link_to_redmine: true theforeman/foreman-documentation: {} theforeman/foreman_expire_hosts: {} theforeman/foreman_host_extra_validator: {} @@ -38,6 +42,7 @@ theforeman/foreman_kubevirt: theforeman/foreman_maintain: redmine: foreman-maintain redmine_required: true + link_to_redmine: true theforeman/foreman_monitoring: {} theforeman/foreman_omaha: {} theforeman/foreman_openscap: @@ -87,6 +92,7 @@ theforeman/foreman_virt_who_configure: redmine_version_prefix: "foreman-virt-who-configure-" theforeman/foreman_webhooks: redmine: webhooks + link_to_redmine: true theforeman/hammer-cli: redmine: hammer-cli redmine_version_prefix: "hammer-cli-" @@ -103,6 +109,7 @@ theforeman/hammer_cli_foreman_bootdisk: theforeman/hammer-cli-foreman-discovery: redmine: discovery redmine_version_prefix: "Hammer Plugin " + link_to_redmine: true theforeman/hammer-cli-foreman-kubevirt: redmine: kubevirt theforeman/hammer_cli_foreman_openscap: @@ -165,8 +172,10 @@ theforeman/smart_proxy_dhcp_infoblox: redmine: infoblox theforeman/smart_proxy_discovery: redmine: discovery + link_to_redmine: true theforeman/smart_proxy_discovery_image: redmine: discovery + link_to_redmine: true theforeman/smart_proxy_dns_infoblox: redmine: infoblox theforeman/smart_proxy_dynflow: @@ -194,17 +203,21 @@ Katello/hammer-cli-katello: redmine: katello redmine_required: true redmine_version_prefix: "Hammer CLI Katello " + link_to_redmine: true Katello/katello: redmine: katello redmine_required: true redmine_version_prefix: "Katello " + link_to_redmine: true Katello/katello-host-tools: redmine: katello redmine_required: true redmine_version_prefix: "Katello Host Tools " + link_to_redmine: true theforeman/katello-selinux: redmine: katello redmine_version_prefix: "Katello " Katello/smart_proxy_container_gateway: redmine: katello redmine_required: true + link_to_redmine: true