|
107 | 107 | button.addEventListener('click', async function(e) { |
108 | 108 | e.preventDefault(); |
109 | 109 |
|
110 | | - // Try to find the review request form/button |
111 | | - // GitHub's UI typically has a button or action to request reviews |
112 | | - // We'll try to find and click it programmatically |
| 110 | + // Copilot reviewer user ID |
| 111 | + const COPILOT_USER_ID = '175728472'; |
113 | 112 |
|
114 | | - // Try to find the "Reviewers" section and expand it if needed |
115 | | - const reviewersSection = document.querySelector('.discussion-sidebar-item.js-discussion-sidebar-item'); |
116 | | - if (reviewersSection) { |
117 | | - // Try multiple selector patterns for the request review button |
118 | | - const requestReviewBtn = reviewersSection.querySelector('button[aria-label*="request"]') || |
119 | | - reviewersSection.querySelector('summary[aria-label*="request"]') || |
120 | | - reviewersSection.querySelector('.js-request-reviewers-button'); |
| 113 | + // Get the authenticity token - look for it in the reviewers form specifically |
| 114 | + const reviewersForm = document.querySelector('form[action*="review-requests"]'); |
| 115 | + let csrfToken = reviewersForm?.querySelector('input[name="authenticity_token"]')?.value; |
| 116 | + |
| 117 | + // Fallback to other sources |
| 118 | + if (!csrfToken) { |
| 119 | + csrfToken = document.querySelector('input[name="authenticity_token"]')?.value; |
| 120 | + } |
| 121 | + |
| 122 | + if (!csrfToken) { |
| 123 | + console.error('Could not find CSRF token'); |
| 124 | + return; |
| 125 | + } |
| 126 | + |
| 127 | + // Get other required headers from the page |
| 128 | + const fetchNonce = document.querySelector('meta[name="fetch-nonce"]')?.content || ''; |
| 129 | + const clientVersion = document.querySelector('meta[name="github-client-version"]')?.content || ''; |
| 130 | + |
| 131 | + // Build the review request URL from current page |
| 132 | + const prUrl = window.location.pathname; // e.g., /owner/repo/pull/123 |
| 133 | + const reviewRequestUrl = `${prUrl}/review-requests`; |
| 134 | + |
| 135 | + // Create form data |
| 136 | + const formData = new FormData(); |
| 137 | + formData.append('authenticity_token', csrfToken); |
| 138 | + formData.append('partial_last_updated', Math.floor(Date.now() / 1000).toString()); |
| 139 | + formData.append('dummy-field-just-to-avoid-empty-submit', 'foo'); |
| 140 | + formData.append('reviewer_user_ids[]', COPILOT_USER_ID); |
| 141 | + |
| 142 | + try { |
| 143 | + const headers = { |
| 144 | + 'Accept': 'text/html', |
| 145 | + 'X-Requested-With': 'XMLHttpRequest' |
| 146 | + }; |
121 | 147 |
|
122 | | - if (requestReviewBtn) { |
123 | | - requestReviewBtn.click(); |
124 | | - |
125 | | - // Wait a bit for the modal/dropdown to appear |
126 | | - setTimeout(() => { |
127 | | - // Try to find and click on Copilot in the reviewer list |
128 | | - const copilotReviewerOption = document.querySelector('[data-filterable-for*="copilot"]') || |
129 | | - document.querySelector('[data-targets*="copilot"]') || |
130 | | - document.querySelector('label[for*="copilot"]'); |
131 | | - if (copilotReviewerOption) { |
132 | | - copilotReviewerOption.click(); |
133 | | - } |
134 | | - }, 100); |
135 | | - |
| 148 | + if (fetchNonce) { |
| 149 | + headers['X-Fetch-Nonce'] = fetchNonce; |
| 150 | + } |
| 151 | + if (clientVersion) { |
| 152 | + headers['X-GitHub-Client-Version'] = clientVersion; |
| 153 | + } |
| 154 | + |
| 155 | + const response = await fetch(reviewRequestUrl, { |
| 156 | + method: 'POST', |
| 157 | + body: formData, |
| 158 | + headers: headers |
| 159 | + }); |
| 160 | + |
| 161 | + if (response.ok) { |
136 | 162 | // Visual feedback - success |
137 | 163 | button.innerHTML = ` |
138 | 164 | <svg aria-hidden="true" height="16" viewBox="0 0 16 16" width="16" class="octicon" style="color: #1a7f37;"> |
|
141 | 167 | `; |
142 | 168 | button.style.color = '#1a7f37'; |
143 | 169 |
|
| 170 | + // Reload the page to show updated reviewers |
144 | 171 | setTimeout(() => { |
145 | | - button.innerHTML = playIcon; |
146 | | - button.style.color = ''; |
147 | | - }, 2000); |
| 172 | + window.location.reload(); |
| 173 | + }, 500); |
148 | 174 | } else { |
149 | | - // Fallback: provide feedback that manual action is needed |
150 | | - button.innerHTML = ` |
151 | | - <svg aria-hidden="true" height="16" viewBox="0 0 16 16" width="16" class="octicon" style="color: #db6d28;"> |
152 | | - <path fill="currentColor" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path> |
153 | | - </svg> |
154 | | - `; |
155 | | - button.style.color = '#db6d28'; |
156 | | - button.title = 'Could not find review request button. Please use the Reviewers section manually.'; |
157 | | - setTimeout(() => { |
158 | | - button.innerHTML = playIcon; |
159 | | - button.style.color = ''; |
160 | | - button.title = 'Request Copilot review for draft PR'; |
161 | | - }, 3000); |
| 175 | + throw new Error(`Request failed: ${response.status}`); |
162 | 176 | } |
163 | | - } else { |
164 | | - // Could not find reviewers section |
| 177 | + } catch (err) { |
| 178 | + console.error('Failed to request review:', err); |
165 | 179 | button.innerHTML = ` |
166 | | - <svg aria-hidden="true" height="16" viewBox="0 0 16 16" width="16" class="octicon" style="color: #db6d28;"> |
167 | | - <path fill="currentColor" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path> |
| 180 | + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" width="16" class="octicon" style="color: #f85149;"> |
| 181 | + <path fill="currentColor" d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> |
168 | 182 | </svg> |
169 | 183 | `; |
170 | | - button.style.color = '#db6d28'; |
171 | | - button.title = 'Could not find Reviewers section. Please request review manually.'; |
| 184 | + button.style.color = '#f85149'; |
| 185 | + button.title = 'Failed to request review'; |
172 | 186 | setTimeout(() => { |
173 | 187 | button.innerHTML = playIcon; |
174 | 188 | button.style.color = ''; |
|
0 commit comments