|
1 | 1 | """GitHub app common module.""" |
2 | 2 |
|
3 | 3 | import logging |
| 4 | +from datetime import timedelta as td |
4 | 5 |
|
| 6 | +from django.utils import timezone |
5 | 7 | from github.GithubException import UnknownObjectException |
6 | 8 |
|
7 | 9 | from apps.github.models.issue import Issue |
@@ -46,97 +48,77 @@ def sync_repository(gh_repository, organization=None, user=None): |
46 | 48 | user=user, |
47 | 49 | ) |
48 | 50 |
|
49 | | - # GitHub repository issues. |
50 | | - if ( |
51 | | - not repository.is_archived |
52 | | - and repository.track_issues |
53 | | - and repository.project |
54 | | - and repository.project.track_issues |
55 | | - ): |
| 51 | + if not repository.is_archived: |
| 52 | + # GitHub repository issues. |
| 53 | + project_track_issues = repository.project.track_issues if repository.project else True |
| 54 | + if repository.track_issues and project_track_issues: |
| 55 | + kwargs = { |
| 56 | + "direction": "asc", |
| 57 | + "sort": "created", |
| 58 | + "state": "all", |
| 59 | + } |
| 60 | + if latest_updated_issue := repository.latest_updated_issue: |
| 61 | + # Get only what has been updated after the latest sync. |
| 62 | + kwargs.update({"since": latest_updated_issue.updated_at}) |
| 63 | + |
| 64 | + for gh_issue in gh_repository.get_issues(**kwargs): |
| 65 | + if gh_issue.pull_request: # Skip pull requests. |
| 66 | + continue |
| 67 | + |
| 68 | + author = User.update_data(gh_issue.user) |
| 69 | + issue = Issue.update_data(gh_issue, author=author, repository=repository) |
| 70 | + |
| 71 | + # Assignees. |
| 72 | + issue.assignees.clear() |
| 73 | + for gh_issue_assignee in gh_issue.assignees: |
| 74 | + issue.assignees.add(User.update_data(gh_issue_assignee)) |
| 75 | + |
| 76 | + # Labels. |
| 77 | + issue.labels.clear() |
| 78 | + for gh_issue_label in gh_issue.labels: |
| 79 | + try: |
| 80 | + issue.labels.add(Label.update_data(gh_issue_label)) |
| 81 | + except UnknownObjectException: |
| 82 | + logger.info("Couldn't get GitHub issue label %s", issue.url) |
| 83 | + else: |
| 84 | + logger.info("Skipping issues sync for %s", repository.name) |
| 85 | + |
| 86 | + # GitHub repository pull requests. |
56 | 87 | kwargs = { |
57 | | - "direction": "asc", |
58 | | - "sort": "created", |
| 88 | + "direction": "desc", |
| 89 | + "sort": "updated", |
59 | 90 | "state": "all", |
60 | 91 | } |
61 | | - if latest_updated_issue := repository.latest_updated_issue: |
62 | | - # Get only what has been updated after the latest sync. |
63 | | - kwargs.update({"since": latest_updated_issue.updated_at}) |
64 | | - |
65 | | - for gh_issue in gh_repository.get_issues(**kwargs): |
66 | | - if gh_issue.pull_request: # Skip pull requests. |
67 | | - continue |
68 | 92 |
|
| 93 | + pull_request_cut_off_at = timezone.now() - td(days=30) |
| 94 | + latest_updated_pull_request = repository.latest_updated_pull_request |
| 95 | + for gh_pull_request in gh_repository.get_pulls(**kwargs): |
69 | 96 | author = User.update_data(gh_issue.user) |
70 | | - issue = Issue.update_data(gh_issue, author=author, repository=repository) |
71 | | - |
72 | | - # Assignees. |
73 | | - issue.assignees.clear() |
74 | | - for gh_issue_assignee in gh_issue.assignees: |
75 | | - issue.assignees.add(User.update_data(gh_issue_assignee)) |
76 | | - |
77 | | - # Labels. |
78 | | - issue.labels.clear() |
79 | | - for gh_issue_label in gh_issue.labels: |
80 | | - try: |
81 | | - issue.labels.add(Label.update_data(gh_issue_label)) |
82 | | - except UnknownObjectException: |
83 | | - logger.info("Couldn't get GitHub issue label %s", issue.url) |
84 | | - else: |
85 | | - logger.info("Skipping issues sync for %s", repository.name) |
86 | | - |
87 | | - if not repository.is_archived and repository.project: |
88 | | - # Fetch both open and closed PRs from GitHub |
89 | | - kwargs = { |
90 | | - "direction": "desc", |
91 | | - "sort": "created", |
92 | | - "state": "open", |
93 | | - } |
94 | | - |
95 | | - latest_pull_request = repository.latest_pull_request |
96 | | - if latest_pull_request: |
97 | | - gh_first_pr = PullRequest.objects.order_by("created_at").first().created_at |
98 | | - kwargs["state"] = "all" |
99 | | - |
100 | | - gh_pull_requests = gh_repository.get_pulls(**kwargs) |
101 | | - |
102 | | - for gh_pull_request in gh_pull_requests: |
103 | | - if latest_pull_request and gh_pull_request.state == "closed": |
104 | | - # Skipping closed PR before first sync |
105 | | - if gh_first_pr > gh_pull_request.created_at: |
106 | | - break |
107 | | - # Check if this PR already exists in the database and is open |
108 | | - existing_open_pr = PullRequest.objects.filter( |
109 | | - repository=repository, state="open", number=gh_pull_request.number |
110 | | - ).first() |
111 | | - |
112 | | - if not existing_open_pr: |
113 | | - continue # Skip closed PRs from previous syncs |
114 | | - |
115 | | - # Extract author details |
116 | | - author = ( |
117 | | - User.update_data(gh_pull_request.user) |
118 | | - if gh_pull_request.user and gh_pull_request.user.type != "Bot" |
119 | | - else None |
120 | | - ) |
121 | | - |
122 | | - # Update PR data |
123 | 97 | pull_request = PullRequest.update_data( |
124 | 98 | gh_pull_request, author=author, repository=repository |
125 | 99 | ) |
126 | 100 |
|
127 | | - # Clear and update assignees |
| 101 | + # Assignees. |
128 | 102 | pull_request.assignees.clear() |
129 | 103 | for gh_pull_request_assignee in gh_pull_request.assignees: |
130 | 104 | pull_request.assignees.add(User.update_data(gh_pull_request_assignee)) |
131 | 105 |
|
132 | | - # Clear and update labels |
| 106 | + # Labels. |
133 | 107 | pull_request.labels.clear() |
134 | 108 | for gh_pull_request_label in gh_pull_request.labels: |
135 | 109 | try: |
136 | 110 | pull_request.labels.add(Label.update_data(gh_pull_request_label)) |
137 | 111 | except UnknownObjectException: |
138 | 112 | logger.info("Couldn't get GitHub pull request label %s", pull_request.url) |
139 | 113 |
|
| 114 | + pull_request_cut_off = pull_request.updated_at <= pull_request_cut_off_at |
| 115 | + pull_request_seen = ( |
| 116 | + latest_updated_pull_request |
| 117 | + and pull_request.updated_at <= latest_updated_pull_request.updated_at |
| 118 | + ) |
| 119 | + if pull_request_seen or pull_request_cut_off: |
| 120 | + break |
| 121 | + |
140 | 122 | # GitHub repository releases. |
141 | 123 | releases = [] |
142 | 124 | if not is_owasp_site_repository: |
|
0 commit comments