diff --git a/lib/tools/auth0/handlers/actions.js b/lib/tools/auth0/handlers/actions.js index 37eb50d9f1c40fbb08cdc4dd6b5c68b0906f283f..696790347d28d362b3556e0c49c536453d662e85 100644 --- a/lib/tools/auth0/handlers/actions.js +++ b/lib/tools/auth0/handlers/actions.js @@ -49,7 +49,8 @@ const default_1 = __importStar(require("./default")); const logger_1 = __importDefault(require("../../../logger")); const utils_1 = require("../../utils"); const client_1 = require("../client"); -const MAX_ACTION_DEPLOY_RETRY_ATTEMPTS = 60; // 60 * 2s => 2 min timeout +const INITIAL_BUILD_VALIDATION_DELAY = 1000; // 1 second +const MAX_BUILD_VALIDATION_DELAY = 20000; // 20 seconds // With this schema, we can only validate property types but not valid properties on per type basis exports.schema = { type: 'array', @@ -131,6 +132,29 @@ class ActionHandler extends default_1.default { stripUpdateFields: ['deployed', 'status'], }); } + async verifyBuilt(action) { + let delay = INITIAL_BUILD_VALIDATION_DELAY; + let waitTime = 0; + + while (waitTime <= MAX_BUILD_VALIDATION_DELAY) { + // Give action some time to build before first check + await (0, utils_1.sleep)(delay); + waitTime += delay; + delay *= 2; + + const { status } = await this.client.actions.get(action.id); + + if (status === 'built') { + return; + } + + if (status === 'failed') { + throw new Error(`${this.type} ${this.objString(action)}\nBuild failed.`); + } + } + + throw new Error(`Timeout: Failed to build ${this.type} ${this.objString(action)}`); + } async createAction(action) { // Strip the deployed flag const addAction = { ...action }; @@ -145,10 +169,13 @@ class ActionHandler extends default_1.default { if (createdAction?.id) { action.id = createdAction.id; } + await this.verifyBuilt(action); return createdAction; } async updateAction(actionId, action) { - return this.client.actions.update(actionId, action); + const updatedAction = await this.client.actions.update(actionId, action); + await this.verifyBuilt(updatedAction); + return updatedAction; } async deleteAction(actionId) { if (!this.client.actions || typeof this.client.actions.delete !== 'function') { @@ -174,27 +201,7 @@ class ActionHandler extends default_1.default { .promise(); } async deployAction(action) { - try { - await this.client.actions.deploy(action.id); - } - catch (err) { - // Retry if pending build. - if (err.message && err.message.includes("must be in the 'built' state")) { - if (!action.retry_count) { - logger_1.default.info(`[${this.type}]: Waiting for build to complete ${this.objString(action)}`); - action.retry_count = 1; - } - if (action.retry_count > MAX_ACTION_DEPLOY_RETRY_ATTEMPTS) { - throw err; - } - await (0, utils_1.sleep)(2000); - action.retry_count += 1; - await this.deployAction(action); - } - else { - throw err; - } - } + await this.client.actions.deploy(action.id); } async actionChanges(action, found) { const actionChanges = {};