From 6f4b55c0f508937b2108b8fcd9f82553ed5b3c1b Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Fri, 16 Oct 2020 12:38:07 +0100 Subject: [PATCH 01/13] making deploy process async, adding local deployment history --- .../pages/[application]/deploy/index.svelte | 30 +++- .../src/api/controllers/deploy/index.js | 166 +++++++++++++++--- packages/server/src/api/routes/deploy.js | 9 +- 3 files changed, 179 insertions(+), 26 deletions(-) diff --git a/packages/builder/src/pages/[application]/deploy/index.svelte b/packages/builder/src/pages/[application]/deploy/index.svelte index 2884a4570e..4ab9cd2789 100644 --- a/packages/builder/src/pages/[application]/deploy/index.svelte +++ b/packages/builder/src/pages/[application]/deploy/index.svelte @@ -1,4 +1,5 @@
@@ -60,6 +74,11 @@ Rocket flying through sky +
+ {#each deployments as deployment} +
{JSON.stringify(deployment)}
+ {/each} +
diff --git a/packages/server/src/api/controllers/deploy/index.js b/packages/server/src/api/controllers/deploy/index.js index 327f820a7e..fd1bc65ef1 100644 --- a/packages/server/src/api/controllers/deploy/index.js +++ b/packages/server/src/api/controllers/deploy/index.js @@ -6,6 +6,7 @@ const { updateDeploymentQuota, } = require("./aws") const { DocumentTypes, SEPARATOR, UNICODE_MAX } = require("../../../db/utils") +const newid = require("../../../db/newid") function replicate(local, remote) { return new Promise((resolve, reject) => { @@ -61,47 +62,164 @@ async function getCurrentInstanceQuota(instanceId) { } } -exports.deployApp = async function(ctx) { - try { - const clientAppLookupDB = new PouchDB("client_app_lookup") - const { clientId } = await clientAppLookupDB.get(ctx.user.appId) +async function storeLocalDeploymentHistory(deployment) { + const db = new PouchDB(deployment.instanceId) - const instanceQuota = await getCurrentInstanceQuota(ctx.user.instanceId) + let deploymentDoc + try { + deploymentDoc = await db.get("_local/deployments") + } catch (err) { + deploymentDoc = { _id: "_local/deployments", history: {} } + } + + const deploymentId = deployment._id || newid() + + // first time deployment + if (!deploymentDoc.history[deploymentId]) + deploymentDoc.history[deploymentId] = {} + + deploymentDoc.history[deploymentId] = { + ...deploymentDoc.history[deploymentId], + ...deployment, + updatedAt: Date.now(), + } + + await db.put(deploymentDoc) + return { + _id: deploymentId, + ...deploymentDoc.history[deploymentId], + } +} + +async function deployApp({ instanceId, appId, clientId, deploymentId }) { + try { + const instanceQuota = await getCurrentInstanceQuota(instanceId) const credentials = await verifyDeployment({ - instanceId: ctx.user.instanceId, - appId: ctx.user.appId, + instanceId, + appId, quota: instanceQuota, }) - ctx.log.info(`Uploading assets for appID ${ctx.user.appId} assets to s3..`) + console.log(`Uploading assets for appID ${appId} assets to s3..`) - if (credentials.errors) { - ctx.throw(500, credentials.errors) - return - } + if (credentials.errors) throw new Error(credentials.errors) - await uploadAppAssets({ - clientId, - appId: ctx.user.appId, - instanceId: ctx.user.instanceId, - ...credentials, - }) + await uploadAppAssets({ clientId, appId, instanceId, ...credentials }) // replicate the DB to the couchDB cluster in prod - ctx.log.info("Replicating local PouchDB to remote..") + console.log("Replicating local PouchDB to remote..") await replicateCouch({ - instanceId: ctx.user.instanceId, + instanceId, clientId, credentials: credentials.couchDbCreds, }) await updateDeploymentQuota(credentials.quota) - ctx.body = { + await storeLocalDeploymentHistory({ + _id: deploymentId, + instanceId, + quota: credentials.quota, status: "SUCCESS", - completed: Date.now(), - } + }) } catch (err) { - ctx.throw(err.status || 500, `Deployment Failed: ${err.message}`) + await storeLocalDeploymentHistory({ + _id: deploymentId, + instanceId, + status: "FAILURE", + err: err.message, + }) + throw new Error(`Deployment Failed: ${err.message}`) } } + +exports.fetchDeployments = async function(ctx) { + try { + const db = new PouchDB(ctx.user.instanceId) + const deploymentDoc = await db.get("_local/deployments") + ctx.body = Object.values(deploymentDoc.history) + } catch (err) { + ctx.body = [] + } +} + +exports.deploymentProgress = async function(ctx) { + try { + const db = new PouchDB(ctx.user.instanceId) + const deploymentDoc = await db.get("_local/deployments") + ctx.body = deploymentDoc[ctx.params.deploymentId] + } catch (err) { + ctx.throw( + 500, + `Error fetching data for deployment ${ctx.params.deploymentId}` + ) + } +} + +exports.deployApp = async function(ctx) { + const clientAppLookupDB = new PouchDB("client_app_lookup") + const { clientId } = await clientAppLookupDB.get(ctx.user.appId) + + const deployment = await storeLocalDeploymentHistory({ + instanceId: ctx.user.instanceId, + appId: ctx.user.appId, + status: "PENDING", + }) + + deployApp({ + ...ctx.user, + clientId, + deploymentId: deployment._id, + }) + + ctx.body = deployment + + // const instanceQuota = await getCurrentInstanceQuota(ctx.user.instanceId) + // const credentials = await verifyDeployment({ + // instanceId: ctx.user.instanceId, + // appId: ctx.user.appId, + // quota: instanceQuota, + // }) + + // ctx.log.info(`Uploading assets for appID ${ctx.user.appId} assets to s3..`) + + // if (credentials.errors) { + // ctx.throw(500, credentials.errors) + // return + // } + + // await uploadAppAssets({ + // clientId, + // appId: ctx.user.appId, + // instanceId: ctx.user.instanceId, + // ...credentials, + // }) + + // // replicate the DB to the couchDB cluster in prod + // ctx.log.info("Replicating local PouchDB to remote..") + // await replicateCouch({ + // instanceId: ctx.user.instanceId, + // clientId, + // credentials: credentials.couchDbCreds, + // }) + + // await updateDeploymentQuota(credentials.quota) + + // const deployment = await storeLocalDeploymentHistory({ + // quota: credentials.quota, + // status: "SUCCESS", + // }) + + // ctx.body = { + // status: "SUCCESS", + // completed: Date.now(), + // } + // } catch (err) { + // ctx.throw(err.status || 500, `Deployment Failed: ${err.message}`) + // await storeLocalDeploymentHistory({ + // appId: ctx.user.appId, + // instanceId: ctx.user.instanceId, + // status: "FAILURE", + // }) + // } +} diff --git a/packages/server/src/api/routes/deploy.js b/packages/server/src/api/routes/deploy.js index eab5680859..4f7aa9b33b 100644 --- a/packages/server/src/api/routes/deploy.js +++ b/packages/server/src/api/routes/deploy.js @@ -5,6 +5,13 @@ const { BUILDER } = require("../../utilities/accessLevels") const router = Router() -router.post("/deploy", authorized(BUILDER), controller.deployApp) +router + .get("/api/deployments", authorized(BUILDER), controller.fetchDeployments) + .get( + "/api/deploy/:deploymentId", + authorized(BUILDER), + controller.deploymentProgress + ) + .post("/api/deploy", authorized(BUILDER), controller.deployApp) module.exports = router From 71ceee4299dc8165ff6003101551889456e6e707 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Sat, 17 Oct 2020 15:13:25 +0100 Subject: [PATCH 02/13] deployment history rendering in side bar --- .../deploy/DeploymentHistory.svelte | 122 ++++++++++++++++++ .../pages/[application]/deploy/index.svelte | 20 +-- 2 files changed, 126 insertions(+), 16 deletions(-) create mode 100644 packages/builder/src/components/deploy/DeploymentHistory.svelte diff --git a/packages/builder/src/components/deploy/DeploymentHistory.svelte b/packages/builder/src/components/deploy/DeploymentHistory.svelte new file mode 100644 index 0000000000..d9dc549294 --- /dev/null +++ b/packages/builder/src/components/deploy/DeploymentHistory.svelte @@ -0,0 +1,122 @@ + + +
+ Deployment History + {#if deployments.length > 0} + + + View Your Deployed App → + + + {/if} + {#each deployments as deployment} +
+
+ + {formatDate(deployment.updatedAt, 'fullDate')} + + + {formatDate(deployment.updatedAt, 'timeOnly')} + +
+
+ {deployment.status} +
+
+ {/each} +
+ + diff --git a/packages/builder/src/pages/[application]/deploy/index.svelte b/packages/builder/src/pages/[application]/deploy/index.svelte index 4ab9cd2789..afeb17f5e2 100644 --- a/packages/builder/src/pages/[application]/deploy/index.svelte +++ b/packages/builder/src/pages/[application]/deploy/index.svelte @@ -5,6 +5,7 @@ import { notifier } from "builderStore/store/notifications" import api from "builderStore/api" import Spinner from "components/common/Spinner.svelte" + import DeploymentHistory from "components/deploy/DeploymentHistory.svelte" import analytics from "analytics" let deployed = false @@ -43,8 +44,8 @@ async function fetchDeployments() { try { - const response = api.get(`/api/deployments`) - deployments = await response.json + const response = await api.get(`/api/deployments`) + deployments = await response.json() } catch (err) { console.error(err) notifier.danger("Error fetching deployment history. Please try again.") @@ -74,11 +75,7 @@ Rocket flying through sky -
- {#each deployments as deployment} -
{JSON.stringify(deployment)}
- {/each} -
+ From ee5b039c767092d3f55aa2d1817ab463b520ba70 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Sat, 17 Oct 2020 18:06:00 +0100 Subject: [PATCH 03/13] Fix unrecoverable crash when the screen URL param is not a valid screen --- .../frontend/[page]/[screen]/_layout.svelte | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/packages/builder/src/pages/[application]/frontend/[page]/[screen]/_layout.svelte b/packages/builder/src/pages/[application]/frontend/[page]/[screen]/_layout.svelte index 097ca48073..3702e0da45 100644 --- a/packages/builder/src/pages/[application]/frontend/[page]/[screen]/_layout.svelte +++ b/packages/builder/src/pages/[application]/frontend/[page]/[screen]/_layout.svelte @@ -1,6 +1,6 @@ From 0116f12ad5b34d43fac361afeb3b85fc65ac241a Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Sat, 17 Oct 2020 18:20:31 +0100 Subject: [PATCH 05/13] Add option to create link when creating new screen --- .../userInterface/NewScreenModal.svelte | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/builder/src/components/userInterface/NewScreenModal.svelte b/packages/builder/src/components/userInterface/NewScreenModal.svelte index 6d02439c1b..7d6677ce17 100644 --- a/packages/builder/src/components/userInterface/NewScreenModal.svelte +++ b/packages/builder/src/components/userInterface/NewScreenModal.svelte @@ -1,7 +1,14 @@ -
- Deployment History - {#if deployments.length > 0} - +{#if deployments.length > 0} +
+
+

Deployment History

View Your Deployed App → - - {/if} - {#each deployments as deployment} -
-
- - {formatDate(deployment.updatedAt, 'fullDate')} - - - {formatDate(deployment.updatedAt, 'timeOnly')} - -
-
- {deployment.status} -
-
- {/each} -
+ +
+ {#each deployments as deployment} +
+
+ + {formatDate(deployment.updatedAt, 'fullDate')} + + + {formatDate(deployment.updatedAt, 'timeOnly')} + +
+
+ {deployment.status} +
+
+ {/each} +
+
+{/if}