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

Version 1.2.2 #461

Merged
merged 26 commits into from
Jun 22, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8368b32
Drop down selector for Connect project instead of text field
jmgasper May 18, 2022
43ad8ea
Deploy for testing
jmgasper May 18, 2022
638b3e3
Updates for timeout
jmgasper May 18, 2022
0ad0c52
Further timeout test
jmgasper May 19, 2022
8d73ae2
Let’s try this
jmgasper May 19, 2022
7077279
Use ui-select (https://angular-ui.github.io/ui-select/) as dropdown s…
gets0ul May 19, 2022
eb360cf
Merge pull request #446 from gets0ul/issue-445
jmgasper May 19, 2022
cef4344
Archived projects still using copilot handle
jmgasper May 20, 2022
446b2c3
https://github.com/topcoder-platform/topcoder-x-ui/issues/448
52cs May 25, 2022
e82f6c6
Merge pull request #449 from 52cs/issue-448
jmgasper May 25, 2022
131b236
Refresh owner user/copilot Gitlab access token automatically when needed
gets0ul May 25, 2022
54055a2
Merge pull request #450 from gets0ul/issue_447
jmgasper May 25, 2022
e29301e
small fix on PR #449 for issue #448
52cs May 27, 2022
595d71c
Merge pull request #451 from 52cs/issue-448-fix
jmgasper May 30, 2022
c4e694f
Changes to Connect ID dropdown:
gets0ul May 31, 2022
8b4bf6b
Merge pull request #454 from gets0ul/issue_452
jmgasper May 31, 2022
9d11673
https://github.com/topcoder-platform/topcoder-x-ui/issues/453
52cs Jun 2, 2022
5e2a247
Merge pull request #455 from 52cs/issue-453
jmgasper Jun 2, 2022
03f10ce
fix lint of PR#455 for Issue453
52cs Jun 2, 2022
855879d
Merge pull request #456 from 52cs/fix-lint-455
jmgasper Jun 2, 2022
2d04d6a
https://github.com/topcoder-platform/topcoder-x-ui/issues/453
52cs Jun 2, 2022
5c2afde
Merge pull request #457 from 52cs/fix-issue-453
jmgasper Jun 2, 2022
c334ca3
fix-empty-tags
52cs Jun 3, 2022
aec774d
Merge pull request #458 from 52cs/fix-empty-tags/Issue#453
jmgasper Jun 3, 2022
9935ebb
https://github.com/topcoder-platform/topcoder-x-ui/issues/459
52cs Jun 14, 2022
c92f485
Merge pull request #460 from 52cs/issue-459
jmgasper Jun 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Archived projects still using copilot handle
  • Loading branch information
jmgasper committed May 20, 2022
commit cef4344823dcfad7d1ecbfebda68f14a604a5777
30 changes: 30 additions & 0 deletions src/common/db-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,35 @@ async function queryOneOrganisation(model, organisation) {
});
}

/**
* Query one active repository
* @param {String} url the repository url
* @returns {Promise<Object>}
*/
async function queryOneRepository(url) {
return await new Promise((resolve, reject) => {
models.Repository.query({
url,
})
.all()
.exec((err, repos) => {
if (err) {
return reject(err);
}
if (!repos || repos.length === 0) resolve(null);
if (repos.length > 1) {
let error = `Repository's url is unique in this version.
This Error must be caused by old data in the Repository table.
The old version can only guarrentee that the active Repository's url is unique.
Please migrate the old Repository table.`;
logger.debug(`queryOneRepository. Error. ${error}`);
reject(error);
}
return resolve(repos[0]);
});
});
}

/**
* Query one active repository
* @param {Object} model the dynamoose model
Expand Down Expand Up @@ -597,6 +626,7 @@ module.exports = {
queryOneActiveProject,
queryOneActiveProjectWithFilter,
queryOneActiveRepository,
queryOneRepository,
queryOneOrganisation,
queryOneIssue,
queryOneUserByType,
Expand Down
2 changes: 2 additions & 0 deletions src/models/Issue.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const schema = new Schema({
repoUrl: {
type: String
},
repositoryIdStr: {type: String, required: false},
labels: {
type: Array,
required: false,
Expand All @@ -49,6 +50,7 @@ const schema = new Schema({
},
// From topcoder api
challengeId: {type: Number, required: false},
challengeUUID: {type: String, required: false},
projectId: {type: String},
status: {type: String},
assignedAt: {type: Date, required: false},
Expand Down
6 changes: 6 additions & 0 deletions src/services/CopilotPaymentService.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ async function _ensureEditPermissionAndGetInfo(paymentId, topcoderUser) {
if (dbPayment.closed === true) {
throw new Error('Closed payment can not be updated');
}
if (dbProject.archived) {
throw new errors.ForbiddenError('You can\'t edit this payment in an archived project');
}
return dbPayment;
}

Expand Down Expand Up @@ -203,6 +206,9 @@ async function create(topcoderUser, payment) {
if (dbProject.copilot !== topcoderUser.handle && dbProject.owner !== topcoderUser.handle) {
throw new errors.ForbiddenError('You do not have permission to edit this payment');
}
if (dbProject.archived) {
throw new errors.ForbiddenError('You can\'t edit this payment in an archived project');
}
payment.username = dbProject.copilot;
payment.closed = false;
payment.id = helper.generateIdentifier();
Expand Down
3 changes: 3 additions & 0 deletions src/services/IssueService.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ async function _ensureEditPermissionAndGetInfo(projectId, currentUser) {
) {
throw new errors.ForbiddenError('You don\'t have access on this project');
}
if (dbProject.archived) {
throw new errors.ForbiddenError('You can\'t access on this archived project');
}
return dbProject;
}

Expand Down
120 changes: 92 additions & 28 deletions src/services/ProjectService.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ async function _validateProjectData(project, repoUrl) {
}
if (existsInDatabase) {
throw new errors.ValidationError(`This repo already has a Topcoder-X project associated with it.
Copilot: ${existsInDatabase.copilot}, Owner: ${existsInDatabase.owner}`)
Repo: ${repoUrl}, Copilot: ${existsInDatabase.copilot}, Owner: ${existsInDatabase.owner}`)
}
const provider = await helper.getProviderType(repoUrl);
const userRole = project.copilot ? project.copilot : project.owner;
Expand Down Expand Up @@ -112,9 +112,80 @@ async function _ensureEditPermissionAndGetInfo(projectId, currentUser) {
) {
throw new errors.ForbiddenError('You don\'t have access on this project');
}
if (dbProject.archived) {
throw new errors.ForbiddenError('You can\'t access on this archived project');
}
return dbProject;
}

/**
* create Repository as well as adding git label, hook, wiki
* or
* migrate Repository as well as related Issue and CopilotPayment
* @param {String} repoUrl the repository url
* @param {Object} project the new project
* @param {String} currentUser the topcoder current user
* @returns {void}
* @private
*/
async function _createOrMigrateRepository(repoUrl, project, currentUser) {
let oldRepo = await dbHelper.queryOneRepository(repoUrl);
if (oldRepo) {
if (oldRepo.projectId === project.id) {
throw new Error(`This error should never occur: the projectId of the repository to be migrate
will never equal to the new project id`);
}
if (oldRepo.archived === false) {
throw new Error(`Duplicate active repository should be blocked by _validateProjectData,
or a time-sequence cornercase encountered here`);
}
try {
let oldIssues = await models.Issue.query({repoUrl: oldRepo.url});
let oldCopilotPaymentPromise = oldIssues.filter(issue => issue.challengeUUID)
.map(issue => models.CopilotPayment.query({challengeUUID: issue.challengeUUID})
.then(payments => {
if (!payments || payments.length === 0) {
/* eslint-disable-next-line no-console */
console.log(`No CopilotPayment correspond to Issue with challengeUUID ${issue.challengeUUID}.
The corresponding CopilotPayment may have been removed.
Or, there is bug in old version.`);
return null;
}
if (payments.length > 1) {
throw new Error(`Duplicate CopilotPayment correspond to one Issue with challengeUUID ${issue.challengeUUID}.
There must be bug in old version`);
}
return payments[0];
}));
let oldCopilotPayment = await Promise.all(oldCopilotPaymentPromise).filter(payment => payment);

await models.Repository.update({id: oldRepo.id}, {projectId: project.id, archived: false});
await oldIssues.forEach(issue => models.Issue.update({id: issue.id}, {projectId: project.id}));
await oldCopilotPayment.forEach(
payment => models.CopilotPayment.update({id: payment.id}, {project: project.id})
);
}
catch (err) {
throw new Error(`Update ProjectId for Repository, Issue, CopilotPayment failed. Repo ${repoUrl}. Internal Error: ${err.message}`);
}
} else {
try {
await dbHelper.create(models.Repository, {
id: helper.generateIdentifier(),
projectId: project.id,
url: repoUrl,
archived: project.archived
})
await createLabel({projectId: project.id}, currentUser, repoUrl);
await createHook({projectId: project.id}, currentUser, repoUrl);
await addWikiRules({projectId: project.id}, currentUser, repoUrl);
}
catch (err) {
throw new Error(`Project created. Adding the webhook, issue labels, and wiki rules failed. Repo ${repoUrl}. Internal Error: ${err.message}`);
}
}
}

/**
* creates project
* @param {Object} project the project detail
Expand Down Expand Up @@ -142,24 +213,16 @@ async function create(project, currentUser) {
project.copilot = project.copilot ? project.copilot.toLowerCase() : null;
project.id = helper.generateIdentifier();

const createdProject = await dbHelper.create(models.Project, project);

// TODO: The following db operation should/could be moved into one transaction
for (const repoUrl of repoUrls) { // eslint-disable-line no-restricted-syntax
await dbHelper.create(models.Repository, {
id: helper.generateIdentifier(),
projectId: project.id,
url: repoUrl,
archived: project.archived
})
try {
await createLabel({projectId: project.id}, currentUser, repoUrl);
await createHook({projectId: project.id}, currentUser, repoUrl);
await addWikiRules({projectId: project.id}, currentUser, repoUrl);
await _createOrMigrateRepository(repoUrl, project, currentUser);
}
catch (err) {
throw new Error(`Project created. Adding the webhook, issue labels, and wiki rules failed. Repo ${repoUrl}`);
throw new Error(`Create or migrate repository failed. Repo ${repoUrl}. Internal Error: ${err.message}`);
}
}
const createdProject = await dbHelper.create(models.Project, project);

return createdProject;
}
Expand All @@ -178,6 +241,7 @@ async function update(project, currentUser) {
for (const repoUrl of repoUrls) { // eslint-disable-line no-restricted-syntax
await _validateProjectData(project, repoUrl);
}
// TODO: remove the useless code-block
if (dbProject.archived === 'false' && project.archived === true) {
// project archived detected.
const result = {
Expand All @@ -201,22 +265,22 @@ async function update(project, currentUser) {
dbProject[item[0]] = item[1];
return item;
});
const oldRepositories = await dbHelper.queryRepositoriesByProjectId(dbProject.id);
const weebhookIds = {};
for (const repo of oldRepositories) { // eslint-disable-line
if (repo.registeredWebhookId) {
weebhookIds[repo.url] = repo.registeredWebhookId;
}
await dbHelper.removeById(models.Repository, repo.id);
}

// TODO: move the following logic into one dynamoose transaction
const repoUrl2Repo = await dbHelper.queryRepositoriesByProjectId(dbProject.id)
.map(repo => { return {[repo.url]: repo}; });

for (const repoUrl of repoUrls) { // eslint-disable-line no-restricted-syntax
await dbHelper.create(models.Repository, {
id: helper.generateIdentifier(),
projectId: dbProject.id,
url: repoUrl,
archived: project.archived,
registeredWebhookId: weebhookIds[repoUrl]
})
if (repoUrl in repoUrl2Repo) {
await models.Repository.update({id: repoUrl2Repo[repoUrl].id}, {archived: project.archived});
} else {
try {
await _createOrMigrateRepository(repoUrl, project, currentUser);
}
catch (err) {
throw new Error(`Create or migrate repository failed. Repo ${repoUrl}. Internal Error: ${err.message}`);
}
}
}
dbProject.updatedAt = new Date();
return await dbHelper.update(models.Project, dbProject.id, dbProject);
Expand Down