From 2533996c92bc3cc5322f633389bc91d3ed977584 Mon Sep 17 00:00:00 2001
From: veshu <tcveshu@gmail.com>
Date: Mon, 16 Jul 2018 18:09:10 +0545
Subject: [PATCH 1/3] changes for
 https://github.com/topcoder-platform/topcoder-x-ui/issues/28

---
 models/Issue.js              |  17 ++++-
 services/IssueService.js     | 118 +++++++++++++++++++++++++++++------
 utils/kafka.js               |   4 +-
 utils/topcoder-api-helper.js |   2 +-
 4 files changed, 118 insertions(+), 23 deletions(-)

diff --git a/models/Issue.js b/models/Issue.js
index a1a6379..1fabcc1 100644
--- a/models/Issue.js
+++ b/models/Issue.js
@@ -18,13 +18,24 @@ const schema = new mongoose.Schema({
   prizes: [{type: Number, required: true}], // extracted from title
   provider: {type: String, required: true}, // github or gitlab
   repositoryId: {type: Number, required: true},
-
+  labels: [{type: String, required: true}],
+  assignee: {type: String, required: false},
+  updatedAt: {
+    type: Date,
+    default: Date.now
+  },
   // From topcoder api
-  challengeId: {type: Number, required: true, unique: true}
+  challengeId: {type: Number, required: true, unique: true},
+  projectId: {type: mongoose.Schema.Types.ObjectId, ref: 'Project'}
 });
 
 // Issue number, provider, repositoryId must be unique
 schema.index({number: 1, provider: 1, repositoryId: 1}, {unique: true});
+schema.index({labels: 1});
+schema.index({projectId: 1});
 
-
+schema.pre('save', function preSave(next) {
+  this.updatedAt = Date.now(); // eslint-disable-line
+  return next();
+});
 module.exports = schema;
diff --git a/services/IssueService.js b/services/IssueService.js
index 30b6b32..a802833 100755
--- a/services/IssueService.js
+++ b/services/IssueService.js
@@ -50,7 +50,7 @@ function parsePrizes(issue) {
   }
 
   issue.prizes = _.map(matches, (match) => parseInt(match.replace('$', ''), 10));
-  issue.title = issue.title.replace(/^(\[.*\])/, '');
+  issue.title = issue.title.replace(/^(\[.*\])/, '').trim();
 }
 
 /**
@@ -107,15 +107,25 @@ async function handleEventGracefully(event, issue, err) {
  * @returns {Object} the found db issue if exists
  * @private
  */
-async function ensureChallengeExists(issue) {
-  const dbIssue = await Issue.findOne({
+async function ensureChallengeExists(event, issue) {
+  let dbIssue = await Issue.findOne({
     number: issue.number,
     provider: issue.provider,
     repositoryId: issue.repositoryId
   });
-
   if (!dbIssue) {
-    throw errors.internalDependencyError(`there is no challenge for the updated issue ${issue.number}`);
+    // create if only in next retry of event
+    // else there can be conflict when issue being created
+    if (event.retryCount && _.toInteger(event.retryCount) > 1) {
+      await handleIssueCreate(event, issue);
+      dbIssue = await Issue.findOne({
+        number: issue.number,
+        provider: issue.provider,
+        repositoryId: issue.repositoryId
+      });
+    } else {
+      throw errors.internalDependencyError(`there is no challenge for the updated issue ${issue.number}`);
+    }
   }
   return dbIssue;
 }
@@ -255,13 +265,17 @@ async function handleIssueAssignment(event, issue) {
   if (userMapping && userMapping.topcoderUsername) {
     let dbIssue;
     try {
-      dbIssue = await ensureChallengeExists(issue);
+      dbIssue = await ensureChallengeExists(event, issue);
 
       logger.debug(`Getting the topcoder member ID for member name: ${userMapping.topcoderUsername}`);
       const topcoderUserId = await topcoderApiHelper.getTopcoderMemberId(userMapping.topcoderUsername);
       // Update the challenge
       logger.debug(`Assigning user to challenge: ${userMapping.topcoderUsername}`);
       assignUserAsRegistrant(topcoderUserId, dbIssue.challengeId);
+      dbIssue.set({
+        assignee: issue.assignee
+      });
+      await dbIssue.save();
     } catch (err) {
       handleEventGracefully(event, issue, err);
       return;
@@ -323,7 +337,7 @@ async function handleIssueComment(event, issue) {
 async function handleIssueUpdate(event, issue) {
   let dbIssue;
   try {
-    dbIssue = await ensureChallengeExists(issue);
+    dbIssue = await ensureChallengeExists(event, issue);
 
     if (_.isMatch(dbIssue, issue)) {
       // Title, body, prizes doesn't change, just ignore
@@ -337,17 +351,19 @@ async function handleIssueUpdate(event, issue) {
       detailedRequirements: issue.body,
       prizes: issue.prizes
     });
+    // Save
+    dbIssue.set({
+      title: issue.title,
+      body: issue.body,
+      prizes: issue.prizes,
+      labels: issue.labels,
+      assignee: issue.assignee
+    });
+    await dbIssue.save();
   } catch (e) {
     await handleEventGracefully(event, issue, e);
     return;
   }
-  // Save
-  dbIssue.set({
-    title: issue.title,
-    body: issue.body,
-    prizes: issue.prizes
-  });
-  await dbIssue.save();
   // comment on the git ticket for the user to self-sign up with the Topcoder x Self-Service tool
   const contestUrl = getUrlForChallengeId(dbIssue.challengeId);
   const comment = `Contest ${contestUrl} has been updated - the new changes has been updated for this ticket.`;
@@ -370,7 +386,7 @@ async function handleIssueUpdate(event, issue) {
 async function handleIssueClose(event, issue) {
   let dbIssue;
   try {
-    dbIssue = await ensureChallengeExists(issue);
+    dbIssue = await ensureChallengeExists(event, issue);
     if (!event.paymentSuccessful) {
       // if issue is closed without assignee then do nothing
       if (!event.data.assignee.id) {
@@ -519,6 +535,45 @@ async function handleIssueCreate(event, issue) {
   logger.debug(`new challenge created with id ${issue.challengeId} for issue ${issue.number}`);
 }
 
+/**
+ * handles the issue label updated event
+ * @param {Object} event the event
+ * @param {Object} issue the issue
+ * @private
+ */
+async function handleIssueLabelUpdated(event, issue) {
+  let dbIssue;
+  try {
+    dbIssue = await ensureChallengeExists(event, issue);
+  } catch (e) {
+    await handleEventGracefully(event, issue, e);
+    return;
+  }
+  dbIssue.set({
+    labels: issue.labels
+  });
+  await dbIssue.save();
+}
+
+/**
+ * handles the issue un assignment event
+ * @param {Object} event the event
+ * @param {Object} issue the issue
+ * @private
+ */
+async function handleIssueUnAssignment(event, issue) {
+  let dbIssue;
+  try {
+    dbIssue = await ensureChallengeExists(event, issue);
+  } catch (e) {
+    await handleEventGracefully(event, issue, e);
+    return;
+  }
+  dbIssue.set({
+    assignee: null
+  });
+  await dbIssue.save();
+}
 
 /**
  * Process issue event.
@@ -532,8 +587,21 @@ async function process(event) {
     title: event.data.issue.title,
     body: event.data.issue.body,
     provider: event.provider,
-    repositoryId: event.data.repository.id
+    repositoryId: event.data.repository.id,
+    labels: event.data.issue.labels
   };
+  let fullRepoUrl;
+  if (event.provider === 'github') {
+    fullRepoUrl = `https://github.com/${event.data.repository.full_name}`;
+  } else if (event.provider === 'gitlab') {
+    fullRepoUrl = `${config.GITLAB_API_BASE_URL}/${event.data.repository.full_name}`;
+  }
+
+  const project = await models.Project.findOne({
+    repoUrl: fullRepoUrl
+  });
+
+  issue.projectId = project.id;
 
   // Parse prize from title
   parsePrizes(issue);
@@ -543,6 +611,14 @@ async function process(event) {
   // Markdown the body
   issue.body = md.render(_.get(issue, 'body', ''));
 
+  if (event.data.issue.assignees && event.data.issue.assignees.length > 0 && event.data.issue.assignees[0].id) {
+    if (event.provider === 'github') {
+      issue.assignee = await gitHubService.getUsernameById(copilot, event.data.issue.assignees[0].id);
+    } else if (event.provider === 'gitlab') {
+      issue.assignee = await gitlabService.getUsernameById(copilot, event.data.issue.assignees[0].id);
+    }
+  }
+  console.warn(JSON.stringify(issue));
   if (event.event === 'issue.created') {
     await handleIssueCreate(event, issue);
   } else if (event.event === 'issue.updated') {
@@ -553,11 +629,16 @@ async function process(event) {
     await handleIssueComment(event, issue);
   } else if (event.event === 'issue.assigned') {
     await handleIssueAssignment(event, issue);
+  } else if (event.event === 'issue.labelUpdated') {
+    await handleIssueLabelUpdated(event, issue);
+  } else if (event.event === 'issue.unassigned') {
+    await handleIssueUnAssignment(event, issue);
   }
 }
 
 process.schema = Joi.object().keys({
-  event: Joi.string().valid('issue.created', 'issue.updated', 'issue.closed', 'comment.created', 'comment.updated', 'issue.assigned').required(),
+  event: Joi.string().valid('issue.created', 'issue.updated', 'issue.closed', 'comment.created', 'comment.updated', 'issue.assigned',
+    'issue.labelUpdated', 'issue.unassigned').required(),
   provider: Joi.string().valid('github', 'gitlab').required(),
   data: Joi.object().keys({
     issue: Joi.object().keys({
@@ -586,7 +667,8 @@ process.schema = Joi.object().keys({
     }),
     assignee: Joi.object().keys({
       id: Joi.number().required().allow(null)
-    })
+    }),
+    labels: Joi.array().items(Joi.string())
   }).required(),
   retryCount: Joi.number().integer().default(0).optional(),
   paymentSuccessful: Joi.boolean().default(false).optional()
diff --git a/utils/kafka.js b/utils/kafka.js
index 7ad536d..7a371f3 100644
--- a/utils/kafka.js
+++ b/utils/kafka.js
@@ -43,7 +43,9 @@ class Kafka {
         return;
       }
 
-      if (event && _.includes(['issue.created', 'issue.updated', 'issue.closed', 'comment.created', 'comment.updated', 'issue.assigned'], event.event)) {
+      if (event && _.includes(['issue.created', 'issue.updated', 'issue.closed',
+        'comment.created', 'comment.updated', 'issue.assigned', 'issue.labelUpdated', 'issue.unassigned']
+        , event.event)) {
         IssueService
           .process(event)
           .catch(logger.error);
diff --git a/utils/topcoder-api-helper.js b/utils/topcoder-api-helper.js
index 4cb1230..6ca0043 100644
--- a/utils/topcoder-api-helper.js
+++ b/utils/topcoder-api-helper.js
@@ -248,7 +248,7 @@ async function getProjectBillingAccountId(id) {
     });
     const billingAccountId = _.get(response, 'data.result.content.billingAccountIds[0]');
     if (!billingAccountId) {
-      _.set(response, 'data.result.content', `There is no billing account id associated with project ${id}`)
+      _.set(response, 'data.result.content', `There is no billing account id associated with project ${id}`);
       throw new Error(response);
     }
     return billingAccountId;

From 365e9265a7d7b728efe88127a76af1386263dc03 Mon Sep 17 00:00:00 2001
From: veshu <tcveshu@gmail.com>
Date: Sat, 21 Jul 2018 01:36:47 +0545
Subject: [PATCH 2/3] update issue after only last try

---
 services/IssueService.js | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/services/IssueService.js b/services/IssueService.js
index a802833..d3a8140 100755
--- a/services/IssueService.js
+++ b/services/IssueService.js
@@ -74,27 +74,29 @@ async function handleEventGracefully(event, issue, err) {
         logger.debug('The event is scheduled for retry');
       }, config.RETRY_INTERVAL);
     }
-    let comment = `[${err.statusCode}]: ${err.message}`;
-    if (event.event === 'issue.closed' && event.paymentSuccessful === false) {
-      comment = `Payment failed: ${comment}`;
-    }
+
     if (event.retryCount === config.RETRY_COUNT) {
+      let comment = `[${err.statusCode}]: ${err.message}`;
+      if (event.event === 'issue.closed' && event.paymentSuccessful === false) {
+        comment = `Payment failed: ${comment}`;
+      }
       // notify error in git host
       if (event.provider === 'github') {
         await gitHubService.createComment(event.copilot, event.data.repository.name, issue.number, comment);
       } else {
         await gitlabService.createComment(event.copilot, event.data.repository.id, issue.number, comment);
       }
-    }
-    if (event.event === 'issue.closed') {
-      // reopen
-      await reOpenIssue(event, issue);
-      // ensure label is ready for review
-      const readyForReviewLabels = [config.READY_FOR_REVIEW_ISSUE_LABEL];
-      if (event.provider === 'github') {
-        await gitHubService.addLabels(event.copilot, event.data.repository.name, issue.number, readyForReviewLabels);
-      } else {
-        await gitlabService.addLabels(event.copilot, event.data.repository.id, issue.number, readyForReviewLabels);
+
+      if (event.event === 'issue.closed') {
+        // reopen
+        await reOpenIssue(event, issue);
+        // ensure label is ready for review
+        const readyForReviewLabels = [config.READY_FOR_REVIEW_ISSUE_LABEL];
+        if (event.provider === 'github') {
+          await gitHubService.addLabels(event.copilot, event.data.repository.name, issue.number, readyForReviewLabels);
+        } else {
+          await gitlabService.addLabels(event.copilot, event.data.repository.id, issue.number, readyForReviewLabels);
+        }
       }
     }
   }
@@ -618,7 +620,6 @@ async function process(event) {
       issue.assignee = await gitlabService.getUsernameById(copilot, event.data.issue.assignees[0].id);
     }
   }
-  console.warn(JSON.stringify(issue));
   if (event.event === 'issue.created') {
     await handleIssueCreate(event, issue);
   } else if (event.event === 'issue.updated') {

From f41df8c794f57df7d48086e9e31a431c5e6535f1 Mon Sep 17 00:00:00 2001
From: veshu <tcveshu@gmail.com>
Date: Wed, 25 Jul 2018 12:55:48 +0545
Subject: [PATCH 3/3] fix for #36

---
 services/GithubService.js | 81 +++++++++++++++++++++++----------------
 services/IssueService.js  | 25 ++++++------
 2 files changed, 60 insertions(+), 46 deletions(-)

diff --git a/services/GithubService.js b/services/GithubService.js
index cfef8a2..89b05e0 100644
--- a/services/GithubService.js
+++ b/services/GithubService.js
@@ -22,6 +22,19 @@ const copilotUserSchema = Joi.object().keys({
   topcoderUsername: Joi.string()
 }).required();
 
+/**
+ * parse the repository name and repoFullName owner
+ * @param {String} fullName the full repository name
+ * @returns {Object} the parsed data
+ * @private
+ */
+function _parseRepoUrl(fullName) {
+  const results = fullName.split('/');
+  const repo = results[results.length - 1];
+  const owner = _(results).slice(0, results.length - 1).join('/');
+  return {owner, repo};
+}
+
 /**
  * authenticate the github using access token
  * @param {String} accessToken the access token of copilot
@@ -79,14 +92,14 @@ async function _getUsernameById(github, id) {
 /**
  * updates the title of github issue
  * @param {Object} copilot the copilot
- * @param {string} repo the repository
+ * @param {string} repoFullName the repository
  * @param {Number} number the issue number
  * @param {string} title new title
  */
-async function updateIssue(copilot, repo, number, title) {
-  Joi.attempt({copilot, repo, number, title}, updateIssue.schema);
+async function updateIssue(copilot, repoFullName, number, title) {
+  Joi.attempt({copilot, repoFullName, number, title}, updateIssue.schema);
   const github = await _authenticate(copilot.accessToken);
-  const owner = await _getUsernameById(github, copilot.userProviderId);
+  const {owner, repo} = _parseRepoUrl(repoFullName);
   try {
     await github.issues.edit({owner, repo, number, title});
   } catch (err) {
@@ -97,7 +110,7 @@ async function updateIssue(copilot, repo, number, title) {
 
 updateIssue.schema = {
   copilot: copilotUserSchema,
-  repo: Joi.string().required(),
+  repoFullName: Joi.string().required(),
   number: Joi.number().required(),
   title: Joi.string().required()
 };
@@ -105,14 +118,14 @@ updateIssue.schema = {
 /**
  * Assigns the issue to user
  * @param {Object} copilot the copilot
- * @param {string} repo the repository
+ * @param {string} repoFullName the repository
  * @param {Number} number the issue number
  * @param {string} user the user login of assignee
  */
-async function assignUser(copilot, repo, number, user) {
-  Joi.attempt({copilot, repo, number, user}, assignUser.schema);
+async function assignUser(copilot, repoFullName, number, user) {
+  Joi.attempt({copilot, repoFullName, number, user}, assignUser.schema);
   const github = await _authenticate(copilot.accessToken);
-  const owner = await _getUsernameById(github, copilot.userProviderId);
+  const {owner, repo} = _parseRepoUrl(repoFullName);
   try {
     const issue = await github.issues.get({owner, repo, number});
 
@@ -129,7 +142,7 @@ async function assignUser(copilot, repo, number, user) {
 
 assignUser.schema = {
   copilot: copilotUserSchema,
-  repo: Joi.string().required(),
+  repoFullName: Joi.string().required(),
   number: Joi.number().required(),
   user: Joi.string().required()
 };
@@ -137,15 +150,15 @@ assignUser.schema = {
 /**
  * Removes an assignee from the issue
  * @param {Object} copilot the copilot
- * @param {string} repo the repository
+ * @param {string} repoFullName the repository
  * @param {Number} number the issue number
  * @param {string} user the user login of assignee
  */
-async function removeAssign(copilot, repo, number, user) {
-  Joi.attempt({copilot, repo, number, user}, removeAssign.schema);
+async function removeAssign(copilot, repoFullName, number, user) {
+  Joi.attempt({copilot, repoFullName, number, user}, removeAssign.schema);
 
   const github = await _authenticate(copilot.accessToken);
-  const owner = await _getUsernameById(github, copilot.userProviderId);
+  const {owner, repo} = _parseRepoUrl(repoFullName);
   await _removeAssignees(github, owner, repo, number, [user]);
   logger.debug(`Github user ${user} is unassigned from issue number ${number}`);
 }
@@ -155,15 +168,15 @@ removeAssign.schema = assignUser.schema;
 /**
  * creates the comments on github issue
  * @param {Object} copilot the copilot
- * @param {string} repo the repository
+ * @param {string} repoFullName the repository
  * @param {Number} number the issue number
  * @param {string} body the comment body text
  */
-async function createComment(copilot, repo, number, body) {
-  Joi.attempt({copilot, repo, number, body}, createComment.schema);
+async function createComment(copilot, repoFullName, number, body) {
+  Joi.attempt({copilot, repoFullName, number, body}, createComment.schema);
 
   const github = await _authenticate(copilot.accessToken);
-  const owner = await _getUsernameById(github, copilot.userProviderId);
+  const {owner, repo} = _parseRepoUrl(repoFullName);
   try {
     await github.issues.createComment({owner, repo, number, body});
   } catch (err) {
@@ -174,7 +187,7 @@ async function createComment(copilot, repo, number, body) {
 
 createComment.schema = {
   copilot: copilotUserSchema,
-  repo: Joi.string().required(),
+  repoFullName: Joi.string().required(),
   number: Joi.number().required(),
   body: Joi.string().required()
 };
@@ -218,14 +231,14 @@ getUserIdByLogin.schema = {
 /**
  * updates the github issue as paid and fix accepted
  * @param {Object} copilot the copilot
- * @param {string} repo the repository
+ * @param {string} repoFullName the repository
  * @param {Number} number the issue number
  * @param {Number} challengeId the challenge id
  */
-async function markIssueAsPaid(copilot, repo, number, challengeId) {
-  Joi.attempt({copilot, repo, number, challengeId}, markIssueAsPaid.schema);
+async function markIssueAsPaid(copilot, repoFullName, number, challengeId) {
+  Joi.attempt({copilot, repoFullName, number, challengeId}, markIssueAsPaid.schema);
   const github = await _authenticate(copilot.accessToken);
-  const owner = await _getUsernameById(github, copilot.userProviderId);
+  const {owner, repo} = _parseRepoUrl(repoFullName);
   const labels = [config.PAID_ISSUE_LABEL, config.FIX_ACCEPTED_ISSUE_LABEL];
   try {
     await github.issues.edit({owner, repo, number, labels});
@@ -239,7 +252,7 @@ async function markIssueAsPaid(copilot, repo, number, challengeId) {
 
 markIssueAsPaid.schema = {
   copilot: copilotUserSchema,
-  repo: Joi.string().required(),
+  repoFullName: Joi.string().required(),
   number: Joi.number().required(),
   challengeId: Joi.number().positive().required()
 };
@@ -247,14 +260,14 @@ markIssueAsPaid.schema = {
 /**
  * change the state of github issue
  * @param {Object} copilot the copilot
- * @param {string} repo the repository
+ * @param {string} repoFullName the repository
  * @param {Number} number the issue number
  * @param {string} state new state
  */
-async function changeState(copilot, repo, number, state) {
-  Joi.attempt({copilot, repo, number, state}, changeState.schema);
+async function changeState(copilot, repoFullName, number, state) {
+  Joi.attempt({copilot, repoFullName, number, state}, changeState.schema);
   const github = await _authenticate(copilot.accessToken);
-  const owner = await _getUsernameById(github, copilot.userProviderId);
+  const {owner, repo} = _parseRepoUrl(repoFullName);
   try {
     await github.issues.edit({owner, repo, number, state});
   } catch (err) {
@@ -265,7 +278,7 @@ async function changeState(copilot, repo, number, state) {
 
 changeState.schema = {
   copilot: copilotUserSchema,
-  repo: Joi.string().required(),
+  repoFullName: Joi.string().required(),
   number: Joi.number().required(),
   state: Joi.string().required()
 };
@@ -273,14 +286,14 @@ changeState.schema = {
 /**
  * updates the github issue with new labels
  * @param {Object} copilot the copilot
- * @param {string} repo the repository
+ * @param {string} repoFullName the repository
  * @param {Number} number the issue number
  * @param {Number} labels the challenge id
  */
-async function addLabels(copilot, repo, number, labels) {
-  Joi.attempt({copilot, repo, number, labels}, addLabels.schema);
+async function addLabels(copilot, repoFullName, number, labels) {
+  Joi.attempt({copilot, repoFullName, number, labels}, addLabels.schema);
   const github = await _authenticate(copilot.accessToken);
-  const owner = await _getUsernameById(github, copilot.userProviderId);
+  const {owner, repo} = _parseRepoUrl(repoFullName);
   try {
     await github.issues.edit({owner, repo, number, labels});
   } catch (err) {
@@ -291,7 +304,7 @@ async function addLabels(copilot, repo, number, labels) {
 
 addLabels.schema = {
   copilot: copilotUserSchema,
-  repo: Joi.string().required(),
+  repoFullName: Joi.string().required(),
   number: Joi.number().required(),
   labels: Joi.array().items(Joi.string()).required()
 };
diff --git a/services/IssueService.js b/services/IssueService.js
index d3a8140..c45e67c 100755
--- a/services/IssueService.js
+++ b/services/IssueService.js
@@ -65,7 +65,7 @@ async function handleEventGracefully(event, issue, err) {
     // reschedule event
     if (event.retryCount <= config.RETRY_COUNT) {
       logger.debug('Scheduling event for next retry');
-      const newEvent = { ...event };
+      const newEvent = {...event};
       newEvent.retryCount += 1;
       delete newEvent.copilot;
       setTimeout(async () => {
@@ -82,7 +82,7 @@ async function handleEventGracefully(event, issue, err) {
       }
       // notify error in git host
       if (event.provider === 'github') {
-        await gitHubService.createComment(event.copilot, event.data.repository.name, issue.number, comment);
+        await gitHubService.createComment(event.copilot, event.data.repository.full_name, issue.number, comment);
       } else {
         await gitlabService.createComment(event.copilot, event.data.repository.id, issue.number, comment);
       }
@@ -93,7 +93,7 @@ async function handleEventGracefully(event, issue, err) {
         // ensure label is ready for review
         const readyForReviewLabels = [config.READY_FOR_REVIEW_ISSUE_LABEL];
         if (event.provider === 'github') {
-          await gitHubService.addLabels(event.copilot, event.data.repository.name, issue.number, readyForReviewLabels);
+          await gitHubService.addLabels(event.copilot, event.data.repository.full_name, issue.number, readyForReviewLabels);
         } else {
           await gitlabService.addLabels(event.copilot, event.data.repository.id, issue.number, readyForReviewLabels);
         }
@@ -105,6 +105,7 @@ async function handleEventGracefully(event, issue, err) {
 
 /**
  * check if challenge is exists for given issue in db/topcoder
+ * @param {Object} event the event
  * @param {Object} issue the issue
  * @returns {Object} the found db issue if exists
  * @private
@@ -177,7 +178,7 @@ async function assignUserAsRegistrant(topcoderUserId, challengeId) {
  */
 async function reOpenIssue(event, issue) {
   if (event.provider === 'github') {
-    await gitHubService.changeState(event.copilot, event.data.repository.name, issue.number, 'open');
+    await gitHubService.changeState(event.copilot, event.data.repository.full_name, issue.number, 'open');
   } else {
     await gitlabService.changeState(event.copilot, event.data.repository.id, issue.number, 'reopen');
   }
@@ -202,9 +203,9 @@ async function rollbackAssignee(event, assigneeUserId, issue, reOpen = false) {
   // comment on the git ticket for the user to self-sign up with the Topcoder x Self-Service tool
   const comment = `@${assigneeUsername}, please sign-up with Topcoder X tool`;
   if (event.provider === 'github') {
-    await gitHubService.createComment(event.copilot, event.data.repository.name, issue.number, comment);
+    await gitHubService.createComment(event.copilot, event.data.repository.full_name, issue.number, comment);
     // un-assign the user from the ticket
-    await gitHubService.removeAssign(event.copilot, event.data.repository.name, issue.number, assigneeUsername);
+    await gitHubService.removeAssign(event.copilot, event.data.repository.full_name, issue.number, assigneeUsername);
   } else {
     await gitlabService.createComment(event.copilot, event.data.repository.id, issue.number, comment);
     // un-assign the user from the ticket
@@ -285,7 +286,7 @@ async function handleIssueAssignment(event, issue) {
     const contestUrl = getUrlForChallengeId(dbIssue.challengeId);
     const comment = `Contest ${contestUrl} has been updated - it has been assigned to ${userMapping.topcoderUsername}.`;
     if (event.provider === 'github') {
-      await gitHubService.createComment(event.copilot, event.data.repository.name, issue.number, comment);
+      await gitHubService.createComment(event.copilot, event.data.repository.full_name, issue.number, comment);
     } else {
       await gitlabService.createComment(event.copilot, event.data.repository.id, issue.number, comment);
     }
@@ -314,7 +315,7 @@ async function handleIssueComment(event, issue) {
     logger.debug(`updating issue: ${event.data.repository.name}/${issue.number}`);
 
     if (event.provider === 'github') {
-      await gitHubService.updateIssue(event.copilot, event.data.repository.name, issue.number, newTitle);
+      await gitHubService.updateIssue(event.copilot, event.data.repository.full_name, issue.number, newTitle);
     } else {
       await gitlabService.updateIssue(event.copilot, event.data.repository.id, issue.number, newTitle);
     }
@@ -322,7 +323,7 @@ async function handleIssueComment(event, issue) {
     // assign user
     logger.debug(`assigning user, ${parsedComment.assignedUser} to issue: ${event.data.repository.name}/${issue.number}`);
     if (event.provider === 'github') {
-      await gitHubService.assignUser(event.copilot, event.data.repository.name, issue.number, parsedComment.assignedUser);
+      await gitHubService.assignUser(event.copilot, event.data.repository.full_name, issue.number, parsedComment.assignedUser);
     } else {
       const userId = await gitlabService.getUserIdByLogin(event.copilot, parsedComment.assignedUser);
       await gitlabService.assignUser(event.copilot, event.data.repository.id, issue.number, userId);
@@ -370,7 +371,7 @@ async function handleIssueUpdate(event, issue) {
   const contestUrl = getUrlForChallengeId(dbIssue.challengeId);
   const comment = `Contest ${contestUrl} has been updated - the new changes has been updated for this ticket.`;
   if (event.provider === 'github') {
-    await gitHubService.createComment(event.copilot, event.data.repository.name, issue.number, comment);
+    await gitHubService.createComment(event.copilot, event.data.repository.full_name, issue.number, comment);
   } else {
     await gitlabService.createComment(event.copilot, event.data.repository.id, issue.number, comment);
   }
@@ -461,7 +462,7 @@ async function handleIssueClose(event, issue) {
   try {
     logger.debug('update issue as paid');
     if (event.provider === 'github') {
-      await gitHubService.markIssueAsPaid(event.copilot, event.data.repository.name, issue.number, dbIssue.challengeId);
+      await gitHubService.markIssueAsPaid(event.copilot, event.data.repository.full_name, issue.number, dbIssue.challengeId);
     } else {
       await gitlabService.markIssueAsPaid(event.copilot, event.data.repository.id, issue.number, dbIssue.challengeId);
     }
@@ -520,7 +521,7 @@ async function handleIssueCreate(event, issue) {
   const contestUrl = getUrlForChallengeId(issue.challengeId);
   const comment = `Contest ${contestUrl} has been created for this ticket.`;
   if (event.provider === 'github') {
-    await gitHubService.createComment(event.copilot, event.data.repository.name, issue.number, comment);
+    await gitHubService.createComment(event.copilot, event.data.repository.full_name, issue.number, comment);
   } else {
     await gitlabService.createComment(event.copilot, event.data.repository.id, issue.number, comment);
   }