diff --git a/packages/server/modules/automate/domain/operations.ts b/packages/server/modules/automate/domain/operations.ts index 41599b1a0..8e8aad365 100644 --- a/packages/server/modules/automate/domain/operations.ts +++ b/packages/server/modules/automate/domain/operations.ts @@ -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 +export type GetAutomationRevisions = (params: { + automationRevisionIds: string[] +}) => Promise + +export type GetAutomationRevision = (params: { + automationRevisionId: string +}) => Promise> + +export type GetActiveTriggerDefinitions = < + T extends AutomationTriggerType = AutomationTriggerType +>( + params: AutomationTriggerRecordBase +) => Promise[]> + +export type GetAutomationToken = ( + automationId: string +) => Promise + +export type UpsertAutomationRun = ( + automationRun: InsertableAutomationRun +) => Promise + export type CreateStoredAuthCode = ( params: Omit ) => Promise @@ -101,3 +131,11 @@ type KeyPair = { export type GetEncryptionKeyPair = () => Promise export type GetEncryptionKeyPairFor = (publicKey: string) => Promise + +export type TriggerAutomationRevisionRun = < + M extends BaseTriggerManifest = BaseTriggerManifest +>(params: { + revisionId: string + manifest: M + source?: RunTriggerSource +}) => Promise<{ automationRunId: string }> diff --git a/packages/server/modules/automate/graph/resolvers/automate.ts b/packages/server/modules/automate/graph/resolvers/automate.ts index 74d8d6d50..a3aaa47a2 100644 --- a/packages/server/modules/automate/graph/resolvers/automate.ts +++ b/packages/server/modules/automate/graph/resolvers/automate.ts @@ -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({ diff --git a/packages/server/modules/automate/index.ts b/packages/server/modules/automate/index.ts index 730b3a85c..016566108 100644 --- a/packages/server/modules/automate/index.ts +++ b/packages/server/modules/automate/index.ts @@ -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, diff --git a/packages/server/modules/automate/repositories/automations.ts b/packages/server/modules/automate/repositories/automations.ts index 1dff1b56b..f1e756eaa 100644 --- a/packages/server/modules/automate/repositories/automations.ts +++ b/packages/server/modules/automate/repositories/automations.ts @@ -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) { - const { triggeringId, triggerType } = params +export const getActiveTriggerDefinitionsFactory = + (deps: { db: Knex }): GetActiveTriggerDefinitions => + async ( + params: AutomationTriggerRecordBase + ) => { + const { triggeringId, triggerType } = params - const q = AutomationTriggers.knex[]>() - .where(AutomationTriggers.col.triggeringId, triggeringId) - .andWhere(AutomationTriggers.col.triggerType, triggerType) + const q = tables + .automationTriggers(deps.db) + .select[]>('*') + .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[] } -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) + 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 { - const token = await AutomationTokens.knex() - .where(AutomationTokens.col.automationId, automationId) - .first() - return token || null -} +export const getAutomationTokenFactory = + (deps: { db: Knex }): GetAutomationToken => + async (automationId: string): Promise => { + 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() - .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[] diff --git a/packages/server/modules/automate/services/trigger.ts b/packages/server/modules/automate/services/trigger.ts index 5e2c6f55c..b22d43442 100644 --- a/packages/server/modules/automate/services/trigger.ts +++ b/packages/server/modules/automate/services/trigger.ts @@ -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 + 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 + 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 (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 (params: { revisionId: string @@ -450,7 +464,7 @@ export type ManuallyTriggerAutomationDeps = { getAutomationTriggerDefinitions: typeof getAutomationTriggerDefinitions getAutomation: GetAutomation getBranchLatestCommits: typeof getBranchLatestCommits - triggerFunction: ReturnType + triggerFunction: ReturnType } 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 }) diff --git a/packages/server/modules/automate/tests/trigger.spec.ts b/packages/server/modules/automate/tests/trigger.spec.ts index 87272104a..e8a38b715 100644 --- a/packages/server/modules/automate/tests/trigger.spec.ts +++ b/packages/server/modules/automate/tests/trigger.spec.ts @@ -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 = {} - 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 = {} - 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 = {} 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: { @@ -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: { @@ -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: { @@ -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 || {}) }) diff --git a/packages/server/modules/core/loaders.ts b/packages/server/modules/core/loaders.ts index 2ba89850a..f1e76f28f 100644 --- a/packages/server/modules/core/loaders.ts +++ b/packages/server/modules/core/loaders.ts @@ -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