|
2 | 2 | """ |
3 | 3 | import logging |
4 | 4 | import multiprocessing |
| 5 | +import os |
5 | 6 | import re |
6 | | -import six |
7 | | -import requests |
8 | | - |
9 | 7 | from abc import ABCMeta, abstractmethod |
| 8 | +from urllib.parse import urlencode |
| 9 | + |
| 10 | +import requests |
| 11 | +import six |
10 | 12 |
|
11 | 13 | logger = logging.getLogger(__name__) |
12 | 14 |
|
@@ -38,28 +40,58 @@ def __init__(self, url, proxies): |
38 | 40 | self.proxies = proxies |
39 | 41 |
|
40 | 42 | def is_active(self): |
41 | | - """Check if the issue is still active. |
| 43 | + """Check if the GitHub issue is still active. |
42 | 44 |
|
43 | | - If unable to get issue state, always consider it as active. |
| 45 | + Attempt to fetch issue details via proxy if configured. If proxy fails, retry with direct GitHub API URL. |
| 46 | + If unable to retrieve issue state, assume the issue is active (safe default). |
44 | 47 |
|
45 | 48 | Returns: |
46 | 49 | bool: False if the issue is closed else True. |
47 | 50 | """ |
48 | | - try: |
49 | | - response = requests.get(self.api_url, proxies=self.proxies, timeout=10) |
| 51 | + |
| 52 | + def fetch_issue(url): |
| 53 | + response = requests.get(url, proxies=self.proxies, timeout=10) |
50 | 54 | response.raise_for_status() |
51 | | - issue_data = response.json() |
52 | | - if issue_data.get('state', '') == 'closed': |
53 | | - logger.debug('Issue {} is closed'.format(self.url)) |
54 | | - labels = issue_data.get('labels', []) |
55 | | - if any(['name' in label and 'duplicate' in label['name'].lower() for label in labels]): |
56 | | - logger.warning('GitHub issue: {} looks like duplicate and was closed. Please re-check and ignore' |
57 | | - 'the test on the parent issue'.format(self.url)) |
58 | | - return False |
59 | | - except Exception as e: |
60 | | - logger.error('Get details for {} failed with: {}'.format(self.url, repr(e))) |
61 | | - |
62 | | - logger.debug('Issue {} is active. Or getting issue state failed, consider it as active anyway'.format(self.url)) |
| 55 | + return response.json() |
| 56 | + |
| 57 | + direct_url = self.api_url |
| 58 | + proxy_url = os.getenv("SONIC_AUTOMATION_PROXY_GITHUB_ISSUES_URL") |
| 59 | + |
| 60 | + issue_data = None |
| 61 | + |
| 62 | + # Attempt to access via proxy first (if configured) |
| 63 | + # The proxy is used to work around GitHub's unauthenticated rate limit (60 requests/hour per IP). |
| 64 | + # For details, refer to GitHub API rate limits documentation: |
| 65 | + # https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#primary-rate-limit-for-unauthenticated-users |
| 66 | + if proxy_url: |
| 67 | + try: |
| 68 | + proxy_endpoint = f"{proxy_url.rstrip('/')}/?{urlencode({'github_issue_url': direct_url})}" |
| 69 | + logger.info("Attempting to access GitHub API via proxy.") |
| 70 | + issue_data = fetch_issue(proxy_endpoint) |
| 71 | + except Exception as proxy_err: |
| 72 | + logger.warning(f"Proxy access failed: {proxy_err}. Falling back to direct API.") |
| 73 | + |
| 74 | + # Fallback to direct URL if proxy is not set or fails |
| 75 | + if issue_data is None: |
| 76 | + try: |
| 77 | + logger.info(f"Accessing GitHub API directly: {direct_url}") |
| 78 | + issue_data = fetch_issue(direct_url) |
| 79 | + except Exception as direct_err: |
| 80 | + logger.error(f"Access GitHub API directly failed for {direct_url}: {direct_err}") |
| 81 | + logger.debug(f"Issue {direct_url} is considered active due to API access failure.") |
| 82 | + return True |
| 83 | + |
| 84 | + # Check issue state |
| 85 | + if issue_data.get('state') == 'closed': |
| 86 | + logger.debug(f"Issue {direct_url} is closed.") |
| 87 | + labels = issue_data.get('labels', []) |
| 88 | + if any('name' in label and 'duplicate' in label['name'].lower() for label in labels): |
| 89 | + logger.warning( |
| 90 | + f"GitHub issue {direct_url} appears to be a duplicate and was closed. " |
| 91 | + f"Consider ignoring related test failures.") |
| 92 | + return False |
| 93 | + |
| 94 | + logger.debug(f"Issue {direct_url} is active.") |
63 | 95 | return True |
64 | 96 |
|
65 | 97 |
|
|
0 commit comments