diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e201e9f075..5a52658b910 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,3 +3,4 @@ - Fixes issue where all database functions triggered on the default namespace (#2501) - Fixes issue where rules paths were not normalized before reading (#2544) - Functions emulator waits for all functions to finish before exiting (#1813) +- Adds support for deploying functions with a failure policy. diff --git a/package-lock.json b/package-lock.json index 6c7346b4933..bf64a0a4b0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4691,9 +4691,9 @@ } }, "firebase-functions": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.8.0.tgz", - "integrity": "sha512-RFvoS7ZcXrk2sQ918czsjv94p4hnSoD0/e4cZ86XFpa1HbNZBI7ZuSgBCzRvlv6dJ1ArytAL13NpB1Bp2tJ6Yg==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.10.0.tgz", + "integrity": "sha512-1KsZ7vlD6AaWjza++zga8sRwXn9J1YrVcq/gUeEJLL7+WZ1MIVB7ojKsyb3+C1YzpkhlL6iXP/KFN7EvpfvLNA==", "dev": true, "requires": { "@types/express": "4.17.3", diff --git a/package.json b/package.json index 095aa3cc16a..daa4e048c51 100644 --- a/package.json +++ b/package.json @@ -173,7 +173,7 @@ "eslint-plugin-prettier": "^3.1.0", "firebase": "^7.14.0", "firebase-admin": "^8.9.0", - "firebase-functions": "^3.8.0", + "firebase-functions": "^3.10.0", "mocha": "^7.1.1", "nock": "^9.3.3", "nyc": "^15.0.1", diff --git a/src/deploy/functions/release.js b/src/deploy/functions/release.js index 407f6135bc4..a9f7197209a 100644 --- a/src/deploy/functions/release.js +++ b/src/deploy/functions/release.js @@ -152,8 +152,47 @@ module.exports = function(context, options, payload) { var deleteReleaseNames; var existingScheduledFunctions; + // Collect all the functions that have a retry policy + var failurePolicyFunctions = functionsInfo.filter((fn) => { + return !!fn.failurePolicy; + }); + + var failurePolicyFunctionLabels = failurePolicyFunctions.map((fn) => { + return helper.getFunctionLabel(_.get(fn, "name")); + }); + var retryMessage = + "The following functions will be retried in case of failure: " + + clc.bold(failurePolicyFunctionLabels.join(", ")) + + ". " + + "Retried executions are billed as any other execution, and functions are retried repeatedly until they either successfully execute or the maximum retry period has elapsed, which can be up to 7 days. " + + "For safety, you might want to ensure that your functions are idempotent; see https://firebase.google.com/docs/functions/retries to learn more."; + + utils.logLabeledWarning("functions", retryMessage); + + let proceedPrompt = Promise.resolve(true); + if (options.nonInteractive && !options.force) { + throw new FirebaseError("Pass the --force option to deploy functions with a failure policy", { + exit: 1, + }); + } else if (!options.nonInteractive) { + proceedPrompt = promptOnce({ + type: "confirm", + name: "confirm", + default: false, + message: "Would you like to proceed with deployment?", + }); + } + delete payload.functions; - return Promise.resolve(context.existingFunctions) + + return proceedPrompt + .then((proceed) => { + if (!proceed) { + throw new FirebaseError("Deployment canceled.", { exit: 1 }); + } + + return Promise.resolve(context.existingFunctions); + }) .then(function(existingFunctions) { var pluckName = function(functionObject) { return _.get(functionObject, "name"); // e.g.'projects/proj1/locations/us-central1/functions/func' diff --git a/src/functionsDeployHelper.js b/src/functionsDeployHelper.js index c99f2d1a502..5224d57b21d 100644 --- a/src/functionsDeployHelper.js +++ b/src/functionsDeployHelper.js @@ -123,8 +123,10 @@ function getFunctionTrigger(functionInfo) { return _.pick(functionInfo, "httpsTrigger"); } else if (functionInfo.eventTrigger) { var trigger = functionInfo.eventTrigger; + trigger.failurePolicy = functionInfo.failurePolicy; return { eventTrigger: trigger }; } + logger.debug("Unknown trigger type found in:", functionInfo); return new FirebaseError("Could not parse function trigger, unknown trigger type."); }