| import sys |
| from urllib.parse import urlparse |
| |
| import requests |
| |
| WEBSITE_REPOS = [ |
| "erpnext_com", |
| "frappe_io", |
| ] |
| |
| DOCUMENTATION_DOMAINS = [ |
| "docs.erpnext.com", |
| "frappeframework.com", |
| ] |
| |
| |
| def is_valid_url(url: str) -> bool: |
| parts = urlparse(url) |
| return all((parts.scheme, parts.netloc, parts.path)) |
| |
| |
| def is_documentation_link(word: str) -> bool: |
| if not word.startswith("http") or not is_valid_url(word): |
| return False |
| |
| parsed_url = urlparse(word) |
| if parsed_url.netloc in DOCUMENTATION_DOMAINS: |
| return True |
| |
| if parsed_url.netloc == "github.com": |
| parts = parsed_url.path.split("/") |
| if len(parts) == 5 and parts[1] == "frappe" and parts[2] in WEBSITE_REPOS: |
| return True |
| |
| return False |
| |
| |
| def contains_documentation_link(body: str) -> bool: |
| return any(is_documentation_link(word) for line in body.splitlines() for word in line.split()) |
| |
| |
| def check_pull_request(number: str) -> "tuple[int, str]": |
| response = requests.get(f"https://api.github.com/repos/frappe/erpnext/pulls/{number}") |
| if not response.ok: |
| return 1, "Pull Request Not Found! ⚠️" |
| |
| payload = response.json() |
| title = (payload.get("title") or "").lower().strip() |
| head_sha = (payload.get("head") or {}).get("sha") |
| body = (payload.get("body") or "").lower() |
| |
| if not title.startswith("feat") or not head_sha or "no-docs" in body or "backport" in body: |
| return 0, "Skipping documentation checks... 🏃" |
| |
| if contains_documentation_link(body): |
| return 0, "Documentation Link Found. You're Awesome! 🎉" |
| |
| return 1, "Documentation Link Not Found! ⚠️" |
| |
| |
| if __name__ == "__main__": |
| exit_code, message = check_pull_request(sys.argv[1]) |
| print(message) |
| sys.exit(exit_code) |