diff --git a/services/github/pod-github/Dockerfile b/services/github/pod-github/Dockerfile index 130f1903ab..8c68a0474f 100644 --- a/services/github/pod-github/Dockerfile +++ b/services/github/pod-github/Dockerfile @@ -15,4 +15,4 @@ COPY bundle/bundle.js ./ COPY bundle/bundle.js.map ./ EXPOSE 3078 -CMD [ "node", "--inspect", "--async-stack-traces", "--enable-source-maps", "bundle.js" ] +CMD [ "node", "bundle.js" ] diff --git a/services/github/pod-github/src/sync/comments.ts b/services/github/pod-github/src/sync/comments.ts index 1c72308167..a9a227f702 100644 --- a/services/github/pod-github/src/sync/comments.ts +++ b/services/github/pod-github/src/sync/comments.ts @@ -12,8 +12,8 @@ import core, { Ref, TxOperations } from '@hcengineering/core' -import { LiveQuery } from '@hcengineering/query' import github, { DocSyncInfo, GithubIntegrationRepository, GithubProject } from '@hcengineering/github' +import { LiveQuery } from '@hcengineering/query' import { deepEqual } from 'fast-equals' import { ContainerFocus, @@ -252,7 +252,7 @@ export class CommentSyncManager implements DocSyncManager { } if (info.external === undefined) { // TODO: Use selected repository - const repo = container.repository.find((it) => it._id === parent?.repository) + const repo = await this.provider.getRepositoryById(parent?.repository) if (repo?.nodeId === undefined) { // No need to sync if parent repository is not defined. return { needSync: githubSyncVersion } @@ -303,7 +303,7 @@ export class CommentSyncManager implements DocSyncManager { comment: CommentExternalData, account: Ref ): Promise { - const repository = container.repository.find((it) => it._id === info.repository) + const repository = await this.provider.getRepositoryById(info.repository) if (repository === undefined) { return } @@ -384,7 +384,7 @@ export class CommentSyncManager implements DocSyncManager { derivedClient: TxOperations ): Promise> { // TODO: Use selected repository - const repo = container.repository.find((it) => it._id === parent?.repository) + const repo = await this.provider.getRepositoryById(parent?.repository) if (repo?.nodeId === undefined) { // No need to sync if parent repository is not defined. return { needSync: githubSyncVersion } diff --git a/services/github/pod-github/src/sync/issueBase.ts b/services/github/pod-github/src/sync/issueBase.ts index dffebee633..476ef23a64 100644 --- a/services/github/pod-github/src/sync/issueBase.ts +++ b/services/github/pod-github/src/sync/issueBase.ts @@ -302,8 +302,7 @@ export abstract class IssueSyncManagerBase { const ff = await this.toPlatformField( { container: integration, - project: prj, - repository: repositories.filter((it) => it.githubProject === prj._id) + project: prj }, f, target, @@ -949,17 +948,19 @@ export abstract class IssueSyncManagerBase { existing: WithMarkup, issueExternal: IssueExternalData ): Promise { - const repo = container.repository.find((it) => it._id === info.repository) as GithubIntegrationRepository - await this.addConnectToMessage( - existing._class === github.class.GithubPullRequest - ? github.string.PullRequestConnectedActivityInfo - : github.string.IssueConnectedActivityInfo, - existing.space, - existing._id, - existing._class, - issueExternal, - repo - ) + const repo = await this.provider.getRepositoryById(info.repository) + if (repo != null) { + await this.addConnectToMessage( + existing._class === github.class.GithubPullRequest + ? github.string.PullRequestConnectedActivityInfo + : github.string.IssueConnectedActivityInfo, + existing.space, + existing._id, + existing._class, + issueExternal, + repo + ) + } } async collectIssueUpdate ( @@ -1125,7 +1126,7 @@ export abstract class IssueSyncManagerBase { container: IntegrationContainer, existingIssue: Issue | undefined, external: IssueExternalData - ): Promise { + ): Promise { if (existingIssue !== undefined) { // Select a milestone project if (existingIssue.milestone != null) { @@ -1133,14 +1134,7 @@ export abstract class IssueSyncManagerBase { await this.provider.liveQuery.queryFind(github.mixin.GithubMilestone, {}) ).find((it) => it._id === existingIssue.milestone) if (milestone === undefined) { - // Let's search for milestone, and if it doesn't have mixin, return undefined. - const mstone = await this.client.findOne(github.mixin.GithubMilestone, { - _id: existingIssue.milestone as Ref - }) - if (mstone === undefined) { - return undefined - } - return null + return } return { project, diff --git a/services/github/pod-github/src/sync/issues.ts b/services/github/pod-github/src/sync/issues.ts index cc9ebc9f05..a28f214a3b 100644 --- a/services/github/pod-github/src/sync/issues.ts +++ b/services/github/pod-github/src/sync/issues.ts @@ -345,7 +345,9 @@ export class IssueSyncManager extends IssueSyncManagerBase implements DocSyncMan } if (info.repository == null) { // No need to sync if component it not yet set - const repos = container.repository.map((it) => it.name).join(', ') + const repos = (await this.provider.getProjectRepositories(container.project._id)) + .map((it) => it.name) + .join(', ') this.ctx.error('Not syncing repository === null', { url: info.url, identifier: (existing as Issue).identifier, @@ -360,9 +362,11 @@ export class IssueSyncManager extends IssueSyncManagerBase implements DocSyncMan let issueExternal = info.external as IssueExternalData if (info.external === undefined && existing !== undefined) { - const repository = container.repository.find((it) => it._id === info.repository) + const repository = await this.provider.getRepositoryById(info.repository) if (repository === undefined) { - const repos = container.repository.map((it) => it.name).join(', ') + const repos = (await this.provider.getProjectRepositories(container.project._id)) + .map((it) => it.name) + .join(', ') this.ctx.error('Not syncing repository === undefined', { url: info.url, identifier: (existing as Issue).identifier, @@ -427,11 +431,6 @@ export class IssueSyncManager extends IssueSyncManagerBase implements DocSyncMan existing as Issue, issueExternal ) - if (target === null) { - // We need to wait, no milestone data yet. - this.ctx.error('target === null, no milestone data yet', { url: info.url }) - return { needSync: githubSyncVersion } - } if (target === undefined) { target = this.getProjectIssueTarget(container.project, issueExternal) } @@ -573,6 +572,11 @@ export class IssueSyncManager extends IssueSyncManagerBase implements DocSyncMan container.container, issueExternal.body ) + const repo = await this.provider.getRepositoryById(info.repository) + if (repo == null) { + // No repository, it probable deleted + return { needSync: githubSyncVersion } + } await this.ctx.withLog( 'create platform issue', {}, @@ -590,7 +594,7 @@ export class IssueSyncManager extends IssueSyncManagerBase implements DocSyncMan info.repository as Ref, container.project, taskTypes[0]._id, - container.repository.find((it) => it._id === info.repository) as GithubIntegrationRepository & { + repo as GithubIntegrationRepository & { repository: IntegrationRepositoryData }, !markdownCompatible diff --git a/services/github/pod-github/src/sync/projects.ts b/services/github/pod-github/src/sync/projects.ts index db5201e2c2..79f19e3c4a 100644 --- a/services/github/pod-github/src/sync/projects.ts +++ b/services/github/pod-github/src/sync/projects.ts @@ -12,11 +12,6 @@ import core, { TxOperations, generateId } from '@hcengineering/core' -import { getEmbeddedLabel, translate } from '@hcengineering/platform' -import { LiveQuery } from '@hcengineering/query' -import task from '@hcengineering/task' -import tracker, { Milestone } from '@hcengineering/tracker' -import { RepositoryEvent } from '@octokit/webhooks-types' import github, { DocSyncInfo, GithubFieldMapping, @@ -25,6 +20,11 @@ import github, { GithubProject, GithubProjectSyncData } from '@hcengineering/github' +import { getEmbeddedLabel, translate } from '@hcengineering/platform' +import { LiveQuery } from '@hcengineering/query' +import task from '@hcengineering/task' +import tracker, { Milestone } from '@hcengineering/tracker' +import { RepositoryEvent } from '@octokit/webhooks-types' import { deepEqual } from 'fast-equals' import { Octokit } from 'octokit' import { @@ -238,6 +238,28 @@ export class ProjectsSyncManager implements DocSyncManager { external: data, needSync: '' }) + + // We also need to notify all issues with milestone set to this milestone. + const milestonedIds = await this.client.findAll( + tracker.class.Issue, + { milestone: milestone._id }, + { projection: { _id: 1 } } + ) + while (milestonedIds.length > 0) { + const part = milestonedIds.splice(0, 100) + const docInfos = await this.client.findAll( + github.class.DocSyncInfo, + { _id: { $in: part.map((it) => it._id as unknown as Ref) } }, + { projection: { _id: 1 } } + ) + if (docInfos.length > 0) { + const ops = derivedClient.apply() + for (const d of docInfos) { + await ops.update(d, { needSync: '' }) + } + await ops.commit() + } + } } } } diff --git a/services/github/pod-github/src/sync/pullrequests.ts b/services/github/pod-github/src/sync/pullrequests.ts index 7bc2507908..066d73cb9a 100644 --- a/services/github/pod-github/src/sync/pullrequests.ts +++ b/services/github/pod-github/src/sync/pullrequests.ts @@ -32,7 +32,6 @@ import github, { import task, { TaskType, calcRank, makeRank } from '@hcengineering/task' import time, { ToDo, ToDoPriority } from '@hcengineering/time' import tracker, { Issue, IssuePriority, IssueStatus, Project } from '@hcengineering/tracker' -import { OctokitResponse } from '@octokit/types' import { ProjectsV2ItemEvent, PullRequestEvent } from '@octokit/webhooks-types' import { Octokit } from 'octokit' import config from '../config' @@ -59,7 +58,16 @@ import { } from './githubTypes' import { GithubIssueData, IssueSyncManagerBase, IssueSyncTarget, WithMarkup } from './issueBase' import { syncConfig } from './syncConfig' -import { errorToObj, getSinceRaw, gqlp, guessStatus, isGHWriteAllowed, syncDerivedDocuments, syncRunner } from './utils' +import { + errorToObj, + getSinceRaw, + gqlp, + guessStatus, + isGHWriteAllowed, + syncChilds, + syncDerivedDocuments, + syncRunner +} from './utils' type GithubPullRequestData = GithubIssueData & Omit @@ -487,8 +495,8 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS await this.ctx.withLog( 'retrieve pull request patch', {}, - async () => - await this.handlePatch( + () => + this.handlePatch( info, container, pullRequestExternal, @@ -526,7 +534,7 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS info.repository as Ref, container.project, taskTypes[0]._id, - container.repository.find((it) => it._id === info.repository) as GithubIntegrationRepository, + (await this.provider.getRepositoryById(info.repository)) as GithubIntegrationRepository, !markdownCompatible ) }, @@ -544,6 +552,9 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS await op.commit() + // To sync reviews/review threads in case they are created before us. + await syncChilds(info, this.client, derivedClient) + return { needSync: '', external: pullRequestExternal, @@ -563,7 +574,7 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS await this.ctx.withLog( 'update pull request patch', {}, - async () => + async () => { await this.handlePatch( info, container, @@ -575,7 +586,8 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS }, lastModified, accountGH - ), + ) + }, { url: pullRequestExternal.url } ) } @@ -966,10 +978,6 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS existing as Issue, pullRequestExternal ) - if (target === null) { - // We need to wait, no milestone data yet. - return { needSync: '' } - } if (target === undefined) { target = this.getProjectIssueTarget(container.project, pullRequestExternal) } @@ -1085,18 +1093,17 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS existingPR: Pick, lastModified: number, account: Ref - ): Promise { - let patch: string | null = null - const repo = container.repository.find((it) => it._id === info.repository) + ): Promise { + const repo = await this.provider.getRepositoryById(info.repository) if (repo?.nodeId === undefined) { - return null + return } if (info.external?.patch !== true) { - patch = await this.fetchPatch(pullRequestExternal, container.container.octokit, repo) + const { patch, contentType } = await this.fetchPatch(pullRequestExternal, container.container.octokit, repo) // Update attached patch data. const patchAttachment = await this.client.findOne(github.class.GithubPatch, { attachedTo: existingPR._id }) - const blob = await this.provider.uploadFile(patch, patchAttachment?.file) + const blob = await this.provider.uploadFile(patch, patchAttachment?.file, contentType) if (blob !== undefined) { if (patchAttachment === undefined) { await this.client.addCollection( @@ -1131,7 +1138,6 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS } } } - return patch } private async createPullRequest ( @@ -1544,8 +1550,9 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS pullRequest: PullRequestExternalData, octokit: Octokit, repository: GithubIntegrationRepository - ): Promise { + ): Promise<{ patch: string, contentType: string }> { let patch = '' + let contentType = 'application/vnd.github.VERSION.diff' try { const patchContent = await octokit.rest.pulls.get({ owner: repository.owner?.login as string, @@ -1556,12 +1563,13 @@ export class PullRequestSyncManager extends IssueSyncManagerBase implements DocS 'X-GitHub-Api-Version': '2022-11-28' } }) - patch = ((patchContent as unknown as OctokitResponse).data ?? '').slice(0, 2 * 1024 * 1024) + patch = (patchContent.data as unknown as string) ?? '' + contentType = patchContent.headers['content-type'] ?? 'application/vnd.github.VERSION.diff' } catch (err: any) { this.ctx.error('Error', { err }) Analytics.handleError(err) } - return patch + return { patch, contentType } } async deleteGithubDocument (container: ContainerFocus, account: Ref, id: string): Promise { diff --git a/services/github/pod-github/src/sync/reviewComments.ts b/services/github/pod-github/src/sync/reviewComments.ts index 36cf294a2b..3cc0883bbe 100644 --- a/services/github/pod-github/src/sync/reviewComments.ts +++ b/services/github/pod-github/src/sync/reviewComments.ts @@ -310,11 +310,11 @@ export class ReviewCommentSyncManager implements DocSyncManager { return {} } if (parent === undefined) { - return { needSync: '' } + return { needSync: githubSyncVersion } } if (info.external === undefined) { // TODO: Use selected repository - const repo = container.repository.find((it) => it._id === parent?.repository) + const repo = await this.provider.getRepositoryById(parent?.repository) if (repo?.nodeId === undefined) { // No need to sync if parent repository is not defined. return { needSync: githubSyncVersion } @@ -381,7 +381,7 @@ export class ReviewCommentSyncManager implements DocSyncManager { account: Ref, derivedClient: TxOperations ): Promise { - const repository = container.repository.find((it) => it._id === info.repository) + const repository = await this.provider.getRepositoryById(info.repository) if (repository === undefined) { return } @@ -473,7 +473,7 @@ export class ReviewCommentSyncManager implements DocSyncManager { derivedClient: TxOperations ): Promise> { // TODO: Use selected repository - const repo = container.repository.find((it) => it._id === parent?.repository) + const repo = await this.provider.getRepositoryById(parent?.repository) if (repo?.nodeId === undefined) { // No need to sync if parent repository is not defined. return { needSync: githubSyncVersion } diff --git a/services/github/pod-github/src/sync/reviewThreads.ts b/services/github/pod-github/src/sync/reviewThreads.ts index 3d4d047cf0..0ce7ff5c21 100644 --- a/services/github/pod-github/src/sync/reviewThreads.ts +++ b/services/github/pod-github/src/sync/reviewThreads.ts @@ -11,14 +11,14 @@ import core, { Ref, TxOperations } from '@hcengineering/core' -import { EmptyMarkup } from '@hcengineering/text' -import { LiveQuery } from '@hcengineering/query' import github, { DocSyncInfo, GithubIntegrationRepository, GithubProject, GithubReviewThread } from '@hcengineering/github' +import { LiveQuery } from '@hcengineering/query' +import { EmptyMarkup } from '@hcengineering/text' import { ContainerFocus, DocSyncManager, @@ -35,7 +35,7 @@ import { getUpdatedAtReviewThread, reviewThreadDetails } from './githubTypes' -import { collectUpdate, deleteObjects, errorToObj, isGHWriteAllowed, syncDerivedDocuments } from './utils' +import { collectUpdate, deleteObjects, errorToObj, isGHWriteAllowed, syncChilds, syncDerivedDocuments } from './utils' import { Analytics } from '@hcengineering/analytics' import { PullRequestReviewThreadEvent } from '@octokit/webhooks-types' @@ -266,11 +266,11 @@ export class ReviewThreadSyncManager implements DocSyncManager { return {} } if (parent === undefined) { - return { needSync: '' } + return { needSync: githubSyncVersion } } if (info.external === undefined) { // TODO: Use selected repository - const repo = container.repository.find((it) => it._id === parent?.repository) + const repo = await this.provider.getRepositoryById(parent?.repository) if (repo?.nodeId === undefined) { // No need to sync if parent repository is not defined. return { needSync: githubSyncVersion } @@ -305,6 +305,9 @@ export class ReviewThreadSyncManager implements DocSyncManager { if (existing === undefined) { try { await this.createReviewThread(info, messageData, parent, review, account) + + // We need trigger comments, if their sync data created before + await syncChilds(info, this.client, derivedClient) return { needSync: githubSyncVersion, current: messageData } } catch (err: any) { this.ctx.error('Error', { err }) @@ -327,7 +330,7 @@ export class ReviewThreadSyncManager implements DocSyncManager { account: Ref, derivedClient: TxOperations ): Promise { - const repository = container.repository.find((it) => it._id === info.repository) + const repository = await this.provider.getRepositoryById(info.repository) if (repository === undefined) { return } @@ -422,7 +425,7 @@ export class ReviewThreadSyncManager implements DocSyncManager { derivedClient: TxOperations ): Promise> { // TODO: Use selected repository - const repo = container.repository.find((it) => it._id === parent?.repository) + const repo = await this.provider.getRepositoryById(parent?.repository) if (repo?.nodeId === undefined) { // No need to sync if parent repository is not defined. return { needSync: githubSyncVersion } diff --git a/services/github/pod-github/src/sync/reviews.ts b/services/github/pod-github/src/sync/reviews.ts index 03e1ac5ea5..e1d1082fcd 100644 --- a/services/github/pod-github/src/sync/reviews.ts +++ b/services/github/pod-github/src/sync/reviews.ts @@ -11,7 +11,6 @@ import core, { Ref, TxOperations } from '@hcengineering/core' -import { LiveQuery } from '@hcengineering/query' import github, { DocSyncInfo, GithubIntegrationRepository, @@ -19,6 +18,7 @@ import github, { GithubPullRequestReviewState, GithubReview } from '@hcengineering/github' +import { LiveQuery } from '@hcengineering/query' import { ContainerFocus, DocSyncManager, @@ -29,7 +29,7 @@ import { githubSyncVersion } from '../types' import { PullRequestExternalData, Review as ReviewExternalData, reviewDetails, toReviewState } from './githubTypes' -import { collectUpdate, deleteObjects, errorToObj, isGHWriteAllowed } from './utils' +import { collectUpdate, deleteObjects, errorToObj, isGHWriteAllowed, syncChilds } from './utils' import { Analytics } from '@hcengineering/analytics' import { PullRequestReviewEvent, PullRequestReviewSubmittedEvent } from '@octokit/webhooks-types' @@ -284,11 +284,11 @@ export class ReviewSyncManager implements DocSyncManager { return {} } if (parent === undefined) { - return { needSync: '' } + return { needSync: githubSyncVersion } } if (info.external === undefined) { // TODO: Use selected repository - const repo = container.repository.find((it) => it._id === parent?.repository) + const repo = await this.provider.getRepositoryById(parent?.repository) if (repo?.nodeId === undefined) { // No need to sync if parent repository is not defined. return { needSync: githubSyncVersion } @@ -310,6 +310,8 @@ export class ReviewSyncManager implements DocSyncManager { if (existing === undefined) { try { await this.createReview(info, messageData, parent, review, account) + + await syncChilds(info, this.client, derivedClient) return { needSync: githubSyncVersion, current: messageData } } catch (err: any) { this.ctx.error('Error', { err }) @@ -331,7 +333,7 @@ export class ReviewSyncManager implements DocSyncManager { review: ReviewExternalData, account: Ref ): Promise { - const repository = container.repository.find((it) => it._id === info.repository) + const repository = await this.provider.getRepositoryById(info.repository) if (repository === undefined) { return } @@ -400,7 +402,7 @@ export class ReviewSyncManager implements DocSyncManager { derivedClient: TxOperations ): Promise> { // TODO: Use selected repository - const repo = container.repository.find((it) => it._id === parent?.repository) + const repo = await this.provider.getRepositoryById(parent?.repository) if (repo?.nodeId === undefined) { // No need to sync if parent repository is not defined. return { needSync: githubSyncVersion } diff --git a/services/github/pod-github/src/sync/utils.ts b/services/github/pod-github/src/sync/utils.ts index 684caa0c19..dd62c13f0c 100644 --- a/services/github/pod-github/src/sync/utils.ts +++ b/services/github/pod-github/src/sync/utils.ts @@ -16,15 +16,15 @@ import core, { Type, toIdMap } from '@hcengineering/core' -import { PlatformError, unknownStatus } from '@hcengineering/platform' -import task, { TaskType, calculateStatuses, createState, findStatusAttr } from '@hcengineering/task' -import tracker, { IssueStatus } from '@hcengineering/tracker' import github, { DocSyncInfo, GithubIntegrationRepository, GithubIssueStateReason, GithubProject } from '@hcengineering/github' +import { PlatformError, unknownStatus } from '@hcengineering/platform' +import task, { TaskType, calculateStatuses, createState, findStatusAttr } from '@hcengineering/task' +import tracker, { IssueStatus } from '@hcengineering/tracker' import { deepEqual } from 'fast-equals' import { IntegrationManager, githubExternalSyncVersion } from '../types' import { GithubDataType } from './githubTypes' @@ -411,3 +411,14 @@ export function compareMarkdown (a: string, b: string): boolean { return na === nb } + +export async function syncChilds (info: DocSyncInfo, client: TxOperations, derivedClient: TxOperations): Promise { + const childInfos = await client.findAll(github.class.DocSyncInfo, { parent: info.url.toLowerCase() }) + if (childInfos.length > 0) { + const ops = derivedClient.apply() + for (const child of childInfos) { + await ops?.update(child, { needSync: '' }) + } + await ops.commit() + } +} diff --git a/services/github/pod-github/src/types.ts b/services/github/pod-github/src/types.ts index 9bc08458c3..4c2938a597 100644 --- a/services/github/pod-github/src/types.ts +++ b/services/github/pod-github/src/types.ts @@ -77,7 +77,6 @@ export type UserInfo = Data export interface ContainerFocus { container: IntegrationContainer - repository: GithubIntegrationRepository[] project: GithubProject } @@ -96,7 +95,7 @@ export interface IntegrationManager { sync: () => void getGithubLogin: (container: IntegrationContainer, account: Ref) => Promise - uploadFile: (patch: string, file?: string) => Promise + uploadFile: (patch: string, file?: string, contentType?: string) => Promise getStatuses: (type: Ref | undefined) => Promise getProjectStatuses: (type: Ref | undefined) => Promise @@ -126,6 +125,10 @@ export interface IntegrationManager { ) => Promise<{ markdownCompatible: boolean, markdown: string }> isPlatformUser: (account: Ref) => Promise + + getProjectRepositories: (space: Ref) => Promise + + getRepositoryById: (ref?: Ref | null) => Promise } export type ExternalSyncField = 'externalVersion' | 'derivedVersion' diff --git a/services/github/pod-github/src/worker.ts b/services/github/pod-github/src/worker.ts index 9fb7159946..7fbb684819 100644 --- a/services/github/pod-github/src/worker.ts +++ b/services/github/pod-github/src/worker.ts @@ -186,29 +186,45 @@ export class GithubWorker implements IntegrationManager { } async getContainer (space: Ref): Promise { - for (const v of this.integrations.values()) { - if (v.octokit === undefined) { - continue - } - const project = ( - await this.liveQuery.queryFind(github.mixin.GithubProject, { - _id: space as Ref - }) - ).shift() - if (project !== undefined) { - const repositories = await this.liveQuery.queryFind( - github.class.GithubIntegrationRepository, - {} - ) + const project = ( + await this.liveQuery.queryFind(github.mixin.GithubProject, { + _id: space as Ref + }) + ).shift() + if (project !== undefined) { + for (const v of this.integrations.values()) { + if (v.octokit === undefined) { + continue + } + if (project.integration !== v.integration._id) { + continue + } return { container: v, - repository: repositories.filter((it) => it.githubProject === space), project } } } } + async getProjectRepositories (space: Ref): Promise { + const repositories = await this.liveQuery.queryFind( + github.class.GithubIntegrationRepository, + {} + ) + return repositories.filter((it) => it.githubProject === space) + } + + async getRepositoryById ( + _id?: Ref | null + ): Promise { + if (_id != null) { + return ( + await this.liveQuery.queryFind(github.class.GithubIntegrationRepository, { _id }) + ).shift() + } + } + async getAccountU (user: User): Promise { return await this.getAccount({ id: user.node_id, @@ -584,9 +600,9 @@ export class GithubWorker implements IntegrationManager { return record !== undefined && accountRef !== undefined } - async uploadFile (patch: string, file?: string): Promise { + async uploadFile (patch: string, file?: string, contentType?: string): Promise { const id: string = file ?? generateId() - await this.storageAdapter.put(this.ctx, this.workspace, id, patch, 'text/x-patch', patch.length) + await this.storageAdapter.put(this.ctx, this.workspace, id, patch, contentType ?? 'text/x-patch') return await this.storageAdapter.stat(this.ctx, this.workspace, id) } @@ -1101,17 +1117,6 @@ export class GithubWorker implements IntegrationManager { const _projects = projects.map((it) => it._id) const _repositories = repositories.map((it) => it._id) - const h = this.client.getHierarchy() - const sortCases = this.mappers - .map((it) => it._class) - .flat() - .map((it) => h.getDescendants(it)) - .flat() - .map((it, idx) => ({ - query: it, - index: idx - })) - const docs = await this.ctx.with( 'find-doc-sync-info', {}, @@ -1125,13 +1130,7 @@ export class GithubWorker implements IntegrationManager { repository: { $in: [null, ..._repositories] } }, { - limit: 50, - sort: { - objectClass: { - order: SortingOrder.Ascending, - cases: sortCases - } - } + limit: 50 } ), { _projects, _repositories } @@ -1261,8 +1260,7 @@ export class GithubWorker implements IntegrationManager { }) continue } - const container = await this.getContainer(info.space) - const repo = container?.repository.find((it) => it._id === info.repository) + const repo = await this.getRepositoryById(info.repository) if (repo !== undefined && !repo.enabled) { continue }