From cbf0cf76d33d90b73fd3f3ec7a55631010155c52 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 5 Nov 2024 17:09:32 +0100 Subject: [PATCH 1/5] Use timestamp from runtime --- packages/server/src/automations/utils.ts | 10 +++++++--- packages/types/src/sdk/automations/index.ts | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/server/src/automations/utils.ts b/packages/server/src/automations/utils.ts index 62125ea589..365dc36b68 100644 --- a/packages/server/src/automations/utils.ts +++ b/packages/server/src/automations/utils.ts @@ -70,6 +70,10 @@ export async function processEvent(job: AutomationJob) { const task = async () => { try { + if (isCronTrigger(job.data.automation)) { + // Requires the timestamp at run time + job.data.event.timestamp = Date.now() + } // need to actually await these so that an error can be captured properly console.log("automation running", ...loggingArgs(job)) @@ -210,15 +214,15 @@ export async function enableCronTrigger(appId: any, automation: Automation) { } // make a job id rather than letting Bull decide, makes it easier to handle on way out const jobId = `${appId}_cron_${utils.newid()}` - const job: any = await automationQueue.add( + const job = await automationQueue.add( { automation, - event: { appId, timestamp: Date.now() }, + event: { appId }, }, { repeat: { cron: cronExp }, jobId } ) // Assign cron job ID from bull so we can remove it later if the cron trigger is removed - trigger.cronJobId = job.id + trigger.cronJobId = job.id.toString() // can't use getAppDB here as this is likely to be called from dev app, // but this call could be for dev app or prod app, need to just use what // was passed in diff --git a/packages/types/src/sdk/automations/index.ts b/packages/types/src/sdk/automations/index.ts index 9ceded03ee..ba79d47021 100644 --- a/packages/types/src/sdk/automations/index.ts +++ b/packages/types/src/sdk/automations/index.ts @@ -14,6 +14,7 @@ export interface AutomationDataEvent { row?: Row oldRow?: Row user?: UserBindings + timestamp?: number } export interface AutomationData { From 0667dd9d30cd3038b61fd006d18c907f5a2cf349 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 6 Nov 2024 12:38:58 +0100 Subject: [PATCH 2/5] Add test --- .../backend-core/src/queue/inMemoryQueue.ts | 2 +- .../tests/cron-automations.spec.ts | 49 +++++++++++++++++++ .../server/src/tests/utilities/structures.ts | 32 ++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 packages/server/src/automations/tests/cron-automations.spec.ts diff --git a/packages/backend-core/src/queue/inMemoryQueue.ts b/packages/backend-core/src/queue/inMemoryQueue.ts index 62b971f9f5..1d8544828d 100644 --- a/packages/backend-core/src/queue/inMemoryQueue.ts +++ b/packages/backend-core/src/queue/inMemoryQueue.ts @@ -141,7 +141,7 @@ class InMemoryQueue implements Partial { } else { pushMessage() } - return {} as any + return { id: jobId } as any } /** diff --git a/packages/server/src/automations/tests/cron-automations.spec.ts b/packages/server/src/automations/tests/cron-automations.spec.ts new file mode 100644 index 0000000000..62c8ccd612 --- /dev/null +++ b/packages/server/src/automations/tests/cron-automations.spec.ts @@ -0,0 +1,49 @@ +import tk from "timekeeper" +import "../../environment" +import * as automations from "../index" +import * as setup from "./utilities" +import { basicCronAutomation } from "../../tests/utilities/structures" + +const initialTime = Date.now() +tk.freeze(initialTime) + +const oneMinuteInMs = 60 * 1000 + +describe("cron automations", () => { + let config = setup.getConfig() + + beforeAll(async () => { + await automations.init() + await config.init() + }) + + afterAll(async () => { + await automations.shutdown() + setup.afterAll() + }) + + beforeEach(() => { + tk.freeze(initialTime) + }) + + async function travel(ms: number) { + tk.travel(Date.now() + ms) + } + + it("should initialise the automation timestamp", async () => { + const automation = basicCronAutomation(config.appId!, "* * * * *") + await config.api.automation.post(automation) + await travel(oneMinuteInMs) + await config.publish() + + const automationLogs = await config.getAutomationLogs() + expect(automationLogs.data).toHaveLength(1) + expect(automationLogs.data).toEqual([ + expect.objectContaining({ + trigger: expect.objectContaining({ + outputs: { timestamp: initialTime + oneMinuteInMs }, + }), + }), + ]) + }) +}) diff --git a/packages/server/src/tests/utilities/structures.ts b/packages/server/src/tests/utilities/structures.ts index 49046d9eda..beb03ecf08 100644 --- a/packages/server/src/tests/utilities/structures.ts +++ b/packages/server/src/tests/utilities/structures.ts @@ -245,6 +245,38 @@ export function basicAutomation(appId?: string): Automation { } } +export function basicCronAutomation(appId: string, cron: string): Automation { + const automation: Automation = { + name: `Automation ${generator.guid()}`, + definition: { + trigger: { + stepId: AutomationTriggerStepId.CRON, + name: "test", + tagline: "test", + icon: "test", + description: "test", + type: AutomationStepType.TRIGGER, + id: "test", + inputs: { + cron, + }, + schema: { + inputs: { + properties: {}, + }, + outputs: { + properties: {}, + }, + }, + }, + steps: [], + }, + type: "automation", + appId, + } + return automation +} + export function serverLogAutomation(appId?: string): Automation { return { name: "My Automation", From 8455356cee838afd73c7eec68ff295b396f6615a Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Wed, 6 Nov 2024 16:44:23 +0000 Subject: [PATCH 3/5] turning on AI flags --- packages/backend-core/src/features/features.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend-core/src/features/features.ts b/packages/backend-core/src/features/features.ts index 7bba9f23a4..de6b9cad8b 100644 --- a/packages/backend-core/src/features/features.ts +++ b/packages/backend-core/src/features/features.ts @@ -271,8 +271,8 @@ export const flags = new FlagSet({ [FeatureFlag.AUTOMATION_BRANCHING]: Flag.boolean(true), [FeatureFlag.SQS]: Flag.boolean(true), [FeatureFlag.ENRICHED_RELATIONSHIPS]: Flag.boolean(true), - [FeatureFlag.AI_CUSTOM_CONFIGS]: Flag.boolean(env.isDev()), - [FeatureFlag.BUDIBASE_AI]: Flag.boolean(env.isDev()), + [FeatureFlag.AI_CUSTOM_CONFIGS]: Flag.boolean(true), + [FeatureFlag.BUDIBASE_AI]: Flag.boolean(true), }) type UnwrapPromise = T extends Promise ? U : T From 6fd9a41fb9997d3b6320c2ad4bbf90993d17ded1 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Wed, 6 Nov 2024 17:35:06 +0000 Subject: [PATCH 4/5] Bump version to 3.1.3 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 08a9aa5857..ca6d8d9e81 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.1.2", + "version": "3.1.3", "npmClient": "yarn", "packages": [ "packages/*", From 1b491715ae543ba650cc54c4ebc80562a0890f3a Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Thu, 7 Nov 2024 08:20:15 +0000 Subject: [PATCH 5/5] Bump version to 3.2.0 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index ca6d8d9e81..19b603b1cd 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.1.3", + "version": "3.2.0", "npmClient": "yarn", "packages": [ "packages/*",