mirror of
https://github.com/hcengineering/platform.git
synced 2026-08-25 13:52:24 +02:00
UBERF-9724: Use updated accounts (#8452)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
@@ -104,7 +104,7 @@ export class CommentSyncManager implements DocSyncManager {
|
||||
return true
|
||||
}
|
||||
const account =
|
||||
existing?.createdBy ?? (await this.provider.getAccountU(commentExternal.user))?._id ?? core.account.System
|
||||
existing?.createdBy ?? (await this.provider.getAccountU(commentExternal.user)) ?? core.account.System
|
||||
|
||||
if (commentExternal !== undefined) {
|
||||
try {
|
||||
@@ -164,7 +164,7 @@ export class CommentSyncManager implements DocSyncManager {
|
||||
return
|
||||
}
|
||||
|
||||
const account = (await this.provider.getAccountU(event.sender))?._id ?? core.account.System
|
||||
const account = (await this.provider.getAccountU(event.sender)) ?? core.account.System
|
||||
switch (event.action) {
|
||||
case 'created': {
|
||||
await this.createSyncData(event, derivedClient, repo)
|
||||
@@ -277,7 +277,7 @@ export class CommentSyncManager implements DocSyncManager {
|
||||
return { needSync: githubSyncVersion }
|
||||
}
|
||||
|
||||
const account = existing?.modifiedBy ?? (await this.provider.getAccountU(comment.user))?._id ?? core.account.System
|
||||
const account = existing?.modifiedBy ?? (await this.provider.getAccountU(comment.user)) ?? core.account.System
|
||||
|
||||
const messageData: MessageData = {
|
||||
message: await this.provider.getMarkupSafe(container.container, comment.body)
|
||||
|
||||
@@ -10,14 +10,15 @@
|
||||
import activity from '@hcengineering/activity'
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import { CollaboratorClient } from '@hcengineering/collaborator-client'
|
||||
import contact, { Person } from '@hcengineering/contact'
|
||||
import core, {
|
||||
PersonId,
|
||||
AttachedDoc,
|
||||
Class,
|
||||
Doc,
|
||||
DocumentUpdate,
|
||||
Markup,
|
||||
MeasureContext,
|
||||
PersonId,
|
||||
Ref,
|
||||
Space,
|
||||
Status,
|
||||
@@ -29,7 +30,6 @@ import github, {
|
||||
GithubFieldMapping,
|
||||
GithubIntegrationRepository,
|
||||
GithubIssue,
|
||||
GithubIssue as GithubIssueP,
|
||||
GithubMilestone,
|
||||
GithubProject
|
||||
} from '@hcengineering/github'
|
||||
@@ -138,19 +138,22 @@ export abstract class IssueSyncManagerBase {
|
||||
this.provider = provider
|
||||
}
|
||||
|
||||
async getAssignees (issue: IssueExternalData): Promise<any[]> {
|
||||
// TODO: FIXME
|
||||
throw new Error('Not implemented')
|
||||
async getAssignees (issue: IssueExternalData): Promise<Ref<Person>[]> {
|
||||
// Find Assignees and reviewers
|
||||
// const assignees: PersonAccount[] = []
|
||||
const assignees: PersonId[] = []
|
||||
|
||||
// for (const o of issue.assignees.nodes) {
|
||||
// const acc = await this.provider.getAccount(o)
|
||||
// if (acc !== undefined) {
|
||||
// assignees.push(acc)
|
||||
// }
|
||||
// }
|
||||
// return assignees
|
||||
for (const o of issue.assignees.nodes) {
|
||||
const acc = await this.provider.getAccount(o)
|
||||
if (acc !== undefined) {
|
||||
assignees.push(acc)
|
||||
}
|
||||
}
|
||||
return await this.getPersonsFromId(assignees)
|
||||
}
|
||||
|
||||
async getPersonsFromId (assignees: PersonId[]): Promise<Ref<Person>[]> {
|
||||
const socialIds = await this.client.findAll(contact.class.SocialIdentity, { _id: { $in: assignees as any } })
|
||||
return socialIds.map((it) => it.attachedTo)
|
||||
}
|
||||
|
||||
async processProjectV2Event (
|
||||
@@ -159,7 +162,7 @@ export abstract class IssueSyncManagerBase {
|
||||
derivedClient: TxOperations,
|
||||
prj: GithubProject
|
||||
): Promise<void> {
|
||||
const account = (await this.provider.getAccountU(event.sender))?._id ?? core.account.System
|
||||
const account = (await this.provider.getAccountU(event.sender)) ?? core.account.System
|
||||
switch (event.action) {
|
||||
case 'edited': {
|
||||
const itemId = event.projects_v2_item.node_id
|
||||
@@ -708,263 +711,261 @@ export abstract class IssueSyncManagerBase {
|
||||
accountGH: PersonId,
|
||||
syncToProject: boolean
|
||||
): Promise<DocumentUpdate<DocSyncInfo>> {
|
||||
// TODO: FIXME
|
||||
throw new Error('Not implemented')
|
||||
// let needUpdate = false
|
||||
// if (!this.client.getHierarchy().hasMixin(existing, github.mixin.GithubIssue)) {
|
||||
// await this.ctx.withLog(
|
||||
// 'create mixin issue: GithubIssue',
|
||||
// {},
|
||||
// async () => {
|
||||
// await this.client.createMixin<Issue, GithubIssueP>(
|
||||
// existing._id as Ref<GithubIssueP>,
|
||||
// existing._class,
|
||||
// existing.space,
|
||||
// github.mixin.GithubIssue,
|
||||
// {
|
||||
// githubNumber: issueExternal.number,
|
||||
// url: issueExternal.url,
|
||||
// repository: info.repository as Ref<GithubIntegrationRepository>
|
||||
// }
|
||||
// )
|
||||
// await this.notifyConnected(container, info, existing, issueExternal)
|
||||
// },
|
||||
// { identifier: existing.identifier, url: issueExternal.url }
|
||||
// )
|
||||
// // Re iterate to have existing value with mixin inside.
|
||||
// needUpdate = true
|
||||
// } else {
|
||||
// const ghIssue = this.client.getHierarchy().as(existing, github.mixin.GithubIssue)
|
||||
// await this.client.diffUpdate(ghIssue, {
|
||||
// githubNumber: issueExternal.number,
|
||||
// url: issueExternal.url,
|
||||
// repository: info.repository as Ref<GithubIntegrationRepository>
|
||||
// })
|
||||
// if (ghIssue.url !== issueExternal.url) {
|
||||
// await this.notifyConnected(container, info, existing, issueExternal)
|
||||
// }
|
||||
// }
|
||||
// if (!this.client.getHierarchy().hasMixin(existing, container.project.mixinClass)) {
|
||||
// await this.ctx.withLog(
|
||||
// 'create mixin issue',
|
||||
// {},
|
||||
// () =>
|
||||
// this.client.createMixin<Issue, Issue>(
|
||||
// existing._id as Ref<GithubIssueP>,
|
||||
// existing._class,
|
||||
// existing.space,
|
||||
// container.project.mixinClass,
|
||||
// {}
|
||||
// ),
|
||||
// { identifier: existing.identifier, url: issueExternal.url }
|
||||
// )
|
||||
// // Re iterate to have existing value with mixin inside.
|
||||
// needUpdate = true
|
||||
// }
|
||||
// if (needUpdate) {
|
||||
// return { needSync: '' }
|
||||
// }
|
||||
let needUpdate = false
|
||||
if (!this.client.getHierarchy().hasMixin(existing, github.mixin.GithubIssue)) {
|
||||
await this.ctx.withLog(
|
||||
'create mixin issue: GithubIssue',
|
||||
{},
|
||||
async () => {
|
||||
await this.client.createMixin<Issue, GithubIssue>(
|
||||
existing._id as Ref<GithubIssue>,
|
||||
existing._class,
|
||||
existing.space,
|
||||
github.mixin.GithubIssue,
|
||||
{
|
||||
githubNumber: issueExternal.number,
|
||||
url: issueExternal.url,
|
||||
repository: info.repository as Ref<GithubIntegrationRepository>
|
||||
}
|
||||
)
|
||||
await this.notifyConnected(container, info, existing, issueExternal)
|
||||
},
|
||||
{ identifier: existing.identifier, url: issueExternal.url }
|
||||
)
|
||||
// Re iterate to have existing value with mixin inside.
|
||||
needUpdate = true
|
||||
} else {
|
||||
const ghIssue = this.client.getHierarchy().as(existing, github.mixin.GithubIssue)
|
||||
await this.client.diffUpdate(ghIssue, {
|
||||
githubNumber: issueExternal.number,
|
||||
url: issueExternal.url,
|
||||
repository: info.repository as Ref<GithubIntegrationRepository>
|
||||
})
|
||||
if (ghIssue.url !== issueExternal.url) {
|
||||
await this.notifyConnected(container, info, existing, issueExternal)
|
||||
}
|
||||
}
|
||||
if (!this.client.getHierarchy().hasMixin(existing, container.project.mixinClass)) {
|
||||
await this.ctx.withLog(
|
||||
'create mixin issue',
|
||||
{},
|
||||
() =>
|
||||
this.client.createMixin<Issue, Issue>(
|
||||
existing._id as Ref<GithubIssue>,
|
||||
existing._class,
|
||||
existing.space,
|
||||
container.project.mixinClass,
|
||||
{}
|
||||
),
|
||||
{ identifier: existing.identifier, url: issueExternal.url }
|
||||
)
|
||||
// Re iterate to have existing value with mixin inside.
|
||||
needUpdate = true
|
||||
}
|
||||
if (needUpdate) {
|
||||
return { needSync: '' }
|
||||
}
|
||||
|
||||
// const existingIssue = this.client.getHierarchy().as(existing, container.project.mixinClass)
|
||||
// const previousData: GithubIssueData = info.current ?? ({} as unknown as GithubIssueData)
|
||||
// const type = await this.provider.getTaskTypeOf(container.project.type, existing._class)
|
||||
// const stst = await this.provider.getStatuses(type?._id)
|
||||
const existingIssue = this.client.getHierarchy().as(existing, container.project.mixinClass)
|
||||
const previousData: GithubIssueData = info.current ?? ({} as unknown as GithubIssueData)
|
||||
const type = await this.provider.getTaskTypeOf(container.project.type, existing._class)
|
||||
const stst = await this.provider.getStatuses(type?._id)
|
||||
|
||||
// const update = collectUpdate<Issue>(previousData, issueData, Object.keys(issueData))
|
||||
const update = collectUpdate<Issue>(previousData, issueData, Object.keys(issueData))
|
||||
|
||||
// const allAttributes = this.client.getHierarchy().getAllAttributes(container.project.mixinClass)
|
||||
// const platformUpdate = collectUpdate<Issue>(previousData, existingIssue, Array.from(allAttributes.keys()))
|
||||
const allAttributes = this.client.getHierarchy().getAllAttributes(container.project.mixinClass)
|
||||
const platformUpdate = collectUpdate<Issue>(previousData, existingIssue, Array.from(allAttributes.keys()))
|
||||
|
||||
// const okit = (await this.provider.getOctokit(account as PersonId)) ?? container.container.octokit
|
||||
const okit = (await this.provider.getOctokit(account)) ?? container.container.octokit
|
||||
|
||||
// // Remove current same values from update
|
||||
// for (const [k, v] of Object.entries(update)) {
|
||||
// if ((existingIssue as any)[k] === v) {
|
||||
// // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
// delete (update as any)[k]
|
||||
// }
|
||||
// }
|
||||
// Remove current same values from update
|
||||
for (const [k, v] of Object.entries(update)) {
|
||||
if ((existingIssue as any)[k] === v) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
delete (update as any)[k]
|
||||
}
|
||||
}
|
||||
|
||||
// if (update.description !== undefined) {
|
||||
// if (update.description === existingIssue.description) {
|
||||
// delete update.description
|
||||
// }
|
||||
// }
|
||||
if (update.description !== undefined) {
|
||||
if (update.description === existingIssue.description) {
|
||||
delete update.description
|
||||
}
|
||||
}
|
||||
|
||||
// for (const [k, v] of Object.entries(update)) {
|
||||
// let pv = (platformUpdate as any)[k]
|
||||
for (const [k, v] of Object.entries(update)) {
|
||||
let pv = (platformUpdate as any)[k]
|
||||
|
||||
// if (k === 'description' && pv != null) {
|
||||
// const mdown = await this.provider.getMarkdown(pv)
|
||||
// pv = await this.provider.getMarkupSafe(container.container, mdown, this.stripGuestLink)
|
||||
// }
|
||||
// if (pv != null && pv !== v) {
|
||||
// // We have conflict of values, assume platform is more proper one.
|
||||
// this.ctx.error('conflict', { id: existing.identifier, k })
|
||||
// // Assume platform change is more important in case of conflict values.
|
||||
// // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
// delete (update as any)[k]
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
if (k === 'description' && pv != null) {
|
||||
const mdown = await this.provider.getMarkdown(pv)
|
||||
pv = await this.provider.getMarkupSafe(container.container, mdown, this.stripGuestLink)
|
||||
}
|
||||
if (pv != null && pv !== v) {
|
||||
// We have conflict of values, assume platform is more proper one.
|
||||
this.ctx.error('conflict', { id: existing.identifier, k })
|
||||
// Assume platform change is more important in case of conflict values.
|
||||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
delete (update as any)[k]
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// await this.fillBackChanges(update, existingIssue, issueExternal)
|
||||
await this.fillBackChanges(update, existingIssue, issueExternal)
|
||||
|
||||
// let needExternalSync = false
|
||||
let needExternalSync = false
|
||||
|
||||
// if (container !== undefined && okit !== undefined) {
|
||||
// // Check and update issue fields.
|
||||
// needExternalSync = await this.performIssueFieldsUpdate(
|
||||
// info,
|
||||
// existing,
|
||||
// platformUpdate,
|
||||
// issueData,
|
||||
// container,
|
||||
// issueExternal,
|
||||
// okit,
|
||||
// account
|
||||
// )
|
||||
if (container !== undefined && okit !== undefined) {
|
||||
// Check and update issue fields.
|
||||
needExternalSync = await this.performIssueFieldsUpdate(
|
||||
info,
|
||||
existing,
|
||||
platformUpdate,
|
||||
issueData,
|
||||
container,
|
||||
issueExternal,
|
||||
okit,
|
||||
account
|
||||
)
|
||||
|
||||
// const fieldsUpdate: { id: string, value: any, dataType: GithubDataType }[] = []
|
||||
const fieldsUpdate: { id: string, value: any, dataType: GithubDataType }[] = []
|
||||
|
||||
// // Collect field update.
|
||||
// for (const [k, v] of Object.entries(platformUpdate)) {
|
||||
// const mapping = target.mappings.filter((it) => it != null).find((it) => it.name === k)
|
||||
// if (mapping === undefined) {
|
||||
// continue
|
||||
// }
|
||||
// const attr = this.client.getHierarchy().getAttribute(mapping._class, mapping.name)
|
||||
// Collect field update.
|
||||
for (const [k, v] of Object.entries(platformUpdate)) {
|
||||
const mapping = target.mappings.filter((it) => it != null).find((it) => it.name === k)
|
||||
if (mapping === undefined) {
|
||||
continue
|
||||
}
|
||||
const attr = this.client.getHierarchy().getAttribute(mapping._class, mapping.name)
|
||||
|
||||
// if (attr.name === 'status') {
|
||||
// // Handle status field
|
||||
// const status = stst.find((it) => it._id === v) as Status
|
||||
// const optionId = this.findOptionId(container, mapping.githubId, status.name, target)
|
||||
// if (optionId !== undefined) {
|
||||
// fieldsUpdate.push({
|
||||
// id: mapping.githubId,
|
||||
// dataType: 'SINGLE_SELECT',
|
||||
// value: optionId
|
||||
// })
|
||||
// this.ctx.info(' => prepare issue status update', {
|
||||
// url: issueExternal.url,
|
||||
// name: status.name,
|
||||
// workspace: this.provider.getWorkspaceId()
|
||||
// })
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
// if (attr.name === 'priority') {
|
||||
// const values: Record<IssuePriority, string> = {
|
||||
// [IssuePriority.NoPriority]: '',
|
||||
// [IssuePriority.High]: 'High',
|
||||
// [IssuePriority.Medium]: 'Medium',
|
||||
// [IssuePriority.Low]: 'Low',
|
||||
// [IssuePriority.Urgent]: 'Urgent'
|
||||
// }
|
||||
// // Handle priority field TODO: Add clear of field
|
||||
// const priorityName = values[v as IssuePriority]
|
||||
// const optionId = this.findOptionId(container, mapping.githubId, priorityName, target)
|
||||
// if (optionId !== undefined) {
|
||||
// fieldsUpdate.push({
|
||||
// id: mapping.githubId,
|
||||
// dataType: 'SINGLE_SELECT',
|
||||
// value: optionId
|
||||
// })
|
||||
// this.ctx.info(' => prepare issue priority update', {
|
||||
// url: issueExternal.url,
|
||||
// priority: priorityName,
|
||||
// workspace: this.provider.getWorkspaceId()
|
||||
// })
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
if (attr.name === 'status') {
|
||||
// Handle status field
|
||||
const status = stst.find((it) => it._id === v) as Status
|
||||
const optionId = this.findOptionId(container, mapping.githubId, status.name, target)
|
||||
if (optionId !== undefined) {
|
||||
fieldsUpdate.push({
|
||||
id: mapping.githubId,
|
||||
dataType: 'SINGLE_SELECT',
|
||||
value: optionId
|
||||
})
|
||||
this.ctx.info(' => prepare issue status update', {
|
||||
url: issueExternal.url,
|
||||
name: status.name,
|
||||
workspace: this.provider.getWorkspaceId()
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
if (attr.name === 'priority') {
|
||||
const values: Record<IssuePriority, string> = {
|
||||
[IssuePriority.NoPriority]: '',
|
||||
[IssuePriority.High]: 'High',
|
||||
[IssuePriority.Medium]: 'Medium',
|
||||
[IssuePriority.Low]: 'Low',
|
||||
[IssuePriority.Urgent]: 'Urgent'
|
||||
}
|
||||
// Handle priority field TODO: Add clear of field
|
||||
const priorityName = values[v as IssuePriority]
|
||||
const optionId = this.findOptionId(container, mapping.githubId, priorityName, target)
|
||||
if (optionId !== undefined) {
|
||||
fieldsUpdate.push({
|
||||
id: mapping.githubId,
|
||||
dataType: 'SINGLE_SELECT',
|
||||
value: optionId
|
||||
})
|
||||
this.ctx.info(' => prepare issue priority update', {
|
||||
url: issueExternal.url,
|
||||
priority: priorityName,
|
||||
workspace: this.provider.getWorkspaceId()
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// const dataType = getType(attr)
|
||||
// if (dataType === 'SINGLE_SELECT') {
|
||||
// // Handle status field
|
||||
// const optionId = this.findOptionId(container, mapping.githubId, v, target)
|
||||
// if (optionId !== undefined) {
|
||||
// fieldsUpdate.push({
|
||||
// id: mapping.githubId,
|
||||
// dataType: 'SINGLE_SELECT',
|
||||
// value: optionId
|
||||
// })
|
||||
// this.ctx.info(` => prepare issue field ${attr.label} update`, {
|
||||
// url: issueExternal.url,
|
||||
// value: v,
|
||||
// workspace: this.provider.getWorkspaceId()
|
||||
// })
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
const dataType = getType(attr)
|
||||
if (dataType === 'SINGLE_SELECT') {
|
||||
// Handle status field
|
||||
const optionId = this.findOptionId(container, mapping.githubId, v, target)
|
||||
if (optionId !== undefined) {
|
||||
fieldsUpdate.push({
|
||||
id: mapping.githubId,
|
||||
dataType: 'SINGLE_SELECT',
|
||||
value: optionId
|
||||
})
|
||||
this.ctx.info(` => prepare issue field ${attr.label} update`, {
|
||||
url: issueExternal.url,
|
||||
value: v,
|
||||
workspace: this.provider.getWorkspaceId()
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// if (dataType === undefined) {
|
||||
// continue
|
||||
// }
|
||||
// fieldsUpdate.push({
|
||||
// id: mapping.githubId,
|
||||
// dataType,
|
||||
// value: v
|
||||
// })
|
||||
// this.ctx.info(`=> prepare issue field ${attr.label} update`, {
|
||||
// url: issueExternal.url,
|
||||
// value: v,
|
||||
// workspace: this.provider.getWorkspaceId()
|
||||
// })
|
||||
// }
|
||||
// if (fieldsUpdate.length > 0 && syncToProject && target.prjData !== undefined) {
|
||||
// const errors = await this.updateIssueValues(target, okit, fieldsUpdate)
|
||||
// if (errors.length === 0) {
|
||||
// needExternalSync = true
|
||||
// }
|
||||
// }
|
||||
// // TODO: Add support for labels, milestone, assignees
|
||||
// }
|
||||
if (dataType === undefined) {
|
||||
continue
|
||||
}
|
||||
fieldsUpdate.push({
|
||||
id: mapping.githubId,
|
||||
dataType,
|
||||
value: v
|
||||
})
|
||||
this.ctx.info(`=> prepare issue field ${attr.label} update`, {
|
||||
url: issueExternal.url,
|
||||
value: v,
|
||||
workspace: this.provider.getWorkspaceId()
|
||||
})
|
||||
}
|
||||
if (fieldsUpdate.length > 0 && syncToProject && target.prjData !== undefined) {
|
||||
const errors = await this.updateIssueValues(target, okit, fieldsUpdate)
|
||||
if (errors.length === 0) {
|
||||
needExternalSync = true
|
||||
}
|
||||
}
|
||||
// TODO: Add support for labels, milestone, assignees
|
||||
}
|
||||
|
||||
// // We need remove all readonly field values
|
||||
// for (const k of Object.keys(update)) {
|
||||
// // Skip readonly fields
|
||||
// const attr = this.client.getHierarchy().findAttribute(target.project.mixinClass, k)
|
||||
// if (attr?.readonly === true) {
|
||||
// // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
// delete (update as any)[k]
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
// We need remove all readonly field values
|
||||
for (const k of Object.keys(update)) {
|
||||
// Skip readonly fields
|
||||
const attr = this.client.getHierarchy().findAttribute(target.project.mixinClass, k)
|
||||
if (attr?.readonly === true) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
delete (update as any)[k]
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// // Update collaborative description
|
||||
// if (update.description !== undefined) {
|
||||
// this.ctx.info(`<= perform ${issueExternal.url} update to collaborator`, {
|
||||
// workspace: this.provider.getWorkspaceId()
|
||||
// })
|
||||
// try {
|
||||
// const description = update.description as Markup
|
||||
// issueData.description = description
|
||||
// const collabId = makeDocCollabId(existingIssue, 'description')
|
||||
// await this.collaborator.updateMarkup(collabId, description)
|
||||
// } catch (err: any) {
|
||||
// Analytics.handleError(err)
|
||||
// this.ctx.error('error during description update', err)
|
||||
// }
|
||||
// }
|
||||
// Update collaborative description
|
||||
if (update.description !== undefined) {
|
||||
this.ctx.info(`<= perform ${issueExternal.url} update to collaborator`, {
|
||||
workspace: this.provider.getWorkspaceId()
|
||||
})
|
||||
try {
|
||||
const description = update.description as Markup
|
||||
issueData.description = description
|
||||
const collabId = makeDocCollabId(existingIssue, 'description')
|
||||
await this.collaborator.updateMarkup(collabId, description)
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
this.ctx.error('error during description update', err)
|
||||
}
|
||||
}
|
||||
|
||||
// if (Object.keys(update).length > 0) {
|
||||
// // We have some fields to update of existing from external
|
||||
// this.ctx.info(`<= perform ${issueExternal.url} update to platform`, {
|
||||
// ...update,
|
||||
// workspace: this.provider.getWorkspaceId()
|
||||
// })
|
||||
// await this.client.update(existingIssue, update, false, new Date().getTime(), accountGH)
|
||||
// }
|
||||
if (Object.keys(update).length > 0) {
|
||||
// We have some fields to update of existing from external
|
||||
this.ctx.info(`<= perform ${issueExternal.url} update to platform`, {
|
||||
...update,
|
||||
workspace: this.provider.getWorkspaceId()
|
||||
})
|
||||
await this.client.update(existingIssue, update, false, new Date().getTime(), accountGH)
|
||||
}
|
||||
|
||||
// await this.afterSync(existingIssue, accountGH, issueExternal, info)
|
||||
// // We need to trigger external version retrieval, via sync or event, to prevent move sync operations from platform before we will be sure all is updated on github.
|
||||
// return {
|
||||
// current: issueData,
|
||||
// needSync: githubSyncVersion,
|
||||
// ...(needExternalSync ? { externalVersion: '' } : {}),
|
||||
// lastGithubUser: null
|
||||
// }
|
||||
await this.afterSync(existingIssue, accountGH, issueExternal, info)
|
||||
// We need to trigger external version retrieval, via sync or event, to prevent move sync operations from platform before we will be sure all is updated on github.
|
||||
return {
|
||||
current: issueData,
|
||||
needSync: githubSyncVersion,
|
||||
...(needExternalSync ? { externalVersion: '' } : {}),
|
||||
lastGithubUser: null
|
||||
}
|
||||
}
|
||||
|
||||
private async notifyConnected (
|
||||
@@ -997,83 +998,81 @@ export abstract class IssueSyncManagerBase {
|
||||
issueExternal: IssueExternalData,
|
||||
_class: Ref<Class<Issue>>
|
||||
): Promise<Record<string, any>> {
|
||||
// TODO: FIXME
|
||||
throw new Error('Not implemented')
|
||||
// const issueUpdate: {
|
||||
// title?: string
|
||||
// body?: string
|
||||
// stateReason?: string
|
||||
// assigneeIds?: string[]
|
||||
// } & Record<string, any> = {}
|
||||
// if (platformUpdate.title != null) {
|
||||
// if (platformUpdate.title !== issueExternal.title) {
|
||||
// issueUpdate.title = platformUpdate.title
|
||||
// }
|
||||
// issueData.title = platformUpdate.title
|
||||
// }
|
||||
// if (platformUpdate.description != null) {
|
||||
// // Need to convert to markdown
|
||||
// issueUpdate.body = await this.provider.getMarkdown(platformUpdate.description ?? '')
|
||||
// issueData.description = await this.provider.getMarkupSafe(
|
||||
// container.container,
|
||||
// issueUpdate.body ?? '',
|
||||
// this.stripGuestLink
|
||||
// )
|
||||
const issueUpdate: {
|
||||
title?: string
|
||||
body?: string
|
||||
stateReason?: string
|
||||
assigneeIds?: string[]
|
||||
} & Record<string, any> = {}
|
||||
if (platformUpdate.title != null) {
|
||||
if (platformUpdate.title !== issueExternal.title) {
|
||||
issueUpdate.title = platformUpdate.title
|
||||
}
|
||||
issueData.title = platformUpdate.title
|
||||
}
|
||||
if (platformUpdate.description != null) {
|
||||
// Need to convert to markdown
|
||||
issueUpdate.body = await this.provider.getMarkdown(platformUpdate.description ?? '')
|
||||
issueData.description = await this.provider.getMarkupSafe(
|
||||
container.container,
|
||||
issueUpdate.body ?? '',
|
||||
this.stripGuestLink
|
||||
)
|
||||
|
||||
// // Of value is same, not need to update.
|
||||
// if (compareMarkdown(issueUpdate.body, issueExternal.body)) {
|
||||
// delete issueUpdate.body
|
||||
// }
|
||||
// }
|
||||
// if (platformUpdate.assignee !== undefined) {
|
||||
// const info =
|
||||
// platformUpdate.assignee !== null
|
||||
// ? await this.provider.getGithubLogin(container.container, platformUpdate.assignee)
|
||||
// : undefined
|
||||
// // Check external
|
||||
// Of value is same, not need to update.
|
||||
if (compareMarkdown(issueUpdate.body, issueExternal.body)) {
|
||||
delete issueUpdate.body
|
||||
}
|
||||
}
|
||||
if (platformUpdate.assignee !== undefined) {
|
||||
const info =
|
||||
platformUpdate.assignee !== null
|
||||
? await this.provider.getGithubLogin(container.container, platformUpdate.assignee)
|
||||
: undefined
|
||||
// Check external
|
||||
|
||||
// const currentAssignees = issueExternal.assignees.nodes.map((it) => it.id)
|
||||
// currentAssignees.sort((a, b) => a.localeCompare(b))
|
||||
const currentAssignees = issueExternal.assignees.nodes.map((it) => it.id)
|
||||
currentAssignees.sort((a, b) => a.localeCompare(b))
|
||||
|
||||
// issueUpdate.assigneeIds = info !== undefined ? [info.id] : []
|
||||
// issueUpdate.assigneeIds.sort((a, b) => a.localeCompare(b))
|
||||
issueUpdate.assigneeIds = info !== undefined ? [info.id] : []
|
||||
issueUpdate.assigneeIds.sort((a, b) => a.localeCompare(b))
|
||||
|
||||
// if (deepEqual(currentAssignees, issueUpdate.assigneeIds)) {
|
||||
// // Same ids
|
||||
// delete issueUpdate.assigneeIds
|
||||
// }
|
||||
// issueData.assignee = platformUpdate.assignee
|
||||
// }
|
||||
if (deepEqual(currentAssignees, issueUpdate.assigneeIds)) {
|
||||
// Same ids
|
||||
delete issueUpdate.assigneeIds
|
||||
}
|
||||
issueData.assignee = platformUpdate.assignee
|
||||
}
|
||||
|
||||
// const status = platformUpdate.status ?? issueData.status
|
||||
// const type = await this.provider.getTaskTypeOf(container.project.type, _class)
|
||||
// const statuses = await this.provider.getStatuses(type?._id)
|
||||
// const st = statuses.find((it) => it._id === status)
|
||||
// if (st !== undefined) {
|
||||
// // Need to convert to two operations.
|
||||
// switch (st.category) {
|
||||
// case task.statusCategory.UnStarted:
|
||||
// case task.statusCategory.ToDo:
|
||||
// case task.statusCategory.Active:
|
||||
// if (issueExternal.state !== 'OPEN') {
|
||||
// issueUpdate.state = 'OPEN'
|
||||
// }
|
||||
// break
|
||||
// case task.statusCategory.Won:
|
||||
// if (issueExternal.state !== 'CLOSED' || issueExternal.stateReason !== 'COMPLETED') {
|
||||
// issueUpdate.state = 'CLOSED'
|
||||
// issueUpdate.stateReason = 'COMPLETED'
|
||||
// }
|
||||
// break
|
||||
// case task.statusCategory.Lost:
|
||||
// if (issueExternal.state !== 'CLOSED' || issueExternal.stateReason !== 'NOT_PLANNED') {
|
||||
// issueUpdate.state = 'CLOSED'
|
||||
// issueUpdate.stateReason = 'not_planed' // Not supported change to github
|
||||
// }
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// return issueUpdate
|
||||
const status = platformUpdate.status ?? issueData.status
|
||||
const type = await this.provider.getTaskTypeOf(container.project.type, _class)
|
||||
const statuses = await this.provider.getStatuses(type?._id)
|
||||
const st = statuses.find((it) => it._id === status)
|
||||
if (st !== undefined) {
|
||||
// Need to convert to two operations.
|
||||
switch (st.category) {
|
||||
case task.statusCategory.UnStarted:
|
||||
case task.statusCategory.ToDo:
|
||||
case task.statusCategory.Active:
|
||||
if (issueExternal.state !== 'OPEN') {
|
||||
issueUpdate.state = 'OPEN'
|
||||
}
|
||||
break
|
||||
case task.statusCategory.Won:
|
||||
if (issueExternal.state !== 'CLOSED' || issueExternal.stateReason !== 'COMPLETED') {
|
||||
issueUpdate.state = 'CLOSED'
|
||||
issueUpdate.stateReason = 'COMPLETED'
|
||||
}
|
||||
break
|
||||
case task.statusCategory.Lost:
|
||||
if (issueExternal.state !== 'CLOSED' || issueExternal.stateReason !== 'NOT_PLANNED') {
|
||||
issueUpdate.state = 'CLOSED'
|
||||
issueUpdate.stateReason = 'not_planed' // Not supported change to github
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return issueUpdate
|
||||
}
|
||||
|
||||
async syncIssues (
|
||||
@@ -1219,9 +1218,8 @@ export abstract class IssueSyncManagerBase {
|
||||
// No external issue yet, safe delete, since platform document will be deleted a well.
|
||||
return true
|
||||
}
|
||||
const account =
|
||||
existing?.createdBy ?? (await this.provider.getAccount(issueExternal.author))?._id ?? core.account.System
|
||||
const okit = (await this.provider.getOctokit(account as PersonId)) ?? container.container.octokit
|
||||
const account = existing?.createdBy ?? (await this.provider.getAccount(issueExternal.author)) ?? core.account.System
|
||||
const okit = (await this.provider.getOctokit(account)) ?? container.container.octokit
|
||||
|
||||
if (existing !== undefined && issueExternal !== undefined) {
|
||||
let target = await this.getMilestoneIssueTarget(
|
||||
|
||||
@@ -52,19 +52,17 @@ import { getSince, gqlp, guessStatus, isGHWriteAllowed, syncRunner } from './uti
|
||||
export class IssueSyncManager extends IssueSyncManagerBase implements DocSyncManager {
|
||||
createPromise: Promise<IssueExternalData | undefined> | undefined
|
||||
externalDerivedSync = false
|
||||
async getAssigneesI (issue: GithubIssue): Promise<any[]> {
|
||||
// TODO: FIXME
|
||||
throw new Error('Not implemented')
|
||||
async getAssigneesI (issue: GithubIssue): Promise<PersonId[]> {
|
||||
// Find Assignees and reviewers
|
||||
// const assignees: PersonAccount[] = []
|
||||
const assignees: PersonId[] = []
|
||||
|
||||
// for (const o of issue.assignees) {
|
||||
// const acc = await this.provider.getAccountU(o)
|
||||
// if (acc !== undefined) {
|
||||
// assignees.push(acc)
|
||||
// }
|
||||
// }
|
||||
// return assignees
|
||||
for (const o of issue.assignees) {
|
||||
const acc = await this.provider.getAccountU(o)
|
||||
if (acc !== undefined) {
|
||||
assignees.push(acc)
|
||||
}
|
||||
}
|
||||
return assignees
|
||||
}
|
||||
|
||||
async handleEvent<T = IssuesEvent | ProjectsV2ItemEvent>(
|
||||
@@ -150,7 +148,7 @@ export class IssueSyncManager extends IssueSyncManagerBase implements DocSyncMan
|
||||
integration: IntegrationContainer,
|
||||
prj: GithubProject
|
||||
): Promise<void> {
|
||||
const account = (await this.provider.getAccountU(event.sender))?._id ?? core.account.System
|
||||
const account = (await this.provider.getAccountU(event.sender)) ?? core.account.System
|
||||
|
||||
let externalData: IssueExternalData | undefined
|
||||
if (event.action !== 'deleted') {
|
||||
@@ -243,8 +241,9 @@ export class IssueSyncManager extends IssueSyncManagerBase implements DocSyncMan
|
||||
case 'assigned':
|
||||
case 'unassigned': {
|
||||
const assignees = await this.getAssigneesI(event.issue)
|
||||
const persons = await this.getPersonsFromId(assignees)
|
||||
const update: IssueUpdate = {
|
||||
assignee: assignees?.[0]?.person ?? null
|
||||
assignee: persons?.[0] ?? null
|
||||
}
|
||||
await this.handleUpdate(externalData as IssueExternalData, derivedClient, update, account, prj, false)
|
||||
break
|
||||
@@ -481,9 +480,9 @@ export class IssueSyncManager extends IssueSyncManagerBase implements DocSyncMan
|
||||
info: DocSyncInfo
|
||||
): Promise<DocumentUpdate<DocSyncInfo>> {
|
||||
const account =
|
||||
existing?.modifiedBy ?? (await this.provider.getAccount(issueExternal.author))?._id ?? core.account.System
|
||||
existing?.modifiedBy ?? (await this.provider.getAccount(issueExternal.author)) ?? core.account.System
|
||||
const accountGH =
|
||||
info.lastGithubUser ?? (await this.provider.getAccount(issueExternal.author))?._id ?? core.account.System
|
||||
info.lastGithubUser ?? (await this.provider.getAccount(issueExternal.author)) ?? core.account.System
|
||||
|
||||
const isProjectProjectTarget = target.target.projectNodeId === target.project.projectNodeId
|
||||
const supportProjects =
|
||||
@@ -492,7 +491,7 @@ export class IssueSyncManager extends IssueSyncManagerBase implements DocSyncMan
|
||||
// A target node id
|
||||
const targetNodeId: string | undefined = info.targetNodeId as string
|
||||
|
||||
const okit = (await this.provider.getOctokit(account as PersonId)) ?? container.container.octokit
|
||||
const okit = (await this.provider.getOctokit(account)) ?? container.container.octokit
|
||||
|
||||
const type = await this.provider.getTaskTypeOf(container.project.type, tracker.class.Issue)
|
||||
const statuses = await this.provider.getStatuses(type?._id)
|
||||
@@ -502,7 +501,7 @@ export class IssueSyncManager extends IssueSyncManagerBase implements DocSyncMan
|
||||
const issueData = {
|
||||
title: issueExternal.title,
|
||||
description: await this.provider.getMarkupSafe(container.container, issueExternal.body, this.stripGuestLink),
|
||||
assignee: assignees[0]?.person,
|
||||
assignee: assignees[0],
|
||||
repository: info.repository,
|
||||
remainingTime: 0
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import { Person } from '@hcengineering/contact'
|
||||
import core, {
|
||||
PersonId,
|
||||
AttachedData,
|
||||
Doc,
|
||||
DocumentUpdate,
|
||||
PersonId,
|
||||
Ref,
|
||||
SortingOrder,
|
||||
Status,
|
||||
@@ -41,10 +41,10 @@ import {
|
||||
DocSyncManager,
|
||||
ExternalSyncField,
|
||||
IntegrationContainer,
|
||||
UserInfo,
|
||||
githubDerivedSyncVersion,
|
||||
githubExternalSyncVersion,
|
||||
githubSyncVersion
|
||||
githubSyncVersion,
|
||||
type UserInfo
|
||||
} from '../types'
|
||||
import {
|
||||
IssueExternalData,
|
||||
@@ -154,7 +154,7 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS
|
||||
integration: IntegrationContainer,
|
||||
prj: GithubProject
|
||||
): Promise<void> {
|
||||
const account = (await this.provider.getAccountU(event.sender))?._id ?? core.account.System
|
||||
const account = (await this.provider.getAccountU(event.sender)) ?? core.account.System
|
||||
|
||||
let externalData: PullRequestExternalData
|
||||
try {
|
||||
@@ -243,7 +243,7 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS
|
||||
case 'unassigned': {
|
||||
const assignees = await this.getAssignees(externalData)
|
||||
const update: GithubPullRequestUpdate = {
|
||||
assignee: assignees?.[0]?.person ?? null
|
||||
assignee: assignees?.[0] ?? null
|
||||
}
|
||||
await this.handleUpdate(externalData, derivedClient, update, account, prj, true)
|
||||
break
|
||||
@@ -326,27 +326,27 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS
|
||||
}
|
||||
}
|
||||
|
||||
// async getReviewers (issue: PullRequestExternalData): Promise<PersonAccount[]> {
|
||||
// // Find Assignees and reviewers
|
||||
// const ids: UserInfo[] = issue.reviewRequests.nodes.map((it: any) => it.requestedReviewer)
|
||||
async getReviewers (issue: PullRequestExternalData): Promise<PersonId[]> {
|
||||
// Find Assignees and reviewers
|
||||
const ids: UserInfo[] = issue.reviewRequests.nodes.map((it: any) => it.requestedReviewer)
|
||||
|
||||
// const values: PersonAccount[] = []
|
||||
const values: PersonId[] = []
|
||||
|
||||
// for (const o of ids) {
|
||||
// const acc = await this.provider.getAccount(o)
|
||||
// if (acc !== undefined) {
|
||||
// values.push(acc)
|
||||
// }
|
||||
// }
|
||||
for (const o of ids) {
|
||||
const acc = await this.provider.getAccount(o)
|
||||
if (acc !== undefined) {
|
||||
values.push(acc)
|
||||
}
|
||||
}
|
||||
|
||||
// for (const n of issue.latestReviews.nodes) {
|
||||
// const acc = await this.provider.getAccount(n.author)
|
||||
// if (acc !== undefined) {
|
||||
// values.push(acc)
|
||||
// }
|
||||
// }
|
||||
// return values
|
||||
// }
|
||||
for (const n of issue.latestReviews.nodes) {
|
||||
const acc = await this.provider.getAccount(n.author)
|
||||
if (acc !== undefined) {
|
||||
values.push(acc)
|
||||
}
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
private async createSyncData (
|
||||
pullRequestExternal: PullRequestExternalData,
|
||||
@@ -387,14 +387,14 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS
|
||||
info: DocSyncInfo
|
||||
): Promise<DocumentUpdate<DocSyncInfo>> {
|
||||
const account =
|
||||
existing?.modifiedBy ?? (await this.provider.getAccount(pullRequestExternal.author))?._id ?? core.account.System
|
||||
existing?.modifiedBy ?? (await this.provider.getAccount(pullRequestExternal.author)) ?? core.account.System
|
||||
const accountGH =
|
||||
info.lastGithubUser ?? (await this.provider.getAccount(pullRequestExternal.author))?._id ?? core.account.System
|
||||
info.lastGithubUser ?? (await this.provider.getAccount(pullRequestExternal.author)) ?? core.account.System
|
||||
|
||||
// A target node id
|
||||
const targetNodeId: string | undefined = info.targetNodeId as string
|
||||
|
||||
const okit = (await this.provider.getOctokit(account as PersonId)) ?? container.container.octokit
|
||||
const okit = (await this.provider.getOctokit(account)) ?? container.container.octokit
|
||||
|
||||
const isProjectProjectTarget = target.target.projectNodeId === target.project.projectNodeId
|
||||
const supportProjects =
|
||||
@@ -452,13 +452,12 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS
|
||||
}
|
||||
|
||||
const assignees = await this.getAssignees(pullRequestExternal)
|
||||
// TODO: FIXME
|
||||
const reviewers: any = [] // await this.getReviewers(pullRequestExternal)
|
||||
const reviewers: PersonId[] = await this.getReviewers(pullRequestExternal)
|
||||
|
||||
const latestReviews: LastReviewState[] = []
|
||||
|
||||
for (const d of pullRequestExternal.latestReviews?.nodes ?? []) {
|
||||
const author = (await this.provider.getAccount(d.author))?._id
|
||||
const author = await this.provider.getAccount(d.author)
|
||||
if (author !== undefined) {
|
||||
latestReviews.push({
|
||||
state: toReviewState(d.state),
|
||||
@@ -473,7 +472,7 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS
|
||||
pullRequestExternal.body,
|
||||
this.stripGuestLink
|
||||
),
|
||||
assignee: assignees[0]?.person ?? null,
|
||||
assignee: assignees[0] ?? null,
|
||||
reviewers: reviewers.map((it: any) => it.person),
|
||||
draft: pullRequestExternal.isDraft,
|
||||
head: pullRequestExternal.headRef,
|
||||
@@ -706,10 +705,10 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS
|
||||
}
|
||||
}
|
||||
|
||||
const pendingOrDismissed = new Map<Ref<Person>, PullRequestReviewState>()
|
||||
const pendingOrDismissedIds = new Map<PersonId, PullRequestReviewState>()
|
||||
|
||||
const approvedOrChangesRequested = new Map<Ref<Person>, PullRequestReviewState>()
|
||||
const reviewStates = new Map<Ref<Person>, PullRequestReviewState[]>()
|
||||
const approvedOrChangesRequested = new Map<PersonId, PullRequestReviewState>()
|
||||
const reviewStates = new Map<PersonId, PullRequestReviewState[]>()
|
||||
|
||||
const sortedReviews: (Review & { date: number })[] = external.reviews.nodes
|
||||
.filter((it) => it != null)
|
||||
@@ -734,14 +733,18 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS
|
||||
continue
|
||||
}
|
||||
if (r.state === 'PENDING' || r.state === 'DISMISSED') {
|
||||
pendingOrDismissed.set(rp.person, r.state)
|
||||
pendingOrDismissedIds.set(rp, r.state)
|
||||
}
|
||||
if (r.state === 'APPROVED' || r.state === 'CHANGES_REQUESTED') {
|
||||
approvedOrChangesRequested.set(rp.person, r.state)
|
||||
approvedOrChangesRequested.set(rp, r.state)
|
||||
}
|
||||
reviewStates.set(rp.person, [...(reviewStates.get(rp.person) ?? []), r.state])
|
||||
reviewStates.set(rp, [...(reviewStates.get(rp) ?? []), r.state])
|
||||
}
|
||||
|
||||
const pendingOrDismissed = new Set(
|
||||
await this.getPersonsFromId(Array.from(pendingOrDismissedIds.entries()).map((it) => it[0]))
|
||||
)
|
||||
|
||||
for (const r of pullRequest.reviewers ?? []) {
|
||||
// Find all related todos's
|
||||
const todos = [...allTodos, ...removedTodos].filter((it) => it.user === r && it.purpose === 'review')
|
||||
@@ -750,10 +753,7 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS
|
||||
const hasPending = todos.some((it) => it.doneOn !== null)
|
||||
|
||||
// Create review Todo, if missing.
|
||||
if (
|
||||
pullRequest.state === GithubPullRequestState.open ||
|
||||
(!hasPending && pendingOrDismissed.get(r) !== undefined)
|
||||
) {
|
||||
if (pullRequest.state === GithubPullRequestState.open || (!hasPending && pendingOrDismissed.has(r))) {
|
||||
if (todos.length === 0) {
|
||||
await this.requestReview(client, pullRequest, external, r, account)
|
||||
}
|
||||
@@ -763,26 +763,28 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS
|
||||
// Handle change requests.
|
||||
// If we have change requests pending, we need to create Todo to resolve them to author or assigned person, to resolve them.
|
||||
|
||||
const changeRequestPersons = new Set<Ref<Person>>()
|
||||
const changeRequestPersonsIds = new Set<PersonId>()
|
||||
const author = await this.provider.getAccount(external.author)
|
||||
if (author !== undefined) {
|
||||
changeRequestPersons.add(author.person)
|
||||
changeRequestPersonsIds.add(author)
|
||||
}
|
||||
for (const au of external.assignees.nodes ?? []) {
|
||||
const u = await this.provider.getAccount(au)
|
||||
if (u !== undefined) {
|
||||
changeRequestPersons.add(u.person)
|
||||
changeRequestPersonsIds.add(u)
|
||||
}
|
||||
}
|
||||
|
||||
// Check review threads and create todo to resolve them.
|
||||
const requestedIds: Ref<Person>[] = []
|
||||
|
||||
const changeRequestPersons = await this.getPersonsFromId(Array.from(changeRequestPersonsIds))
|
||||
|
||||
let allResolved = true
|
||||
for (const r of external.reviewThreads.nodes) {
|
||||
if (!r.isResolved) {
|
||||
allResolved = false
|
||||
for (const c of Array.from(changeRequestPersons)) {
|
||||
for (const c of changeRequestPersons) {
|
||||
// We need to add Todo to resolve PR.
|
||||
const todos = [...allTodos, ...removedTodos].filter((it) => it.user === c && it.purpose === 'fix')
|
||||
if (todos.length === 0) {
|
||||
@@ -801,7 +803,7 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS
|
||||
for (const [, sst] of approvedOrChangesRequested.entries()) {
|
||||
if (sst === 'CHANGES_REQUESTED') {
|
||||
// We have changes requested and not resolved yet.
|
||||
for (const c of Array.from(changeRequestPersons)) {
|
||||
for (const c of changeRequestPersons) {
|
||||
const todos = [...allTodos, ...removedTodos].filter((it) => it.user === c && it.purpose === 'fix')
|
||||
if (todos.length === 0 && !requestedIds.includes(c)) {
|
||||
requestedIds.push(c)
|
||||
|
||||
@@ -105,7 +105,7 @@ export class RepositorySyncMapper implements DocSyncManager {
|
||||
async handleEvent<T>(integration: IntegrationContainer, derivedClient: TxOperations, evt: T): Promise<void> {
|
||||
const event = evt as RepositoryEvent
|
||||
|
||||
const account = (await this.provider.getAccountU(event.sender))?._id ?? core.account.System
|
||||
const account = (await this.provider.getAccountU(event.sender)) ?? core.account.System
|
||||
switch (event.action) {
|
||||
case 'created': {
|
||||
await this.client.addCollection(
|
||||
|
||||
@@ -113,7 +113,7 @@ export class ReviewCommentSyncManager implements DocSyncManager {
|
||||
return true
|
||||
}
|
||||
const account =
|
||||
existing?.createdBy ?? (await this.provider.getAccountU(commentExternal.user))?._id ?? core.account.System
|
||||
existing?.createdBy ?? (await this.provider.getAccountU(commentExternal.user)) ?? core.account.System
|
||||
|
||||
if (commentExternal !== undefined) {
|
||||
try {
|
||||
@@ -177,7 +177,7 @@ export class ReviewCommentSyncManager implements DocSyncManager {
|
||||
repo: GithubIntegrationRepository,
|
||||
integration: IntegrationContainer
|
||||
): Promise<void> {
|
||||
const account = (await this.provider.getAccountU(event.sender))?._id ?? core.account.System
|
||||
const account = (await this.provider.getAccountU(event.sender)) ?? core.account.System
|
||||
|
||||
let externalData: ReviewCommentExternalData
|
||||
try {
|
||||
@@ -329,7 +329,7 @@ export class ReviewCommentSyncManager implements DocSyncManager {
|
||||
const reviewComment = info.external as ReviewCommentExternalData
|
||||
|
||||
const account =
|
||||
existing?.modifiedBy ?? (await this.provider.getAccount(reviewComment.author))?._id ?? core.account.System
|
||||
existing?.modifiedBy ?? (await this.provider.getAccount(reviewComment.author)) ?? core.account.System
|
||||
|
||||
if (info.reviewThreadId === undefined && reviewComment.replyTo?.url !== undefined) {
|
||||
const rthread = await derivedClient.findOne(github.class.GithubReviewComment, {
|
||||
|
||||
@@ -132,7 +132,7 @@ export class ReviewThreadSyncManager implements DocSyncManager {
|
||||
return true
|
||||
}
|
||||
const account =
|
||||
existing?.createdBy ?? (await this.provider.getAccountU(commentExternal.user))?._id ?? core.account.System
|
||||
existing?.createdBy ?? (await this.provider.getAccountU(commentExternal.user)) ?? core.account.System
|
||||
|
||||
if (commentExternal !== undefined) {
|
||||
try {
|
||||
@@ -172,7 +172,7 @@ export class ReviewThreadSyncManager implements DocSyncManager {
|
||||
repo: GithubIntegrationRepository,
|
||||
integration: IntegrationContainer
|
||||
): Promise<void> {
|
||||
const account = (await this.provider.getAccountU(event.sender))?._id ?? core.account.System
|
||||
const account = (await this.provider.getAccountU(event.sender)) ?? core.account.System
|
||||
|
||||
let externalData: ReviewThreadExternalData
|
||||
try {
|
||||
@@ -287,7 +287,7 @@ export class ReviewThreadSyncManager implements DocSyncManager {
|
||||
// Use first comment as author, since github doesn't provide one.
|
||||
const account =
|
||||
existing?.modifiedBy ??
|
||||
(await this.provider.getAccount(review.comments.nodes[0].author ?? null))?._id ??
|
||||
(await this.provider.getAccount(review.comments.nodes[0].author ?? null)) ??
|
||||
core.account.System
|
||||
|
||||
const messageData: ReviewThreadData = {
|
||||
@@ -301,7 +301,7 @@ export class ReviewThreadSyncManager implements DocSyncManager {
|
||||
originalLine: review.originalLine,
|
||||
originalStartLine: review.originalStartLine,
|
||||
path: review.path,
|
||||
resolvedBy: (await this.provider.getAccount(review.resolvedBy))?._id ?? core.account.System,
|
||||
resolvedBy: (await this.provider.getAccount(review.resolvedBy)) ?? core.account.System,
|
||||
startDiffSide: review.startDiffSide
|
||||
}
|
||||
if (existing === undefined) {
|
||||
|
||||
@@ -110,7 +110,7 @@ export class ReviewSyncManager implements DocSyncManager {
|
||||
return true
|
||||
}
|
||||
const account =
|
||||
existing?.createdBy ?? (await this.provider.getAccountU(commentExternal.user))?._id ?? core.account.System
|
||||
existing?.createdBy ?? (await this.provider.getAccountU(commentExternal.user)) ?? core.account.System
|
||||
|
||||
if (commentExternal !== undefined) {
|
||||
try {
|
||||
@@ -164,7 +164,7 @@ export class ReviewSyncManager implements DocSyncManager {
|
||||
repo: GithubIntegrationRepository,
|
||||
integration: IntegrationContainer
|
||||
): Promise<void> {
|
||||
const account = (await this.provider.getAccountU(event.sender))?._id ?? core.account.System
|
||||
const account = (await this.provider.getAccountU(event.sender)) ?? core.account.System
|
||||
|
||||
let externalData: ReviewExternalData
|
||||
try {
|
||||
@@ -302,7 +302,7 @@ export class ReviewSyncManager implements DocSyncManager {
|
||||
}
|
||||
const review = info.external as ReviewExternalData
|
||||
|
||||
const account = existing?.modifiedBy ?? (await this.provider.getAccount(review.author))?._id ?? core.account.System
|
||||
const account = existing?.modifiedBy ?? (await this.provider.getAccount(review.author)) ?? core.account.System
|
||||
|
||||
const messageData: ReviewData = {
|
||||
body: await this.provider.getMarkupSafe(container.container, review.body),
|
||||
|
||||
Reference in New Issue
Block a user