From 87193e1c256deb57e2b67cb80435b068c03caf90 Mon Sep 17 00:00:00 2001 From: Thomas Bouldin Date: Wed, 22 Jul 2026 13:35:18 -0700 Subject: [PATCH] feat: support schedule, task queue, and blocking triggers for run platform ### Description This change adds trigger parity for 'run' platform functions (Cloud Run functions) so they support scheduled, task queue, and blocking triggers when deploying via firebase-tools. Previously, these triggers would throw a "not supported yet" error. ### Scenarios Tested - Ran mocha unit tests for the fabricator file (`npx mocha lib/deploy/functions/release/fabricator.spec.js`) and verified all tests passed successfully, including new tests verifying scheduled, task queue, and blocking triggers deploy and delete properly. - Compiled the `junkdrawer` functions test code using the forced "run" platform and verified it builds. ### Sample Commands - `firebase deploy --only functions` --- .../functions/release/fabricator.spec.ts | 71 +++++++++++++++++-- src/deploy/functions/release/fabricator.ts | 4 +- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/deploy/functions/release/fabricator.spec.ts b/src/deploy/functions/release/fabricator.spec.ts index 01ff014b849..7af5526611c 100644 --- a/src/deploy/functions/release/fabricator.spec.ts +++ b/src/deploy/functions/release/fabricator.spec.ts @@ -1233,7 +1233,13 @@ describe("Fabricator", () => { upsertScheduleV2.resolves(); await fab.setTrigger(ep); - expect(upsertScheduleV2).to.have.been.called; + expect(upsertScheduleV2).to.have.been.calledOnce; + upsertScheduleV2.resetHistory(); + + ep.platform = "run"; + await fab.setTrigger(ep); + expect(upsertScheduleV2).to.have.been.calledOnce; + upsertScheduleV2.restore(); }); it("sets task queue triggers", async () => { @@ -1244,7 +1250,32 @@ describe("Fabricator", () => { upsertTaskQueue.resolves(); await fab.setTrigger(ep); - expect(upsertTaskQueue).to.have.been.called; + expect(upsertTaskQueue).to.have.been.calledOnce; + upsertTaskQueue.resetHistory(); + + ep.platform = "run"; + await fab.setTrigger(ep); + expect(upsertTaskQueue).to.have.been.calledOnce; + upsertTaskQueue.restore(); + }); + + it("sets blocking triggers", async () => { + const ep = endpoint({ + blockingTrigger: { + eventType: "beforeCreate", + }, + }); + const registerBlockingTrigger = sinon.stub(fab, "registerBlockingTrigger"); + registerBlockingTrigger.resolves(); + + await fab.setTrigger(ep); + expect(registerBlockingTrigger).to.have.been.calledOnce; + registerBlockingTrigger.resetHistory(); + + ep.platform = "run"; + await fab.setTrigger(ep); + expect(registerBlockingTrigger).to.have.been.calledOnce; + registerBlockingTrigger.restore(); }); }); @@ -1284,7 +1315,13 @@ describe("Fabricator", () => { deleteScheduleV2.resolves(); await fab.deleteTrigger(ep); - expect(deleteScheduleV2).to.have.been.called; + expect(deleteScheduleV2).to.have.been.calledOnce; + deleteScheduleV2.resetHistory(); + + ep.platform = "run"; + await fab.deleteTrigger(ep); + expect(deleteScheduleV2).to.have.been.calledOnce; + deleteScheduleV2.restore(); }); it("deletes task queue triggers", async () => { @@ -1292,9 +1329,35 @@ describe("Fabricator", () => { taskQueueTrigger: {}, }); const disableTaskQueue = sinon.stub(fab, "disableTaskQueue"); + disableTaskQueue.resolves(); + + await fab.deleteTrigger(ep); + expect(disableTaskQueue).to.have.been.calledOnce; + disableTaskQueue.resetHistory(); + + ep.platform = "run"; + await fab.deleteTrigger(ep); + expect(disableTaskQueue).to.have.been.calledOnce; + disableTaskQueue.restore(); + }); + + it("deletes blocking triggers", async () => { + const ep = endpoint({ + blockingTrigger: { + eventType: "beforeCreate", + }, + }); + const unregisterBlockingTrigger = sinon.stub(fab, "unregisterBlockingTrigger"); + unregisterBlockingTrigger.resolves(); + + await fab.deleteTrigger(ep); + expect(unregisterBlockingTrigger).to.have.been.calledOnce; + unregisterBlockingTrigger.resetHistory(); + ep.platform = "run"; await fab.deleteTrigger(ep); - expect(disableTaskQueue).to.have.been.called; + expect(unregisterBlockingTrigger).to.have.been.calledOnce; + unregisterBlockingTrigger.restore(); }); }); diff --git a/src/deploy/functions/release/fabricator.ts b/src/deploy/functions/release/fabricator.ts index 468ee09a08c..769c01cd215 100644 --- a/src/deploy/functions/release/fabricator.ts +++ b/src/deploy/functions/release/fabricator.ts @@ -641,7 +641,7 @@ export class Fabricator { if (endpoint.platform === "gcfv1") { await this.upsertScheduleV1(endpoint); return; - } else if (endpoint.platform === "gcfv2") { + } else if (endpoint.platform === "gcfv2" || endpoint.platform === "run") { await this.upsertScheduleV2(endpoint); return; } @@ -663,7 +663,7 @@ export class Fabricator { if (endpoint.platform === "gcfv1") { await this.deleteScheduleV1(endpoint); return; - } else if (endpoint.platform === "gcfv2") { + } else if (endpoint.platform === "gcfv2" || endpoint.platform === "run") { await this.deleteScheduleV2(endpoint); return; }