making deploy process async, adding local deployment history
This commit is contained in:
parent
f94841b7d8
commit
6f4b55c0f5
|
@ -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>
|
||||||
|
|
|
@ -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",
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue