mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-13 21:27:46 +02:00
Merge staging-new and bump versions
Signed-off-by: Artem Savchenko <armisav@gmail.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hcengineering/pod-github",
|
||||
"version": "0.7.382",
|
||||
"version": "0.7.411",
|
||||
"main": "lib/index.js",
|
||||
"svelte": "src/index.ts",
|
||||
"types": "types/index.d.ts",
|
||||
@@ -31,7 +31,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "~7.0.3",
|
||||
"@hcengineering/platform-rig": "workspace:^0.7.382",
|
||||
"@hcengineering/platform-rig": "workspace:^0.7.411",
|
||||
"@types/node": "^22.18.1",
|
||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
@@ -60,38 +60,40 @@
|
||||
"@types/jest": "^29.5.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/core": "workspace:^0.7.382",
|
||||
"@hcengineering/account": "workspace:^0.7.382",
|
||||
"@hcengineering/account-client": "workspace:^0.7.382",
|
||||
"@hcengineering/platform": "workspace:^0.7.382",
|
||||
"@hcengineering/server-client": "workspace:^0.7.382",
|
||||
"@hcengineering/server-token": "workspace:^0.7.382",
|
||||
"@hcengineering/server-core": "workspace:^0.7.382",
|
||||
"@hcengineering/server-storage": "workspace:^0.7.382",
|
||||
"@hcengineering/mongo": "workspace:^0.7.382",
|
||||
"@hcengineering/client": "workspace:^0.7.382",
|
||||
"@hcengineering/chunter": "workspace:^0.7.382",
|
||||
"@hcengineering/contact": "workspace:^0.7.382",
|
||||
"@hcengineering/client-resources": "workspace:^0.7.382",
|
||||
"@hcengineering/tracker": "workspace:^0.7.382",
|
||||
"@hcengineering/query": "workspace:^0.7.382",
|
||||
"@hcengineering/text": "workspace:^0.7.382",
|
||||
"@hcengineering/text-markdown": "workspace:^0.7.382",
|
||||
"@hcengineering/github": "workspace:^0.7.382",
|
||||
"@hcengineering/attachment": "workspace:^0.7.382",
|
||||
"@hcengineering/core": "workspace:^0.7.411",
|
||||
"@hcengineering/account": "workspace:^0.7.411",
|
||||
"@hcengineering/account-client": "workspace:^0.7.411",
|
||||
"@hcengineering/platform": "workspace:^0.7.411",
|
||||
"@hcengineering/server-client": "workspace:^0.7.411",
|
||||
"@hcengineering/server-token": "workspace:^0.7.411",
|
||||
"@hcengineering/server-core": "workspace:^0.7.411",
|
||||
"@hcengineering/server-storage": "workspace:^0.7.411",
|
||||
"@hcengineering/mongo": "workspace:^0.7.411",
|
||||
"@hcengineering/client": "workspace:^0.7.411",
|
||||
"@hcengineering/chunter": "workspace:^0.7.411",
|
||||
"@hcengineering/contact": "workspace:^0.7.411",
|
||||
"@hcengineering/client-resources": "workspace:^0.7.411",
|
||||
"@hcengineering/tracker": "workspace:^0.7.411",
|
||||
"@hcengineering/query": "workspace:^0.7.411",
|
||||
"@hcengineering/text": "workspace:^0.7.411",
|
||||
"@hcengineering/text-markdown": "workspace:^0.7.411",
|
||||
"@hcengineering/github": "workspace:^0.7.411",
|
||||
"@hcengineering/attachment": "workspace:^0.7.411",
|
||||
"dotenv": "^16.4.5",
|
||||
"octokit": "^3.1.1",
|
||||
"@octokit/webhooks": "^12.0.3",
|
||||
"@octokit/types": "^12.0.0",
|
||||
"graphql": "^16.8.0",
|
||||
"fast-equals": "^5.2.2",
|
||||
"@hcengineering/minio": "workspace:^0.7.382",
|
||||
"@hcengineering/minio": "workspace:^0.7.411",
|
||||
"markdown-it": "^14.0.0",
|
||||
"@tiptap/html": "^2.11.7",
|
||||
"@tiptap/core": "^2.11.7",
|
||||
"@tiptap/pm": "^2.11.7",
|
||||
"@tiptap/starter-kit": "^2.11.7",
|
||||
"@tiptap/extension-highlight": "^2.11.7",
|
||||
"@tiptap/extension-subscript": "^2.11.7",
|
||||
"@tiptap/extension-superscript": "^2.11.7",
|
||||
"@tiptap/extension-placeholder": "^2.11.7",
|
||||
"@tiptap/extension-mention": "^2.11.7",
|
||||
"@tiptap/extension-typography": "^2.11.7",
|
||||
@@ -110,66 +112,66 @@
|
||||
"@tiptap/extension-table-row": "^2.11.7",
|
||||
"@tiptap/extension-code": "^2.11.7",
|
||||
"@tiptap/extension-bubble-menu": "^2.11.7",
|
||||
"@hcengineering/task": "workspace:^0.7.382",
|
||||
"@hcengineering/task": "workspace:^0.7.411",
|
||||
"express": "^4.21.2",
|
||||
"cors": "^2.8.5",
|
||||
"body-parser": "^1.20.3",
|
||||
"mongodb": "^6.16.0",
|
||||
"@hcengineering/setting": "workspace:^0.7.382",
|
||||
"@hcengineering/preference": "workspace:^0.7.382",
|
||||
"@hcengineering/login": "workspace:^0.7.382",
|
||||
"@hcengineering/view": "workspace:^0.7.382",
|
||||
"@hcengineering/recruit": "workspace:^0.7.382",
|
||||
"@hcengineering/activity": "workspace:^0.7.382",
|
||||
"@hcengineering/telegram": "workspace:^0.7.382",
|
||||
"@hcengineering/workbench": "workspace:^0.7.382",
|
||||
"@hcengineering/lead": "workspace:^0.7.382",
|
||||
"@hcengineering/gmail": "workspace:^0.7.382",
|
||||
"@hcengineering/inventory": "workspace:^0.7.382",
|
||||
"@hcengineering/templates": "workspace:^0.7.382",
|
||||
"@hcengineering/notification": "workspace:^0.7.382",
|
||||
"@hcengineering/tags": "workspace:^0.7.382",
|
||||
"@hcengineering/calendar": "workspace:^0.7.382",
|
||||
"@hcengineering/board": "workspace:^0.7.382",
|
||||
"@hcengineering/hr": "workspace:^0.7.382",
|
||||
"@hcengineering/bitrix": "workspace:^0.7.382",
|
||||
"@hcengineering/request": "workspace:^0.7.382",
|
||||
"@hcengineering/drive": "workspace:^0.7.382",
|
||||
"@hcengineering/support": "workspace:^0.7.382",
|
||||
"@hcengineering/collaborator-client": "workspace:^0.7.382",
|
||||
"@hcengineering/document": "workspace:^0.7.382",
|
||||
"@hcengineering/login-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/view-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/task-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/chunter-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/recruit-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/setting-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/contact-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/activity-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/telegram-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/workbench-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/attachment-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/lead-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/gmail-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/inventory-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/templates-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/notification-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/preference-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/tags-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/calendar-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/tracker-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/board-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/hr-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/bitrix-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/request-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/drive-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/support-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/github-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/document-assets": "workspace:^0.7.382",
|
||||
"@hcengineering/time": "workspace:^0.7.382",
|
||||
"@hcengineering/server-guest-resources": "workspace:^0.7.382",
|
||||
"@hcengineering/analytics": "workspace:^0.7.382",
|
||||
"@hcengineering/analytics-service": "workspace:^0.7.382",
|
||||
"@hcengineering/setting": "workspace:^0.7.411",
|
||||
"@hcengineering/preference": "workspace:^0.7.411",
|
||||
"@hcengineering/login": "workspace:^0.7.411",
|
||||
"@hcengineering/view": "workspace:^0.7.411",
|
||||
"@hcengineering/recruit": "workspace:^0.7.411",
|
||||
"@hcengineering/activity": "workspace:^0.7.411",
|
||||
"@hcengineering/telegram": "workspace:^0.7.411",
|
||||
"@hcengineering/workbench": "workspace:^0.7.411",
|
||||
"@hcengineering/lead": "workspace:^0.7.411",
|
||||
"@hcengineering/gmail": "workspace:^0.7.411",
|
||||
"@hcengineering/inventory": "workspace:^0.7.411",
|
||||
"@hcengineering/templates": "workspace:^0.7.411",
|
||||
"@hcengineering/notification": "workspace:^0.7.411",
|
||||
"@hcengineering/tags": "workspace:^0.7.411",
|
||||
"@hcengineering/calendar": "workspace:^0.7.411",
|
||||
"@hcengineering/board": "workspace:^0.7.411",
|
||||
"@hcengineering/hr": "workspace:^0.7.411",
|
||||
"@hcengineering/bitrix": "workspace:^0.7.411",
|
||||
"@hcengineering/request": "workspace:^0.7.411",
|
||||
"@hcengineering/drive": "workspace:^0.7.411",
|
||||
"@hcengineering/support": "workspace:^0.7.411",
|
||||
"@hcengineering/collaborator-client": "workspace:^0.7.411",
|
||||
"@hcengineering/document": "workspace:^0.7.411",
|
||||
"@hcengineering/login-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/view-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/task-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/chunter-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/recruit-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/setting-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/contact-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/activity-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/telegram-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/workbench-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/attachment-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/lead-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/gmail-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/inventory-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/templates-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/notification-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/preference-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/tags-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/calendar-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/tracker-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/board-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/hr-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/bitrix-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/request-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/drive-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/support-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/github-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/document-assets": "workspace:^0.7.411",
|
||||
"@hcengineering/time": "workspace:^0.7.411",
|
||||
"@hcengineering/server-guest-resources": "workspace:^0.7.411",
|
||||
"@hcengineering/analytics": "workspace:^0.7.411",
|
||||
"@hcengineering/analytics-service": "workspace:^0.7.411",
|
||||
"ws": "^8.18.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
import type { MeasureContext, WorkspaceInfoWithStatus, WorkspaceUuid } from '@hcengineering/core'
|
||||
import { GithubWorkerWorkspaceState, getGithubWorkerState } from '../workspaceUtils'
|
||||
|
||||
const WS = '00000000-0000-0000-0000-000000000001' as WorkspaceUuid
|
||||
|
||||
const DAY_MS = 24 * 60 * 60 * 1000
|
||||
|
||||
function createMockCtx (): MeasureContext {
|
||||
return {
|
||||
warn: jest.fn(),
|
||||
info: jest.fn(),
|
||||
error: jest.fn()
|
||||
} as unknown as MeasureContext
|
||||
}
|
||||
|
||||
function baseInfo (overrides: Partial<WorkspaceInfoWithStatus> = {}): WorkspaceInfoWithStatus {
|
||||
return {
|
||||
uuid: WS,
|
||||
name: 'ws',
|
||||
url: 'ws-url',
|
||||
createdOn: 0,
|
||||
versionMajor: 0,
|
||||
versionMinor: 7,
|
||||
versionPatch: 0,
|
||||
mode: 'active',
|
||||
processingAttemps: 0,
|
||||
...overrides
|
||||
}
|
||||
}
|
||||
|
||||
describe('getGithubWorkerState', () => {
|
||||
it('returns Skip and warns when uuid is absent', () => {
|
||||
const ctx = createMockCtx()
|
||||
const checked = new Set<string>()
|
||||
const info = { ...baseInfo(), uuid: undefined as unknown as WorkspaceUuid }
|
||||
const state = getGithubWorkerState(ctx, WS, info, 3, checked)
|
||||
expect(state).toBe(GithubWorkerWorkspaceState.Skip)
|
||||
expect(ctx.warn).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('returns Skip when workspace is disabled', () => {
|
||||
const ctx = createMockCtx()
|
||||
const state = getGithubWorkerState(ctx, WS, baseInfo({ isDisabled: true, mode: 'active' }), 3, new Set())
|
||||
expect(state).toBe(GithubWorkerWorkspaceState.Skip)
|
||||
expect(ctx.info).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it.each(['pending-deletion', 'deleting', 'deleted'] as const)('returns Skip for mode %s', (mode) => {
|
||||
const ctx = createMockCtx()
|
||||
expect(getGithubWorkerState(ctx, WS, baseInfo({ mode }), 3, new Set())).toBe(GithubWorkerWorkspaceState.Skip)
|
||||
})
|
||||
|
||||
it.each(['archived', 'archiving-pending-backup', 'archiving-clean'] as const)(
|
||||
'returns Skip for archiving %s',
|
||||
(mode) => {
|
||||
const ctx = createMockCtx()
|
||||
expect(getGithubWorkerState(ctx, WS, baseInfo({ mode }), 3, new Set())).toBe(GithubWorkerWorkspaceState.Skip)
|
||||
}
|
||||
)
|
||||
|
||||
it.each(['upgrading', 'creating', 'pending-creation'] as const)('returns Wait for mode %s', (mode) => {
|
||||
const ctx = createMockCtx()
|
||||
expect(getGithubWorkerState(ctx, WS, baseInfo({ mode }), 3, new Set())).toBe(GithubWorkerWorkspaceState.Wait)
|
||||
expect(ctx.warn).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('returns Wait when last visit exceeds inactivity interval', () => {
|
||||
const ctx = createMockCtx()
|
||||
const nowMs = 1_700_000_000_000
|
||||
const lastVisit = nowMs - 4 * DAY_MS
|
||||
expect(getGithubWorkerState(ctx, WS, baseInfo({ mode: 'active', lastVisit }), 3, new Set(), nowMs)).toBe(
|
||||
GithubWorkerWorkspaceState.Wait
|
||||
)
|
||||
})
|
||||
|
||||
it('returns Connect when within inactivity interval', () => {
|
||||
const ctx = createMockCtx()
|
||||
const nowMs = 1_700_000_000_000
|
||||
const lastVisit = nowMs - 2 * DAY_MS
|
||||
expect(getGithubWorkerState(ctx, WS, baseInfo({ mode: 'active', lastVisit }), 3, new Set(), nowMs)).toBe(
|
||||
GithubWorkerWorkspaceState.Connect
|
||||
)
|
||||
})
|
||||
|
||||
it('does not apply inactivity gate when interval is 0', () => {
|
||||
const ctx = createMockCtx()
|
||||
const nowMs = 1_700_000_000_000
|
||||
const lastVisit = nowMs - 365 * DAY_MS
|
||||
expect(getGithubWorkerState(ctx, WS, baseInfo({ mode: 'active', lastVisit }), 0, new Set(), nowMs)).toBe(
|
||||
GithubWorkerWorkspaceState.Connect
|
||||
)
|
||||
})
|
||||
|
||||
it('missing lastVisit uses epoch → Wait inactive when interval > 0', () => {
|
||||
const ctx = createMockCtx()
|
||||
const nowMs = 1_700_000_000_000
|
||||
expect(getGithubWorkerState(ctx, WS, baseInfo({ mode: 'active' }), 3, new Set(), nowMs)).toBe(
|
||||
GithubWorkerWorkspaceState.Wait
|
||||
)
|
||||
})
|
||||
|
||||
it('logs inactive warning only once per workspace id', () => {
|
||||
const ctx = createMockCtx()
|
||||
const checked = new Set<string>()
|
||||
const nowMs = 1_700_000_000_000
|
||||
const info = baseInfo({ mode: 'active', lastVisit: nowMs - 10 * DAY_MS })
|
||||
getGithubWorkerState(ctx, WS, info, 3, checked, nowMs)
|
||||
getGithubWorkerState(ctx, WS, info, 3, checked, nowMs)
|
||||
expect(ctx.warn).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
@@ -11,8 +11,6 @@ import core, {
|
||||
Client,
|
||||
ClientConnectEvent,
|
||||
DocumentUpdate,
|
||||
isActiveMode,
|
||||
isDeletingMode,
|
||||
MeasureContext,
|
||||
PersonId,
|
||||
RateLimiter,
|
||||
@@ -46,6 +44,7 @@ import { type StorageAdapter } from '@hcengineering/server-core'
|
||||
import { join } from 'path'
|
||||
import { createPlatformClient } from './client'
|
||||
import config from './config'
|
||||
import { GithubWorkerWorkspaceState, getGithubWorkerState } from './workspaceUtils'
|
||||
import { registerLoaders } from './loaders'
|
||||
import { createNotification } from './notifications'
|
||||
import { errorToObj } from './sync/utils'
|
||||
@@ -68,6 +67,8 @@ interface IntegrationDataValue {
|
||||
installationId: number | number[]
|
||||
}
|
||||
|
||||
export { GithubWorkerWorkspaceState, getGithubWorkerState } from './workspaceUtils'
|
||||
|
||||
export class PlatformWorker {
|
||||
private readonly clients = new Map<WorkspaceUuid, GithubWorker>()
|
||||
|
||||
@@ -948,32 +949,6 @@ export class PlatformWorker {
|
||||
|
||||
checkedWorkspaces = new Set<string>()
|
||||
|
||||
checkWorkspaceIsActive (workspace: WorkspaceUuid, workspaceInfo: WorkspaceInfoWithStatus): boolean {
|
||||
if (workspaceInfo?.uuid === undefined) {
|
||||
this.ctx.error('No workspace exists for workspaceId', { workspace })
|
||||
return false
|
||||
}
|
||||
if (workspaceInfo?.isDisabled === true || isDeletingMode(workspaceInfo?.mode)) {
|
||||
this.ctx.warn('Workspace is disabled', { workspace })
|
||||
return false
|
||||
}
|
||||
if (!isActiveMode(workspaceInfo?.mode)) {
|
||||
this.ctx.warn('Workspace is in maitenance, skipping for now.', { workspace, mode: workspaceInfo?.mode })
|
||||
return true
|
||||
}
|
||||
|
||||
const lastVisit = (Date.now() - (workspaceInfo.lastVisit ?? 0)) / (3600 * 24 * 1000) // In days
|
||||
|
||||
if (config.WorkspaceInactivityInterval > 0 && lastVisit > config.WorkspaceInactivityInterval) {
|
||||
if (!this.checkedWorkspaces.has(workspace)) {
|
||||
this.checkedWorkspaces.add(workspace)
|
||||
this.ctx.warn('Workspace is inactive for too long, skipping for now.', { workspace })
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
checkReconnect (workspace: WorkspaceUuid, event: ClientConnectEvent, worker: GithubWorker): void {
|
||||
if (event === ClientConnectEvent.Refresh || event === ClientConnectEvent.Upgraded) {
|
||||
void this.clients
|
||||
@@ -989,9 +964,15 @@ export class PlatformWorker {
|
||||
getAccountClient(config.AccountsURL, token)
|
||||
.getWorkspaceInfo()
|
||||
.then((wsInfo) => {
|
||||
const res = this.checkWorkspaceIsActive(workspace, wsInfo)
|
||||
if (!res) {
|
||||
this.ctx.warn('Workspace is inactive, removing from clients list.', { workspace })
|
||||
const state = getGithubWorkerState(
|
||||
this.ctx,
|
||||
workspace,
|
||||
wsInfo,
|
||||
config.WorkspaceInactivityInterval,
|
||||
this.checkedWorkspaces
|
||||
)
|
||||
if (state === GithubWorkerWorkspaceState.Skip) {
|
||||
this.ctx.warn('Github worker state is skip, removing from clients list.', { workspace })
|
||||
this.clients.delete(workspace)
|
||||
void worker?.close().catch((err) => {
|
||||
this.ctx.error('Failed to close workspace', { workspace, error: err })
|
||||
@@ -1053,11 +1034,20 @@ export class PlatformWorker {
|
||||
rechecks.push(workspace)
|
||||
continue
|
||||
}
|
||||
const needRecheck = this.checkWorkspaceIsActive(workspace, returnedInfo)
|
||||
if (needRecheck) {
|
||||
const state = getGithubWorkerState(
|
||||
this.ctx,
|
||||
workspace,
|
||||
returnedInfo,
|
||||
config.WorkspaceInactivityInterval,
|
||||
this.checkedWorkspaces
|
||||
)
|
||||
if (state === GithubWorkerWorkspaceState.Wait) {
|
||||
rechecks.push(workspace)
|
||||
continue
|
||||
}
|
||||
if (state === GithubWorkerWorkspaceState.Skip) {
|
||||
continue
|
||||
}
|
||||
await rateLimiter.add(async () => {
|
||||
try {
|
||||
const branding = Object.values(this.brandingMap).find((b) => b.key === returnedInfo?.branding) ?? null
|
||||
|
||||
@@ -24,7 +24,15 @@ import {
|
||||
githubExternalSyncVersion,
|
||||
githubSyncVersion
|
||||
} from '../types'
|
||||
import { collectUpdate, deleteObjects, ensureGraphQLOctokit, errorToObj, getSince, isGHWriteAllowed } from './utils'
|
||||
import {
|
||||
collectUpdate,
|
||||
deleteObjects,
|
||||
ensureGraphQLOctokit,
|
||||
ensureRESTOctokit,
|
||||
errorToObj,
|
||||
getSince,
|
||||
isGHWriteAllowed
|
||||
} from './utils'
|
||||
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import { IssueComment, IssueCommentCreatedEvent, IssueCommentEvent } from '@octokit/webhooks-types'
|
||||
@@ -353,7 +361,10 @@ export class CommentSyncManager implements DocSyncManager {
|
||||
|
||||
if (Object.keys(platformUpdate).length > 0) {
|
||||
// Check and update body with external
|
||||
const okit = (await this.provider.getOctokit(ctx, existing.modifiedBy)) ?? container.container.octokit
|
||||
const okit = ensureRESTOctokit(
|
||||
(await this.provider.getOctokit(ctx, existing.modifiedBy)) ?? container.container.octokit,
|
||||
container
|
||||
)
|
||||
const mdown = await this.provider.getMarkdown(existingComment.message)
|
||||
if (mdown.trim().length > 0) {
|
||||
await okit.rest.issues.updateComment({
|
||||
@@ -426,7 +437,10 @@ export class CommentSyncManager implements DocSyncManager {
|
||||
return {}
|
||||
}
|
||||
const chatMessage = existing as ChatMessage
|
||||
const okit = (await this.provider.getOctokit(ctx, chatMessage.modifiedBy)) ?? container.container.octokit
|
||||
const okit = ensureRESTOctokit(
|
||||
(await this.provider.getOctokit(ctx, chatMessage.modifiedBy)) ?? container.container.octokit,
|
||||
container
|
||||
)
|
||||
|
||||
// No external version yet, create it.
|
||||
try {
|
||||
|
||||
@@ -29,7 +29,6 @@ import github, {
|
||||
GithubIntegrationRepository,
|
||||
GithubIssueStateReason,
|
||||
GithubProject,
|
||||
IntegrationRepositoryData,
|
||||
GithubIssue as TGithubIssue
|
||||
} from '@hcengineering/github'
|
||||
import task, { TaskType, calcRank } from '@hcengineering/task'
|
||||
@@ -523,9 +522,7 @@ export class IssueSyncManager extends IssueSyncManagerBase implements DocSyncMan
|
||||
info.repository as Ref<GithubIntegrationRepository>,
|
||||
container.project,
|
||||
taskTypes[0]._id,
|
||||
repo as GithubIntegrationRepository & {
|
||||
repository: IntegrationRepositoryData
|
||||
},
|
||||
repo,
|
||||
!markdownCompatible
|
||||
)
|
||||
},
|
||||
|
||||
@@ -50,6 +50,17 @@ export function ensureGraphQLOctokit (okit: Octokit | undefined, container: Cont
|
||||
return container.container.octokit
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures an Octokit instance has the REST API available.
|
||||
* If the provided okit doesn't have rest.issues, falls back to container.octokit which is guaranteed to have it.
|
||||
*/
|
||||
export function ensureRESTOctokit (okit: Octokit | undefined, container: ContainerFocus): Octokit {
|
||||
if (okit !== undefined && typeof (okit as any).rest?.issues?.createComment === 'function') {
|
||||
return okit
|
||||
}
|
||||
return container.container.octokit
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
|
||||
@@ -87,6 +87,7 @@ import { ReviewThreadSyncManager } from './sync/reviewThreads'
|
||||
import { ReviewSyncManager } from './sync/reviews'
|
||||
import { appendGuestLinkToImage } from './sync/guest'
|
||||
import { UsersSyncManager, fetchViewerDetails } from './sync/users'
|
||||
import { appendGuestLinkToImage } from './sync/guest'
|
||||
import { errorToObj } from './sync/utils'
|
||||
import {
|
||||
ContainerFocus,
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// Copyright © 2026 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
import {
|
||||
isActiveMode,
|
||||
isArchivingMode,
|
||||
isDeletingMode,
|
||||
type MeasureContext,
|
||||
type WorkspaceInfoWithStatus,
|
||||
type WorkspaceUuid
|
||||
} from '@hcengineering/core'
|
||||
|
||||
/** Whether this pod should run a GithubWorker for the workspace. */
|
||||
export enum GithubWorkerWorkspaceState {
|
||||
/** Active workspace — connect and run worker. */
|
||||
Connect = 'connect',
|
||||
/** Not ready yet (upgrade, creation, …) or too inactive — recheck later; keep existing worker. */
|
||||
Wait = 'wait',
|
||||
/** Disabled, deleting, deleted, or archiving — do not run; drop worker if present. */
|
||||
Skip = 'skip'
|
||||
}
|
||||
|
||||
export function getGithubWorkerState (
|
||||
ctx: MeasureContext,
|
||||
workspace: WorkspaceUuid,
|
||||
workspaceInfo: WorkspaceInfoWithStatus,
|
||||
inactivityIntervalDays: number,
|
||||
checkedWorkspaces: Set<string>,
|
||||
nowMs: number = Date.now()
|
||||
): GithubWorkerWorkspaceState {
|
||||
if (workspaceInfo?.uuid === undefined) {
|
||||
ctx.warn('No workspace exists for workspaceId', { workspace })
|
||||
return GithubWorkerWorkspaceState.Skip
|
||||
}
|
||||
if (workspaceInfo.isDisabled === true || isDeletingMode(workspaceInfo.mode) || isArchivingMode(workspaceInfo.mode)) {
|
||||
ctx.info('Workspace is disabled, deleting, or archived — skipping github worker', {
|
||||
workspace,
|
||||
mode: workspaceInfo.mode,
|
||||
isDisabled: workspaceInfo.isDisabled
|
||||
})
|
||||
return GithubWorkerWorkspaceState.Skip
|
||||
}
|
||||
if (!isActiveMode(workspaceInfo.mode)) {
|
||||
ctx.warn('Workspace is in maintenance, skipping for now.', { workspace, mode: workspaceInfo.mode })
|
||||
return GithubWorkerWorkspaceState.Wait
|
||||
}
|
||||
|
||||
const lastVisitDays = (nowMs - (workspaceInfo.lastVisit ?? 0)) / (3600 * 24 * 1000)
|
||||
|
||||
if (inactivityIntervalDays > 0 && lastVisitDays > inactivityIntervalDays) {
|
||||
if (!checkedWorkspaces.has(workspace)) {
|
||||
checkedWorkspaces.add(workspace)
|
||||
ctx.warn('Workspace is inactive for too long, skipping for now.', { workspace })
|
||||
}
|
||||
return GithubWorkerWorkspaceState.Wait
|
||||
}
|
||||
return GithubWorkerWorkspaceState.Connect
|
||||
}
|
||||
Reference in New Issue
Block a user