chore(server): automate IoC 10 - onModelVersionCreateFactory
This commit is contained in:
@@ -2,13 +2,21 @@ import { InsertableAutomationFunctionRun } from '@/modules/automate/domain/types
|
||||
import {
|
||||
AutomationFunctionRunRecord,
|
||||
AutomationRecord,
|
||||
AutomationRevisionRecord,
|
||||
AutomationRevisionWithTriggersFunctions,
|
||||
AutomationRunWithTriggersFunctionRuns,
|
||||
AutomationTokenRecord,
|
||||
AutomationTriggerDefinitionRecord,
|
||||
AutomationTriggerRecordBase,
|
||||
AutomationTriggerType,
|
||||
AutomationWithRevision
|
||||
AutomationWithRevision,
|
||||
BaseTriggerManifest,
|
||||
RunTriggerSource
|
||||
} from '@/modules/automate/helpers/types'
|
||||
import { InsertableAutomationRevision } from '@/modules/automate/repositories/automations'
|
||||
import {
|
||||
InsertableAutomationRevision,
|
||||
InsertableAutomationRun
|
||||
} from '@/modules/automate/repositories/automations'
|
||||
import { AuthCodePayload } from '@/modules/automate/services/authCode'
|
||||
import { ProjectAutomationCreateInput } from '@/modules/core/graph/generated/graphql'
|
||||
import { ContextResourceAccessRules } from '@/modules/core/helpers/token'
|
||||
@@ -82,6 +90,28 @@ export type GetFullAutomationRunById = (
|
||||
automationRunId: string
|
||||
) => Promise<AutomationRunWithTriggersFunctionRuns | null>
|
||||
|
||||
export type GetAutomationRevisions = (params: {
|
||||
automationRevisionIds: string[]
|
||||
}) => Promise<AutomationRevisionRecord[]>
|
||||
|
||||
export type GetAutomationRevision = (params: {
|
||||
automationRevisionId: string
|
||||
}) => Promise<Nullable<AutomationRevisionRecord>>
|
||||
|
||||
export type GetActiveTriggerDefinitions = <
|
||||
T extends AutomationTriggerType = AutomationTriggerType
|
||||
>(
|
||||
params: AutomationTriggerRecordBase<T>
|
||||
) => Promise<AutomationTriggerDefinitionRecord<T>[]>
|
||||
|
||||
export type GetAutomationToken = (
|
||||
automationId: string
|
||||
) => Promise<AutomationTokenRecord | null>
|
||||
|
||||
export type UpsertAutomationRun = (
|
||||
automationRun: InsertableAutomationRun
|
||||
) => Promise<void>
|
||||
|
||||
export type CreateStoredAuthCode = (
|
||||
params: Omit<AuthCodePayload, 'code'>
|
||||
) => Promise<AuthCodePayload>
|
||||
@@ -101,3 +131,11 @@ type KeyPair = {
|
||||
export type GetEncryptionKeyPair = () => Promise<KeyPair>
|
||||
|
||||
export type GetEncryptionKeyPairFor = (publicKey: string) => Promise<KeyPair>
|
||||
|
||||
export type TriggerAutomationRevisionRun = <
|
||||
M extends BaseTriggerManifest = BaseTriggerManifest
|
||||
>(params: {
|
||||
revisionId: string
|
||||
manifest: M
|
||||
source?: RunTriggerSource
|
||||
}) => Promise<{ automationRunId: string }>
|
||||
|
||||
@@ -63,7 +63,7 @@ import {
|
||||
import {
|
||||
createTestAutomationRun,
|
||||
manuallyTriggerAutomation,
|
||||
triggerAutomationRevisionRun
|
||||
triggerAutomationRevisionRunFactory
|
||||
} from '@/modules/automate/services/trigger'
|
||||
import {
|
||||
reportFunctionRunStatusFactory,
|
||||
@@ -531,7 +531,7 @@ export = (FF_AUTOMATE_MODULE_ENABLED
|
||||
getAutomationTriggerDefinitions,
|
||||
getAutomation,
|
||||
getBranchLatestCommits,
|
||||
triggerFunction: triggerAutomationRevisionRun({
|
||||
triggerFunction: triggerAutomationRevisionRunFactory({
|
||||
automateRunTrigger: triggerAutomationRun,
|
||||
getEncryptionKeyPairFor,
|
||||
getFunctionInputDecryptor: getFunctionInputDecryptorFactory({
|
||||
|
||||
@@ -2,16 +2,18 @@ import { moduleLogger } from '@/logging/logging'
|
||||
import { Optional, SpeckleModule } from '@/modules/shared/helpers/typeHelper'
|
||||
import { VersionEvents, VersionsEmitter } from '@/modules/core/events/versionsEmitter'
|
||||
import {
|
||||
onModelVersionCreate,
|
||||
triggerAutomationRevisionRun
|
||||
onModelVersionCreateFactory,
|
||||
triggerAutomationRevisionRunFactory
|
||||
} from '@/modules/automate/services/trigger'
|
||||
import {
|
||||
getActiveTriggerDefinitions,
|
||||
getAutomationRevision,
|
||||
getActiveTriggerDefinitionsFactory,
|
||||
getAutomationFactory,
|
||||
getAutomationRevisionFactory,
|
||||
getAutomationRunFullTriggersFactory,
|
||||
getAutomationTokenFactory,
|
||||
getFullAutomationRevisionMetadataFactory,
|
||||
getFullAutomationRunByIdFactory
|
||||
getFullAutomationRunByIdFactory,
|
||||
upsertAutomationRunFactory
|
||||
} from '@/modules/automate/repositories/automations'
|
||||
import { Scopes } from '@speckle/shared'
|
||||
import { registerOrUpdateScopeFactory } from '@/modules/shared/repositories/scopes'
|
||||
@@ -36,6 +38,7 @@ import db from '@/db/knex'
|
||||
import { AutomationsEmitter } from '@/modules/automate/events/automations'
|
||||
import { publish } from '@/modules/shared/utils/subscriptions'
|
||||
import { AutomateRunsEmitter } from '@/modules/automate/events/runs'
|
||||
import { createAppToken } from '@/modules/core/services/tokens'
|
||||
|
||||
const { FF_AUTOMATE_MODULE_ENABLED } = getFeatureFlags()
|
||||
let quitListeners: Optional<() => void> = undefined
|
||||
@@ -68,12 +71,16 @@ async function initScopes() {
|
||||
const initializeEventListeners = () => {
|
||||
const getAutomationRunFullTriggers = getAutomationRunFullTriggersFactory({ db })
|
||||
|
||||
const triggerFn = triggerAutomationRevisionRun({
|
||||
const triggerFn = triggerAutomationRevisionRunFactory({
|
||||
automateRunTrigger: triggerAutomationRun,
|
||||
getEncryptionKeyPairFor,
|
||||
getFunctionInputDecryptor: getFunctionInputDecryptorFactory({
|
||||
buildDecryptor
|
||||
})
|
||||
}),
|
||||
createAppToken,
|
||||
automateRunsEmitter: AutomateRunsEmitter.emit,
|
||||
getAutomationToken: getAutomationTokenFactory({ db }),
|
||||
upsertAutomationRun: upsertAutomationRunFactory({ db })
|
||||
})
|
||||
const setupStatusUpdateSubscriptionsInvoke = setupStatusUpdateSubscriptionsFactory({
|
||||
getAutomationRunFullTriggers,
|
||||
@@ -93,12 +100,14 @@ const initializeEventListeners = () => {
|
||||
automateRunsEventListener: AutomateRunsEmitter.listen
|
||||
})
|
||||
const getAutomation = getAutomationFactory({ db })
|
||||
const getAutomationRevision = getAutomationRevisionFactory({ db })
|
||||
const getActiveTriggerDefinitions = getActiveTriggerDefinitionsFactory({ db })
|
||||
|
||||
const quitters = [
|
||||
VersionsEmitter.listen(
|
||||
VersionEvents.Created,
|
||||
async ({ modelId, version, projectId }) => {
|
||||
await onModelVersionCreate({
|
||||
await onModelVersionCreateFactory({
|
||||
getAutomation,
|
||||
getAutomationRevision,
|
||||
getTriggers: getActiveTriggerDefinitions,
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import {
|
||||
GetActiveTriggerDefinitions,
|
||||
GetAutomation,
|
||||
GetAutomationRevision,
|
||||
GetAutomationRevisions,
|
||||
GetAutomationRunFullTriggers,
|
||||
GetAutomations,
|
||||
GetAutomationToken,
|
||||
GetFullAutomationRevisionMetadata,
|
||||
GetFullAutomationRunById,
|
||||
GetFunctionRun,
|
||||
@@ -10,7 +14,8 @@ import {
|
||||
StoreAutomationRevision,
|
||||
StoreAutomationToken,
|
||||
UpdateAutomation,
|
||||
UpsertAutomationFunctionRun
|
||||
UpsertAutomationFunctionRun,
|
||||
UpsertAutomationRun
|
||||
} from '@/modules/automate/domain/operations'
|
||||
import {
|
||||
AutomationRunFullTrigger,
|
||||
@@ -86,17 +91,21 @@ const tables = {
|
||||
|
||||
export const generateRevisionId = () => cryptoRandomString({ length: 10 })
|
||||
|
||||
export async function getActiveTriggerDefinitions<
|
||||
T extends AutomationTriggerType = AutomationTriggerType
|
||||
>(params: AutomationTriggerRecordBase<T>) {
|
||||
const { triggeringId, triggerType } = params
|
||||
export const getActiveTriggerDefinitionsFactory =
|
||||
(deps: { db: Knex }): GetActiveTriggerDefinitions =>
|
||||
async <T extends AutomationTriggerType = AutomationTriggerType>(
|
||||
params: AutomationTriggerRecordBase<T>
|
||||
) => {
|
||||
const { triggeringId, triggerType } = params
|
||||
|
||||
const q = AutomationTriggers.knex<AutomationTriggerDefinitionRecord<T>[]>()
|
||||
.where(AutomationTriggers.col.triggeringId, triggeringId)
|
||||
.andWhere(AutomationTriggers.col.triggerType, triggerType)
|
||||
const q = tables
|
||||
.automationTriggers(deps.db)
|
||||
.select<AutomationTriggerDefinitionRecord<T>[]>('*')
|
||||
.where(AutomationTriggers.col.triggeringId, triggeringId)
|
||||
.andWhere(AutomationTriggers.col.triggerType, triggerType)
|
||||
|
||||
return await q
|
||||
}
|
||||
return await q
|
||||
}
|
||||
|
||||
export const getFullAutomationRevisionMetadataFactory =
|
||||
(deps: { db: Knex }): GetFullAutomationRevisionMetadata =>
|
||||
@@ -158,37 +167,46 @@ export type InsertableAutomationRun = AutomationRunRecord & {
|
||||
functionRuns: Omit<AutomationFunctionRunRecord, 'runId'>[]
|
||||
}
|
||||
|
||||
export async function upsertAutomationRun(automationRun: InsertableAutomationRun) {
|
||||
await AutomationRuns.knex()
|
||||
.insert(_.pick(automationRun, AutomationRuns.withoutTablePrefix.cols))
|
||||
.onConflict(AutomationRuns.withoutTablePrefix.col.id)
|
||||
.merge([
|
||||
AutomationRuns.withoutTablePrefix.col.status,
|
||||
AutomationRuns.withoutTablePrefix.col.updatedAt,
|
||||
AutomationRuns.withoutTablePrefix.col.executionEngineRunId
|
||||
export const upsertAutomationRunFactory =
|
||||
(deps: { db: Knex }): UpsertAutomationRun =>
|
||||
async (automationRun: InsertableAutomationRun) => {
|
||||
await tables
|
||||
.automationRuns(deps.db)
|
||||
.insert(_.pick(automationRun, AutomationRuns.withoutTablePrefix.cols))
|
||||
.onConflict(AutomationRuns.withoutTablePrefix.col.id)
|
||||
.merge([
|
||||
AutomationRuns.withoutTablePrefix.col.status,
|
||||
AutomationRuns.withoutTablePrefix.col.updatedAt,
|
||||
AutomationRuns.withoutTablePrefix.col.executionEngineRunId
|
||||
] as Array<keyof AutomationRunRecord>)
|
||||
await Promise.all([
|
||||
tables
|
||||
.automationRunTriggers(deps.db)
|
||||
.insert(
|
||||
automationRun.triggers.map((t) => ({
|
||||
automationRunId: automationRun.id,
|
||||
..._.pick(t, AutomationRunTriggers.withoutTablePrefix.cols)
|
||||
}))
|
||||
)
|
||||
.onConflict()
|
||||
.ignore(),
|
||||
tables
|
||||
.automationFunctionRuns(deps.db)
|
||||
.insert(
|
||||
automationRun.functionRuns.map((f) => ({
|
||||
..._.pick(f, AutomationFunctionRuns.withoutTablePrefix.cols),
|
||||
runId: automationRun.id
|
||||
}))
|
||||
)
|
||||
.onConflict(AutomationFunctionRuns.withoutTablePrefix.col.id)
|
||||
.merge(
|
||||
AutomationFunctionRuns.withoutTablePrefix.cols as Array<
|
||||
keyof AutomationFunctionRunRecord
|
||||
>
|
||||
)
|
||||
])
|
||||
await Promise.all([
|
||||
AutomationRunTriggers.knex()
|
||||
.insert(
|
||||
automationRun.triggers.map((t) => ({
|
||||
automationRunId: automationRun.id,
|
||||
..._.pick(t, AutomationRunTriggers.withoutTablePrefix.cols)
|
||||
}))
|
||||
)
|
||||
.onConflict()
|
||||
.ignore(),
|
||||
AutomationFunctionRuns.knex()
|
||||
.insert(
|
||||
automationRun.functionRuns.map((f) => ({
|
||||
..._.pick(f, AutomationFunctionRuns.withoutTablePrefix.cols),
|
||||
runId: automationRun.id
|
||||
}))
|
||||
)
|
||||
.onConflict(AutomationFunctionRuns.withoutTablePrefix.col.id)
|
||||
.merge(AutomationFunctionRuns.withoutTablePrefix.cols)
|
||||
])
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
export const getFunctionRunFactory =
|
||||
(deps: { db: Knex }): GetFunctionRun =>
|
||||
@@ -421,14 +439,15 @@ export const storeAutomationRevisionFactory =
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAutomationToken(
|
||||
automationId: string
|
||||
): Promise<AutomationTokenRecord | null> {
|
||||
const token = await AutomationTokens.knex<AutomationTokenRecord>()
|
||||
.where(AutomationTokens.col.automationId, automationId)
|
||||
.first()
|
||||
return token || null
|
||||
}
|
||||
export const getAutomationTokenFactory =
|
||||
(deps: { db: Knex }): GetAutomationToken =>
|
||||
async (automationId: string): Promise<AutomationTokenRecord | null> => {
|
||||
const token = await tables
|
||||
.automationTokens(deps.db)
|
||||
.where(AutomationTokens.col.automationId, automationId)
|
||||
.first()
|
||||
return token || null
|
||||
}
|
||||
|
||||
export const getAutomationsFactory =
|
||||
(deps: { db: Knex }): GetAutomations =>
|
||||
@@ -543,27 +562,30 @@ export async function updateAutomationRun(
|
||||
return ret
|
||||
}
|
||||
|
||||
export async function getAutomationRevisions(params: {
|
||||
automationRevisionIds: string[]
|
||||
}) {
|
||||
const { automationRevisionIds } = params
|
||||
if (!automationRevisionIds.length) return []
|
||||
export const getAutomationRevisionsFactory =
|
||||
(deps: { db: Knex }): GetAutomationRevisions =>
|
||||
async (params: { automationRevisionIds: string[] }) => {
|
||||
const { automationRevisionIds } = params
|
||||
if (!automationRevisionIds.length) return []
|
||||
|
||||
const q = AutomationRevisions.knex<AutomationRevisionRecord[]>()
|
||||
.whereIn(AutomationRevisions.col.id, automationRevisionIds)
|
||||
.andWhere(AutomationRevisions.col.active, true)
|
||||
const q = tables
|
||||
.automationRevisions(deps.db)
|
||||
.whereIn(AutomationRevisions.col.id, automationRevisionIds)
|
||||
.andWhere(AutomationRevisions.col.active, true)
|
||||
|
||||
return await q
|
||||
}
|
||||
return await q
|
||||
}
|
||||
|
||||
export async function getAutomationRevision(params: { automationRevisionId: string }) {
|
||||
const { automationRevisionId } = params
|
||||
const revisions = await getAutomationRevisions({
|
||||
automationRevisionIds: [automationRevisionId]
|
||||
})
|
||||
export const getAutomationRevisionFactory =
|
||||
(deps: { db: Knex }): GetAutomationRevision =>
|
||||
async (params: { automationRevisionId: string }) => {
|
||||
const { automationRevisionId } = params
|
||||
const revisions = await getAutomationRevisionsFactory(deps)({
|
||||
automationRevisionIds: [automationRevisionId]
|
||||
})
|
||||
|
||||
return (revisions[0] || null) as Nullable<(typeof revisions)[0]>
|
||||
}
|
||||
return (revisions[0] || null) as Nullable<(typeof revisions)[0]>
|
||||
}
|
||||
|
||||
export async function getLatestAutomationRevisions(params: {
|
||||
automationIds: string[]
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import {
|
||||
InsertableAutomationRun,
|
||||
getActiveTriggerDefinitions,
|
||||
getAutomationToken,
|
||||
getAutomationTriggerDefinitions,
|
||||
upsertAutomationRun,
|
||||
getAutomationRevision,
|
||||
getLatestAutomationRevision,
|
||||
getFullAutomationRevisionMetadataFactory
|
||||
} from '@/modules/automate/repositories/automations'
|
||||
@@ -39,12 +35,21 @@ import { validateStreamAccess } from '@/modules/core/services/streams/streamAcce
|
||||
import { ContextResourceAccessRules } from '@/modules/core/helpers/token'
|
||||
import { TokenResourceIdentifierType } from '@/modules/core/graph/generated/graphql'
|
||||
import { automateLogger } from '@/logging/logging'
|
||||
import { getFunctionInputDecryptorFactory } from '@/modules/automate/services/encryption'
|
||||
import { FunctionInputDecryptor } from '@/modules/automate/services/encryption'
|
||||
import { LibsodiumEncryptionError } from '@/modules/shared/errors/encryption'
|
||||
import { AutomateRunsEmitter } from '@/modules/automate/events/runs'
|
||||
import {
|
||||
AutomateRunsEmitter,
|
||||
AutomateRunsEventsEmitter
|
||||
} from '@/modules/automate/events/runs'
|
||||
import {
|
||||
GetActiveTriggerDefinitions,
|
||||
GetAutomation,
|
||||
GetEncryptionKeyPairFor
|
||||
GetAutomationRevision,
|
||||
GetAutomationToken,
|
||||
GetEncryptionKeyPairFor,
|
||||
GetFullAutomationRevisionMetadata,
|
||||
TriggerAutomationRevisionRun,
|
||||
UpsertAutomationRun
|
||||
} from '@/modules/automate/domain/operations'
|
||||
import { db } from '@/db/knex'
|
||||
|
||||
@@ -55,15 +60,15 @@ const getFullAutomationRevisionMetadata = getFullAutomationRevisionMetadataFacto
|
||||
|
||||
export type OnModelVersionCreateDeps = {
|
||||
getAutomation: GetAutomation
|
||||
getAutomationRevision: typeof getAutomationRevision
|
||||
getTriggers: typeof getActiveTriggerDefinitions
|
||||
triggerFunction: ReturnType<typeof triggerAutomationRevisionRun>
|
||||
getAutomationRevision: GetAutomationRevision
|
||||
getTriggers: GetActiveTriggerDefinitions
|
||||
triggerFunction: TriggerAutomationRevisionRun
|
||||
}
|
||||
|
||||
/**
|
||||
* This should hook into the model version create event
|
||||
*/
|
||||
export const onModelVersionCreate =
|
||||
export const onModelVersionCreateFactory =
|
||||
(deps: OnModelVersionCreateDeps) =>
|
||||
async (params: { modelId: string; versionId: string; projectId: string }) => {
|
||||
const { modelId, versionId, projectId } = params
|
||||
@@ -133,10 +138,10 @@ type InsertableAutomationRunWithExtendedFunctionRuns = Merge<
|
||||
|
||||
type CreateAutomationRunDataDeps = {
|
||||
getEncryptionKeyPairFor: GetEncryptionKeyPairFor
|
||||
getFunctionInputDecryptor: ReturnType<typeof getFunctionInputDecryptorFactory>
|
||||
getFunctionInputDecryptor: FunctionInputDecryptor
|
||||
}
|
||||
|
||||
const createAutomationRunData =
|
||||
const createAutomationRunDataFactory =
|
||||
(deps: CreateAutomationRunDataDeps) =>
|
||||
async (params: {
|
||||
manifests: BaseTriggerManifest[]
|
||||
@@ -215,19 +220,29 @@ const createAutomationRunData =
|
||||
|
||||
export type TriggerAutomationRevisionRunDeps = {
|
||||
automateRunTrigger: typeof triggerAutomationRun
|
||||
getAutomationToken: GetAutomationToken
|
||||
createAppToken: typeof createAppToken
|
||||
upsertAutomationRun: UpsertAutomationRun
|
||||
automateRunsEmitter: AutomateRunsEventsEmitter
|
||||
} & CreateAutomationRunDataDeps
|
||||
|
||||
/**
|
||||
* This triggers a run for a specific automation revision
|
||||
*/
|
||||
export const triggerAutomationRevisionRun =
|
||||
(deps: TriggerAutomationRevisionRunDeps) =>
|
||||
export const triggerAutomationRevisionRunFactory =
|
||||
(deps: TriggerAutomationRevisionRunDeps): TriggerAutomationRevisionRun =>
|
||||
async <M extends BaseTriggerManifest = BaseTriggerManifest>(params: {
|
||||
revisionId: string
|
||||
manifest: M
|
||||
source?: RunTriggerSource
|
||||
}): Promise<{ automationRunId: string }> => {
|
||||
const { automateRunTrigger } = deps
|
||||
const {
|
||||
automateRunTrigger,
|
||||
getAutomationToken,
|
||||
createAppToken,
|
||||
upsertAutomationRun,
|
||||
automateRunsEmitter
|
||||
} = deps
|
||||
const { revisionId, manifest, source = RunTriggerSource.Automatic } = params
|
||||
|
||||
if (!isVersionCreatedTriggerManifest(manifest)) {
|
||||
@@ -236,16 +251,15 @@ export const triggerAutomationRevisionRun =
|
||||
)
|
||||
}
|
||||
|
||||
const { automationWithRevision, userId, automateToken } = await ensureRunConditions(
|
||||
{
|
||||
const { automationWithRevision, userId, automateToken } =
|
||||
await ensureRunConditionsFactory({
|
||||
revisionGetter: getFullAutomationRevisionMetadata,
|
||||
versionGetter: getCommit,
|
||||
automationTokenGetter: getAutomationToken
|
||||
}
|
||||
)({
|
||||
revisionId,
|
||||
manifest
|
||||
})
|
||||
})({
|
||||
revisionId,
|
||||
manifest
|
||||
})
|
||||
|
||||
const triggerManifests = await composeTriggerData({
|
||||
manifest,
|
||||
@@ -274,7 +288,7 @@ export const triggerAutomationRevisionRun =
|
||||
]
|
||||
})
|
||||
|
||||
const automationRun = await createAutomationRunData(deps)({
|
||||
const automationRun = await createAutomationRunDataFactory(deps)({
|
||||
manifests: triggerManifests,
|
||||
automationWithRevision
|
||||
})
|
||||
@@ -306,7 +320,7 @@ export const triggerAutomationRevisionRun =
|
||||
await upsertAutomationRun(automationRun)
|
||||
}
|
||||
|
||||
await AutomateRunsEmitter.emit(AutomateRunsEmitter.events.Created, {
|
||||
await automateRunsEmitter(AutomateRunsEmitter.events.Created, {
|
||||
run: automationRun,
|
||||
manifests: triggerManifests,
|
||||
automation: automationWithRevision,
|
||||
@@ -317,11 +331,11 @@ export const triggerAutomationRevisionRun =
|
||||
return { automationRunId: automationRun.id }
|
||||
}
|
||||
|
||||
export const ensureRunConditions =
|
||||
export const ensureRunConditionsFactory =
|
||||
(deps: {
|
||||
revisionGetter: typeof getFullAutomationRevisionMetadata
|
||||
revisionGetter: GetFullAutomationRevisionMetadata
|
||||
versionGetter: typeof getCommit
|
||||
automationTokenGetter: typeof getAutomationToken
|
||||
automationTokenGetter: GetAutomationToken
|
||||
}) =>
|
||||
async <M extends BaseTriggerManifest = BaseTriggerManifest>(params: {
|
||||
revisionId: string
|
||||
@@ -450,7 +464,7 @@ export type ManuallyTriggerAutomationDeps = {
|
||||
getAutomationTriggerDefinitions: typeof getAutomationTriggerDefinitions
|
||||
getAutomation: GetAutomation
|
||||
getBranchLatestCommits: typeof getBranchLatestCommits
|
||||
triggerFunction: ReturnType<typeof triggerAutomationRevisionRun>
|
||||
triggerFunction: ReturnType<typeof triggerAutomationRevisionRunFactory>
|
||||
}
|
||||
|
||||
export const manuallyTriggerAutomation =
|
||||
@@ -523,6 +537,7 @@ export type CreateTestAutomationRunDeps = {
|
||||
getAutomation: GetAutomation
|
||||
getLatestAutomationRevision: typeof getLatestAutomationRevision
|
||||
getFullAutomationRevisionMetadata: typeof getFullAutomationRevisionMetadata
|
||||
upsertAutomationRun: UpsertAutomationRun
|
||||
} & CreateAutomationRunDataDeps
|
||||
|
||||
/**
|
||||
@@ -534,7 +549,8 @@ export const createTestAutomationRun =
|
||||
const {
|
||||
getAutomation,
|
||||
getLatestAutomationRevision,
|
||||
getFullAutomationRevisionMetadata
|
||||
getFullAutomationRevisionMetadata,
|
||||
upsertAutomationRun
|
||||
} = deps
|
||||
const { projectId, automationId, userId } = params
|
||||
|
||||
@@ -592,7 +608,7 @@ export const createTestAutomationRun =
|
||||
}
|
||||
})
|
||||
|
||||
const automationRunRecord = await createAutomationRunData(deps)({
|
||||
const automationRunRecord = await createAutomationRunDataFactory(deps)({
|
||||
manifests: triggerManifests,
|
||||
automationWithRevision: automationRevisionRecord
|
||||
})
|
||||
|
||||
@@ -4,10 +4,10 @@ import {
|
||||
} from '@/modules/automate/errors/runs'
|
||||
import {
|
||||
ManuallyTriggerAutomationDeps,
|
||||
ensureRunConditions,
|
||||
ensureRunConditionsFactory,
|
||||
manuallyTriggerAutomation,
|
||||
onModelVersionCreate,
|
||||
triggerAutomationRevisionRun
|
||||
onModelVersionCreateFactory,
|
||||
triggerAutomationRevisionRunFactory
|
||||
} from '@/modules/automate/services/trigger'
|
||||
import {
|
||||
AutomationRecord,
|
||||
@@ -36,7 +36,6 @@ import {
|
||||
getAutomationTriggerDefinitions,
|
||||
updateAutomationRevision,
|
||||
updateAutomationRun,
|
||||
upsertAutomationRun,
|
||||
storeAutomationFactory,
|
||||
storeAutomationTokenFactory,
|
||||
storeAutomationRevisionFactory,
|
||||
@@ -44,7 +43,9 @@ import {
|
||||
updateAutomationFactory,
|
||||
getFunctionRunFactory,
|
||||
upsertAutomationFunctionRunFactory,
|
||||
getFullAutomationRunByIdFactory
|
||||
getFullAutomationRunByIdFactory,
|
||||
upsertAutomationRunFactory,
|
||||
getAutomationTokenFactory
|
||||
} from '@/modules/automate/repositories/automations'
|
||||
import { beforeEachContext, truncateTables } from '@/test/hooks'
|
||||
import { Automate } from '@speckle/shared'
|
||||
@@ -73,6 +74,7 @@ import { buildDecryptor } from '@/modules/shared/utils/libsodium'
|
||||
import { mapGqlStatusToDbStatus } from '@/modules/automate/utils/automateFunctionRunStatus'
|
||||
import { db } from '@/db/knex'
|
||||
import { AutomateRunsEmitter } from '@/modules/automate/events/runs'
|
||||
import { createAppToken } from '@/modules/core/services/tokens'
|
||||
|
||||
const { FF_AUTOMATE_MODULE_ENABLED } = getFeatureFlags()
|
||||
|
||||
@@ -84,6 +86,8 @@ const updateAutomation = updateAutomationFactory({ db })
|
||||
const getFunctionRun = getFunctionRunFactory({ db })
|
||||
const upsertAutomationFunctionRun = upsertAutomationFunctionRunFactory({ db })
|
||||
const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
const upsertAutomationRun = upsertAutomationRunFactory({ db })
|
||||
const getAutomationToken = getAutomationTokenFactory({ db })
|
||||
|
||||
;(FF_AUTOMATE_MODULE_ENABLED ? describe : describe.skip)(
|
||||
'Automate triggers @automate',
|
||||
@@ -173,7 +177,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
describe('On model version create', () => {
|
||||
it('No trigger no run', async () => {
|
||||
const triggered: Record<string, BaseTriggerManifest> = {}
|
||||
await onModelVersionCreate({
|
||||
await onModelVersionCreateFactory({
|
||||
getAutomation: async () => ({} as AutomationRecord),
|
||||
getAutomationRevision: async () => ({} as AutomationRevisionRecord),
|
||||
getTriggers: async () => [],
|
||||
@@ -190,7 +194,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
})
|
||||
it('Does not trigger test automations', async () => {
|
||||
const triggered: Record<string, BaseTriggerManifest> = {}
|
||||
await onModelVersionCreate({
|
||||
await onModelVersionCreateFactory({
|
||||
getAutomation: async () => ({ isTestAutomation: true } as AutomationRecord),
|
||||
getAutomationRevision: async () => ({} as AutomationRevisionRecord),
|
||||
getTriggers: async () => [],
|
||||
@@ -224,7 +228,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
const versionId = cryptoRandomString({ length: 10 })
|
||||
const projectId = cryptoRandomString({ length: 10 })
|
||||
|
||||
await onModelVersionCreate({
|
||||
await onModelVersionCreateFactory({
|
||||
getAutomation: async () => ({} as AutomationRecord),
|
||||
getAutomationRevision: async () => ({} as AutomationRevisionRecord),
|
||||
getTriggers: async <
|
||||
@@ -269,7 +273,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
]
|
||||
const triggered: Record<string, VersionCreatedTriggerManifest> = {}
|
||||
const versionId = cryptoRandomString({ length: 10 })
|
||||
await onModelVersionCreate({
|
||||
await onModelVersionCreateFactory({
|
||||
getAutomation: async () => ({} as AutomationRecord),
|
||||
getAutomationRevision: async () => ({} as AutomationRevisionRecord),
|
||||
getTriggers: async <
|
||||
@@ -296,14 +300,18 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
describe('Triggering an automation revision run', () => {
|
||||
it('Throws if run conditions are not met', async () => {
|
||||
try {
|
||||
await triggerAutomationRevisionRun({
|
||||
await triggerAutomationRevisionRunFactory({
|
||||
automateRunTrigger: async () => ({
|
||||
automationRunId: cryptoRandomString({ length: 10 })
|
||||
}),
|
||||
getFunctionInputDecryptor: getFunctionInputDecryptorFactory({
|
||||
buildDecryptor
|
||||
}),
|
||||
getEncryptionKeyPairFor
|
||||
getEncryptionKeyPairFor,
|
||||
createAppToken,
|
||||
automateRunsEmitter: AutomateRunsEmitter.emit,
|
||||
getAutomationToken,
|
||||
upsertAutomationRun
|
||||
})({
|
||||
revisionId: cryptoRandomString({ length: 10 }),
|
||||
manifest: <VersionCreatedTriggerManifest>{
|
||||
@@ -383,14 +391,18 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
]
|
||||
})
|
||||
const thrownError = 'trigger failed'
|
||||
const { automationRunId } = await triggerAutomationRevisionRun({
|
||||
const { automationRunId } = await triggerAutomationRevisionRunFactory({
|
||||
automateRunTrigger: async () => {
|
||||
throw new Error(thrownError)
|
||||
},
|
||||
getFunctionInputDecryptor: getFunctionInputDecryptorFactory({
|
||||
buildDecryptor
|
||||
}),
|
||||
getEncryptionKeyPairFor
|
||||
getEncryptionKeyPairFor,
|
||||
createAppToken,
|
||||
automateRunsEmitter: AutomateRunsEmitter.emit,
|
||||
getAutomationToken,
|
||||
upsertAutomationRun
|
||||
})({
|
||||
revisionId: automationRevisionId,
|
||||
manifest: <VersionCreatedTriggerManifest>{
|
||||
@@ -476,14 +488,18 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
]
|
||||
})
|
||||
const executionEngineRunId = cryptoRandomString({ length: 10 })
|
||||
const { automationRunId } = await triggerAutomationRevisionRun({
|
||||
const { automationRunId } = await triggerAutomationRevisionRunFactory({
|
||||
automateRunTrigger: async () => ({
|
||||
automationRunId: executionEngineRunId
|
||||
}),
|
||||
getFunctionInputDecryptor: getFunctionInputDecryptorFactory({
|
||||
buildDecryptor
|
||||
}),
|
||||
getEncryptionKeyPairFor
|
||||
getEncryptionKeyPairFor,
|
||||
createAppToken,
|
||||
automateRunsEmitter: AutomateRunsEmitter.emit,
|
||||
getAutomationToken,
|
||||
upsertAutomationRun
|
||||
})({
|
||||
revisionId: automationRevisionId,
|
||||
manifest: <VersionCreatedTriggerManifest>{
|
||||
@@ -509,7 +525,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
describe('Run conditions are NOT met if', () => {
|
||||
it("the referenced revision doesn't exist", async () => {
|
||||
try {
|
||||
await ensureRunConditions({
|
||||
await ensureRunConditionsFactory({
|
||||
revisionGetter: async () => null,
|
||||
versionGetter: async () => undefined,
|
||||
automationTokenGetter: async () => null
|
||||
@@ -531,7 +547,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
})
|
||||
it('the automation is not enabled', async () => {
|
||||
try {
|
||||
await ensureRunConditions({
|
||||
await ensureRunConditionsFactory({
|
||||
revisionGetter: async () => ({
|
||||
id: cryptoRandomString({ length: 10 }),
|
||||
name: cryptoRandomString({ length: 10 }),
|
||||
@@ -574,7 +590,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
})
|
||||
it('the revision is not active', async () => {
|
||||
try {
|
||||
await ensureRunConditions({
|
||||
await ensureRunConditionsFactory({
|
||||
revisionGetter: async () => ({
|
||||
id: cryptoRandomString({ length: 10 }),
|
||||
name: cryptoRandomString({ length: 10 }),
|
||||
@@ -617,7 +633,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
})
|
||||
it("the revision doesn't have the referenced trigger", async () => {
|
||||
try {
|
||||
await ensureRunConditions({
|
||||
await ensureRunConditionsFactory({
|
||||
revisionGetter: async () => ({
|
||||
id: cryptoRandomString({ length: 10 }),
|
||||
createdAt: new Date(),
|
||||
@@ -667,7 +683,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
}
|
||||
|
||||
try {
|
||||
await ensureRunConditions({
|
||||
await ensureRunConditionsFactory({
|
||||
revisionGetter: async () => ({
|
||||
id: cryptoRandomString({ length: 10 }),
|
||||
name: cryptoRandomString({ length: 10 }),
|
||||
@@ -716,7 +732,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
}
|
||||
|
||||
try {
|
||||
await ensureRunConditions({
|
||||
await ensureRunConditionsFactory({
|
||||
revisionGetter: async () => ({
|
||||
id: cryptoRandomString({ length: 10 }),
|
||||
name: cryptoRandomString({ length: 10 }),
|
||||
@@ -766,7 +782,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
}
|
||||
|
||||
try {
|
||||
await ensureRunConditions({
|
||||
await ensureRunConditionsFactory({
|
||||
revisionGetter: async () => ({
|
||||
id: cryptoRandomString({ length: 10 }),
|
||||
name: cryptoRandomString({ length: 10 }),
|
||||
@@ -829,7 +845,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
projectId: cryptoRandomString({ length: 10 })
|
||||
}
|
||||
try {
|
||||
await ensureRunConditions({
|
||||
await ensureRunConditionsFactory({
|
||||
revisionGetter: async () => ({
|
||||
id: cryptoRandomString({ length: 10 }),
|
||||
name: cryptoRandomString({ length: 10 }),
|
||||
@@ -890,7 +906,7 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
projectId: cryptoRandomString({ length: 10 })
|
||||
}
|
||||
try {
|
||||
await ensureRunConditions({
|
||||
await ensureRunConditionsFactory({
|
||||
revisionGetter: async () => ({
|
||||
id: cryptoRandomString({ length: 10 }),
|
||||
name: cryptoRandomString({ length: 10 }),
|
||||
@@ -953,14 +969,18 @@ const getFullAutomationRunById = getFullAutomationRunByIdFactory({ db })
|
||||
getAutomationTriggerDefinitions,
|
||||
getAutomation,
|
||||
getBranchLatestCommits,
|
||||
triggerFunction: triggerAutomationRevisionRun({
|
||||
triggerFunction: triggerAutomationRevisionRunFactory({
|
||||
automateRunTrigger: async () => ({
|
||||
automationRunId: cryptoRandomString({ length: 10 })
|
||||
}),
|
||||
getFunctionInputDecryptor: getFunctionInputDecryptorFactory({
|
||||
buildDecryptor
|
||||
}),
|
||||
getEncryptionKeyPairFor
|
||||
getEncryptionKeyPairFor,
|
||||
createAppToken,
|
||||
automateRunsEmitter: AutomateRunsEmitter.emit,
|
||||
getAutomationToken,
|
||||
upsertAutomationRun
|
||||
}),
|
||||
...(overrides || {})
|
||||
})
|
||||
|
||||
@@ -61,7 +61,7 @@ import {
|
||||
AutomationTriggerDefinitionRecord
|
||||
} from '@/modules/automate/helpers/types'
|
||||
import {
|
||||
getAutomationRevisions,
|
||||
getAutomationRevisionsFactory,
|
||||
getAutomationRunsTriggers,
|
||||
getAutomationsFactory,
|
||||
getFunctionAutomationCounts,
|
||||
@@ -91,6 +91,7 @@ const simpleTupleCacheKey = (key: [string, string]) => `${key[0]}:${key[1]}`
|
||||
const getStreamPendingModels = getStreamPendingModelsFactory({ db })
|
||||
const getAppScopes = getAppScopesFactory({ db })
|
||||
const getAutomations = getAutomationsFactory({ db })
|
||||
const getAutomationRevisions = getAutomationRevisionsFactory({ db })
|
||||
|
||||
/**
|
||||
* TODO: Lazy load DataLoaders to reduce memory usage
|
||||
|
||||
Reference in New Issue
Block a user