Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 582218e

Browse files
authored
Merge pull request #7 from veshu/develop
fix for #topcoder-archive/topcoder-platform-topcoder-x-ui/issues/36
2 parents b8f97cc + 05f0508 commit 582218e

File tree

2 files changed

+75
-60
lines changed

2 files changed

+75
-60
lines changed

services/GithubService.js

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,19 @@ const copilotUserSchema = Joi.object().keys({
2222
topcoderUsername: Joi.string()
2323
}).required();
2424

25+
/**
26+
* parse the repository name and repoFullName owner
27+
* @param {String} fullName the full repository name
28+
* @returns {Object} the parsed data
29+
* @private
30+
*/
31+
function _parseRepoUrl(fullName) {
32+
const results = fullName.split('/');
33+
const repo = results[results.length - 1];
34+
const owner = _(results).slice(0, results.length - 1).join('/');
35+
return {owner, repo};
36+
}
37+
2538
/**
2639
* authenticate the github using access token
2740
* @param {String} accessToken the access token of copilot
@@ -79,14 +92,14 @@ async function _getUsernameById(github, id) {
7992
/**
8093
* updates the title of github issue
8194
* @param {Object} copilot the copilot
82-
* @param {string} repo the repository
95+
* @param {string} repoFullName the repository
8396
* @param {Number} number the issue number
8497
* @param {string} title new title
8598
*/
86-
async function updateIssue(copilot, repo, number, title) {
87-
Joi.attempt({copilot, repo, number, title}, updateIssue.schema);
99+
async function updateIssue(copilot, repoFullName, number, title) {
100+
Joi.attempt({copilot, repoFullName, number, title}, updateIssue.schema);
88101
const github = await _authenticate(copilot.accessToken);
89-
const owner = await _getUsernameById(github, copilot.userProviderId);
102+
const {owner, repo} = _parseRepoUrl(repoFullName);
90103
try {
91104
await github.issues.edit({owner, repo, number, title});
92105
} catch (err) {
@@ -97,22 +110,22 @@ async function updateIssue(copilot, repo, number, title) {
97110

98111
updateIssue.schema = {
99112
copilot: copilotUserSchema,
100-
repo: Joi.string().required(),
113+
repoFullName: Joi.string().required(),
101114
number: Joi.number().required(),
102115
title: Joi.string().required()
103116
};
104117

105118
/**
106119
* Assigns the issue to user
107120
* @param {Object} copilot the copilot
108-
* @param {string} repo the repository
121+
* @param {string} repoFullName the repository
109122
* @param {Number} number the issue number
110123
* @param {string} user the user login of assignee
111124
*/
112-
async function assignUser(copilot, repo, number, user) {
113-
Joi.attempt({copilot, repo, number, user}, assignUser.schema);
125+
async function assignUser(copilot, repoFullName, number, user) {
126+
Joi.attempt({copilot, repoFullName, number, user}, assignUser.schema);
114127
const github = await _authenticate(copilot.accessToken);
115-
const owner = await _getUsernameById(github, copilot.userProviderId);
128+
const {owner, repo} = _parseRepoUrl(repoFullName);
116129
try {
117130
const issue = await github.issues.get({owner, repo, number});
118131

@@ -129,23 +142,23 @@ async function assignUser(copilot, repo, number, user) {
129142

130143
assignUser.schema = {
131144
copilot: copilotUserSchema,
132-
repo: Joi.string().required(),
145+
repoFullName: Joi.string().required(),
133146
number: Joi.number().required(),
134147
user: Joi.string().required()
135148
};
136149

137150
/**
138151
* Removes an assignee from the issue
139152
* @param {Object} copilot the copilot
140-
* @param {string} repo the repository
153+
* @param {string} repoFullName the repository
141154
* @param {Number} number the issue number
142155
* @param {string} user the user login of assignee
143156
*/
144-
async function removeAssign(copilot, repo, number, user) {
145-
Joi.attempt({copilot, repo, number, user}, removeAssign.schema);
157+
async function removeAssign(copilot, repoFullName, number, user) {
158+
Joi.attempt({copilot, repoFullName, number, user}, removeAssign.schema);
146159

147160
const github = await _authenticate(copilot.accessToken);
148-
const owner = await _getUsernameById(github, copilot.userProviderId);
161+
const {owner, repo} = _parseRepoUrl(repoFullName);
149162
await _removeAssignees(github, owner, repo, number, [user]);
150163
logger.debug(`Github user ${user} is unassigned from issue number ${number}`);
151164
}
@@ -155,15 +168,15 @@ removeAssign.schema = assignUser.schema;
155168
/**
156169
* creates the comments on github issue
157170
* @param {Object} copilot the copilot
158-
* @param {string} repo the repository
171+
* @param {string} repoFullName the repository
159172
* @param {Number} number the issue number
160173
* @param {string} body the comment body text
161174
*/
162-
async function createComment(copilot, repo, number, body) {
163-
Joi.attempt({copilot, repo, number, body}, createComment.schema);
175+
async function createComment(copilot, repoFullName, number, body) {
176+
Joi.attempt({copilot, repoFullName, number, body}, createComment.schema);
164177

165178
const github = await _authenticate(copilot.accessToken);
166-
const owner = await _getUsernameById(github, copilot.userProviderId);
179+
const {owner, repo} = _parseRepoUrl(repoFullName);
167180
try {
168181
await github.issues.createComment({owner, repo, number, body});
169182
} catch (err) {
@@ -174,7 +187,7 @@ async function createComment(copilot, repo, number, body) {
174187

175188
createComment.schema = {
176189
copilot: copilotUserSchema,
177-
repo: Joi.string().required(),
190+
repoFullName: Joi.string().required(),
178191
number: Joi.number().required(),
179192
body: Joi.string().required()
180193
};
@@ -218,14 +231,14 @@ getUserIdByLogin.schema = {
218231
/**
219232
* updates the github issue as paid and fix accepted
220233
* @param {Object} copilot the copilot
221-
* @param {string} repo the repository
234+
* @param {string} repoFullName the repository
222235
* @param {Number} number the issue number
223236
* @param {Number} challengeId the challenge id
224237
*/
225-
async function markIssueAsPaid(copilot, repo, number, challengeId) {
226-
Joi.attempt({copilot, repo, number, challengeId}, markIssueAsPaid.schema);
238+
async function markIssueAsPaid(copilot, repoFullName, number, challengeId) {
239+
Joi.attempt({copilot, repoFullName, number, challengeId}, markIssueAsPaid.schema);
227240
const github = await _authenticate(copilot.accessToken);
228-
const owner = await _getUsernameById(github, copilot.userProviderId);
241+
const {owner, repo} = _parseRepoUrl(repoFullName);
229242
const labels = [config.PAID_ISSUE_LABEL, config.FIX_ACCEPTED_ISSUE_LABEL];
230243
try {
231244
await github.issues.edit({owner, repo, number, labels});
@@ -239,22 +252,22 @@ async function markIssueAsPaid(copilot, repo, number, challengeId) {
239252

240253
markIssueAsPaid.schema = {
241254
copilot: copilotUserSchema,
242-
repo: Joi.string().required(),
255+
repoFullName: Joi.string().required(),
243256
number: Joi.number().required(),
244257
challengeId: Joi.number().positive().required()
245258
};
246259

247260
/**
248261
* change the state of github issue
249262
* @param {Object} copilot the copilot
250-
* @param {string} repo the repository
263+
* @param {string} repoFullName the repository
251264
* @param {Number} number the issue number
252265
* @param {string} state new state
253266
*/
254-
async function changeState(copilot, repo, number, state) {
255-
Joi.attempt({copilot, repo, number, state}, changeState.schema);
267+
async function changeState(copilot, repoFullName, number, state) {
268+
Joi.attempt({copilot, repoFullName, number, state}, changeState.schema);
256269
const github = await _authenticate(copilot.accessToken);
257-
const owner = await _getUsernameById(github, copilot.userProviderId);
270+
const {owner, repo} = _parseRepoUrl(repoFullName);
258271
try {
259272
await github.issues.edit({owner, repo, number, state});
260273
} catch (err) {
@@ -265,22 +278,22 @@ async function changeState(copilot, repo, number, state) {
265278

266279
changeState.schema = {
267280
copilot: copilotUserSchema,
268-
repo: Joi.string().required(),
281+
repoFullName: Joi.string().required(),
269282
number: Joi.number().required(),
270283
state: Joi.string().required()
271284
};
272285

273286
/**
274287
* updates the github issue with new labels
275288
* @param {Object} copilot the copilot
276-
* @param {string} repo the repository
289+
* @param {string} repoFullName the repository
277290
* @param {Number} number the issue number
278291
* @param {Number} labels the challenge id
279292
*/
280-
async function addLabels(copilot, repo, number, labels) {
281-
Joi.attempt({copilot, repo, number, labels}, addLabels.schema);
293+
async function addLabels(copilot, repoFullName, number, labels) {
294+
Joi.attempt({copilot, repoFullName, number, labels}, addLabels.schema);
282295
const github = await _authenticate(copilot.accessToken);
283-
const owner = await _getUsernameById(github, copilot.userProviderId);
296+
const {owner, repo} = _parseRepoUrl(repoFullName);
284297
try {
285298
await github.issues.edit({owner, repo, number, labels});
286299
} catch (err) {
@@ -291,7 +304,7 @@ async function addLabels(copilot, repo, number, labels) {
291304

292305
addLabels.schema = {
293306
copilot: copilotUserSchema,
294-
repo: Joi.string().required(),
307+
repoFullName: Joi.string().required(),
295308
number: Joi.number().required(),
296309
labels: Joi.array().items(Joi.string()).required()
297310
};

services/IssueService.js

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ async function handleEventGracefully(event, issue, err) {
6565
// reschedule event
6666
if (event.retryCount <= config.RETRY_COUNT) {
6767
logger.debug('Scheduling event for next retry');
68-
const newEvent = { ...event };
68+
const newEvent = {...event};
6969
newEvent.retryCount += 1;
7070
delete newEvent.copilot;
7171
setTimeout(async () => {
@@ -74,27 +74,29 @@ async function handleEventGracefully(event, issue, err) {
7474
logger.debug('The event is scheduled for retry');
7575
}, config.RETRY_INTERVAL);
7676
}
77-
let comment = `[${err.statusCode}]: ${err.message}`;
78-
if (event.event === 'issue.closed' && event.paymentSuccessful === false) {
79-
comment = `Payment failed: ${comment}`;
80-
}
77+
8178
if (event.retryCount === config.RETRY_COUNT) {
79+
let comment = `[${err.statusCode}]: ${err.message}`;
80+
if (event.event === 'issue.closed' && event.paymentSuccessful === false) {
81+
comment = `Payment failed: ${comment}`;
82+
}
8283
// notify error in git host
8384
if (event.provider === 'github') {
84-
await gitHubService.createComment(event.copilot, event.data.repository.name, issue.number, comment);
85+
await gitHubService.createComment(event.copilot, event.data.repository.full_name, issue.number, comment);
8586
} else {
8687
await gitlabService.createComment(event.copilot, event.data.repository.id, issue.number, comment);
8788
}
88-
}
89-
if (event.event === 'issue.closed') {
90-
// reopen
91-
await reOpenIssue(event, issue);
92-
// ensure label is ready for review
93-
const readyForReviewLabels = [config.READY_FOR_REVIEW_ISSUE_LABEL];
94-
if (event.provider === 'github') {
95-
await gitHubService.addLabels(event.copilot, event.data.repository.name, issue.number, readyForReviewLabels);
96-
} else {
97-
await gitlabService.addLabels(event.copilot, event.data.repository.id, issue.number, readyForReviewLabels);
89+
90+
if (event.event === 'issue.closed') {
91+
// reopen
92+
await reOpenIssue(event, issue);
93+
// ensure label is ready for review
94+
const readyForReviewLabels = [config.READY_FOR_REVIEW_ISSUE_LABEL];
95+
if (event.provider === 'github') {
96+
await gitHubService.addLabels(event.copilot, event.data.repository.full_name, issue.number, readyForReviewLabels);
97+
} else {
98+
await gitlabService.addLabels(event.copilot, event.data.repository.id, issue.number, readyForReviewLabels);
99+
}
98100
}
99101
}
100102
}
@@ -103,6 +105,7 @@ async function handleEventGracefully(event, issue, err) {
103105

104106
/**
105107
* check if challenge is exists for given issue in db/topcoder
108+
* @param {Object} event the event
106109
* @param {Object} issue the issue
107110
* @returns {Object} the found db issue if exists
108111
* @private
@@ -175,7 +178,7 @@ async function assignUserAsRegistrant(topcoderUserId, challengeId) {
175178
*/
176179
async function reOpenIssue(event, issue) {
177180
if (event.provider === 'github') {
178-
await gitHubService.changeState(event.copilot, event.data.repository.name, issue.number, 'open');
181+
await gitHubService.changeState(event.copilot, event.data.repository.full_name, issue.number, 'open');
179182
} else {
180183
await gitlabService.changeState(event.copilot, event.data.repository.id, issue.number, 'reopen');
181184
}
@@ -200,9 +203,9 @@ async function rollbackAssignee(event, assigneeUserId, issue, reOpen = false) {
200203
// comment on the git ticket for the user to self-sign up with the Topcoder x Self-Service tool
201204
const comment = `@${assigneeUsername}, please sign-up with Topcoder X tool`;
202205
if (event.provider === 'github') {
203-
await gitHubService.createComment(event.copilot, event.data.repository.name, issue.number, comment);
206+
await gitHubService.createComment(event.copilot, event.data.repository.full_name, issue.number, comment);
204207
// un-assign the user from the ticket
205-
await gitHubService.removeAssign(event.copilot, event.data.repository.name, issue.number, assigneeUsername);
208+
await gitHubService.removeAssign(event.copilot, event.data.repository.full_name, issue.number, assigneeUsername);
206209
} else {
207210
await gitlabService.createComment(event.copilot, event.data.repository.id, issue.number, comment);
208211
// un-assign the user from the ticket
@@ -283,7 +286,7 @@ async function handleIssueAssignment(event, issue) {
283286
const contestUrl = getUrlForChallengeId(dbIssue.challengeId);
284287
const comment = `Contest ${contestUrl} has been updated - it has been assigned to ${userMapping.topcoderUsername}.`;
285288
if (event.provider === 'github') {
286-
await gitHubService.createComment(event.copilot, event.data.repository.name, issue.number, comment);
289+
await gitHubService.createComment(event.copilot, event.data.repository.full_name, issue.number, comment);
287290
} else {
288291
await gitlabService.createComment(event.copilot, event.data.repository.id, issue.number, comment);
289292
}
@@ -312,15 +315,15 @@ async function handleIssueComment(event, issue) {
312315
logger.debug(`updating issue: ${event.data.repository.name}/${issue.number}`);
313316

314317
if (event.provider === 'github') {
315-
await gitHubService.updateIssue(event.copilot, event.data.repository.name, issue.number, newTitle);
318+
await gitHubService.updateIssue(event.copilot, event.data.repository.full_name, issue.number, newTitle);
316319
} else {
317320
await gitlabService.updateIssue(event.copilot, event.data.repository.id, issue.number, newTitle);
318321
}
319322

320323
// assign user
321324
logger.debug(`assigning user, ${parsedComment.assignedUser} to issue: ${event.data.repository.name}/${issue.number}`);
322325
if (event.provider === 'github') {
323-
await gitHubService.assignUser(event.copilot, event.data.repository.name, issue.number, parsedComment.assignedUser);
326+
await gitHubService.assignUser(event.copilot, event.data.repository.full_name, issue.number, parsedComment.assignedUser);
324327
} else {
325328
const userId = await gitlabService.getUserIdByLogin(event.copilot, parsedComment.assignedUser);
326329
await gitlabService.assignUser(event.copilot, event.data.repository.id, issue.number, userId);
@@ -368,7 +371,7 @@ async function handleIssueUpdate(event, issue) {
368371
const contestUrl = getUrlForChallengeId(dbIssue.challengeId);
369372
const comment = `Contest ${contestUrl} has been updated - the new changes has been updated for this ticket.`;
370373
if (event.provider === 'github') {
371-
await gitHubService.createComment(event.copilot, event.data.repository.name, issue.number, comment);
374+
await gitHubService.createComment(event.copilot, event.data.repository.full_name, issue.number, comment);
372375
} else {
373376
await gitlabService.createComment(event.copilot, event.data.repository.id, issue.number, comment);
374377
}
@@ -459,7 +462,7 @@ async function handleIssueClose(event, issue) {
459462
try {
460463
logger.debug('update issue as paid');
461464
if (event.provider === 'github') {
462-
await gitHubService.markIssueAsPaid(event.copilot, event.data.repository.name, issue.number, dbIssue.challengeId);
465+
await gitHubService.markIssueAsPaid(event.copilot, event.data.repository.full_name, issue.number, dbIssue.challengeId);
463466
} else {
464467
await gitlabService.markIssueAsPaid(event.copilot, event.data.repository.id, issue.number, dbIssue.challengeId);
465468
}
@@ -518,7 +521,7 @@ async function handleIssueCreate(event, issue) {
518521
const contestUrl = getUrlForChallengeId(issue.challengeId);
519522
const comment = `Contest ${contestUrl} has been created for this ticket.`;
520523
if (event.provider === 'github') {
521-
await gitHubService.createComment(event.copilot, event.data.repository.name, issue.number, comment);
524+
await gitHubService.createComment(event.copilot, event.data.repository.full_name, issue.number, comment);
522525
} else {
523526
await gitlabService.createComment(event.copilot, event.data.repository.id, issue.number, comment);
524527
}
@@ -618,7 +621,6 @@ async function process(event) {
618621
issue.assignee = await gitlabService.getUsernameById(copilot, event.data.issue.assignees[0].id);
619622
}
620623
}
621-
console.warn(JSON.stringify(issue));
622624
if (event.event === 'issue.created') {
623625
await handleIssueCreate(event, issue);
624626
} else if (event.event === 'issue.updated') {

0 commit comments

Comments
 (0)