making deploy process async, adding local deployment history

This commit is contained in:
Martin McKeaveney 2020-10-16 12:38:07 +01:00
parent f94841b7d8
commit 6f4b55c0f5
3 changed files with 179 additions and 26 deletions

View File

@ -1,4 +1,5 @@
<script> <script>
import { onMount } from "svelte"
import { Button, Spacer } from "@budibase/bbui" import { Button, Spacer } from "@budibase/bbui"
import { store } from "builderStore" import { store } from "builderStore"
import { notifier } from "builderStore/store/notifications" import { notifier } from "builderStore/store/notifications"
@ -8,12 +9,13 @@
let deployed = false let deployed = false
let loading = false let loading = false
let deployments = []
$: appId = $store.appId $: appId = $store.appId
async function deployApp() { async function deployApp() {
loading = true loading = true
const DEPLOY_URL = `/deploy` const DEPLOY_URL = `/api/deploy`
try { try {
notifier.info("Starting Deployment..") notifier.info("Starting Deployment..")
@ -38,6 +40,18 @@
loading = false loading = false
} }
} }
async function fetchDeployments() {
try {
const response = api.get(`/api/deployments`)
deployments = await response.json
} catch (err) {
console.error(err)
notifier.danger("Error fetching deployment history. Please try again.")
}
}
onMount(fetchDeployments)
</script> </script>
<section> <section>
@ -60,6 +74,11 @@
<img <img
src="/_builder/assets/deploy-rocket.jpg" src="/_builder/assets/deploy-rocket.jpg"
alt="Rocket flying through sky" /> alt="Rocket flying through sky" />
<section class="deployment-history">
{#each deployments as deployment}
<div>{JSON.stringify(deployment)}</div>
{/each}
</section>
</section> </section>
<style> <style>
@ -93,4 +112,13 @@
margin-right: auto; margin-right: auto;
width: 50%; width: 50%;
} }
.deployment-history {
height: 100%;
width: 400px;
position: absolute;
right: 0;
background: var(--white);
overflow-y: scroll;
}
</style> </style>

View File

@ -6,6 +6,7 @@ const {
updateDeploymentQuota, updateDeploymentQuota,
} = require("./aws") } = require("./aws")
const { DocumentTypes, SEPARATOR, UNICODE_MAX } = require("../../../db/utils") const { DocumentTypes, SEPARATOR, UNICODE_MAX } = require("../../../db/utils")
const newid = require("../../../db/newid")
function replicate(local, remote) { function replicate(local, remote) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -61,47 +62,164 @@ async function getCurrentInstanceQuota(instanceId) {
} }
} }
exports.deployApp = async function(ctx) { async function storeLocalDeploymentHistory(deployment) {
try { const db = new PouchDB(deployment.instanceId)
const clientAppLookupDB = new PouchDB("client_app_lookup")
const { clientId } = await clientAppLookupDB.get(ctx.user.appId)
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({ const credentials = await verifyDeployment({
instanceId: ctx.user.instanceId, instanceId,
appId: ctx.user.appId, appId,
quota: instanceQuota, 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) { if (credentials.errors) throw new Error(credentials.errors)
ctx.throw(500, credentials.errors)
return
}
await uploadAppAssets({ await uploadAppAssets({ clientId, appId, instanceId, ...credentials })
clientId,
appId: ctx.user.appId,
instanceId: ctx.user.instanceId,
...credentials,
})
// replicate the DB to the couchDB cluster in prod // 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({ await replicateCouch({
instanceId: ctx.user.instanceId, instanceId,
clientId, clientId,
credentials: credentials.couchDbCreds, credentials: credentials.couchDbCreds,
}) })
await updateDeploymentQuota(credentials.quota) await updateDeploymentQuota(credentials.quota)
ctx.body = { await storeLocalDeploymentHistory({
_id: deploymentId,
instanceId,
quota: credentials.quota,
status: "SUCCESS", status: "SUCCESS",
completed: Date.now(), })
}
} catch (err) { } 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",
// })
// }
}

View File

@ -5,6 +5,13 @@ const { BUILDER } = require("../../utilities/accessLevels")
const router = Router() 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 module.exports = router