mirror of https://github.com/Budibase/budibase.git
12 changed files with 215 additions and 116 deletions
|
After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 484 KiB |
@ -1 +1,60 @@ |
|||
<img src="/_builder/assets/deploy_rocket.jpg" /> |
|||
<script> |
|||
import { Button } from "@budibase/bbui" |
|||
import { notifier } from "builderStore/store/notifications" |
|||
import api from "builderStore/api" |
|||
|
|||
async function deployApp() { |
|||
const DEPLOY_URL = `/deploy` |
|||
|
|||
try { |
|||
notifier.info("Starting Deployment..") |
|||
const response = await api.post(DEPLOY_URL) |
|||
const json = await response.json() |
|||
if (response.status !== 200) { |
|||
throw new Error |
|||
} |
|||
|
|||
notifier.success("Deployment Complete. View your app at blah URL") |
|||
} catch (err) { |
|||
notifier.danger("Deployment unsuccessful. Please try again later.") |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<section> |
|||
<div> |
|||
<h4>It's time to shine!</h4> |
|||
<Button secondary medium on:click={deployApp}> |
|||
Deploy App |
|||
</Button> |
|||
</div> |
|||
<img src="/_builder/assets/deploy-rocket.jpg" /> |
|||
</section> |
|||
|
|||
<style> |
|||
h4 { |
|||
color: var(--white); |
|||
font-size: 18px; |
|||
font-weight: bold; |
|||
margin-bottom: 30px; |
|||
} |
|||
|
|||
section { |
|||
position: relative; |
|||
} |
|||
|
|||
div { |
|||
position: absolute; |
|||
display: flex; |
|||
text-align: center; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
left: 0; |
|||
right: 0; |
|||
top: 20%; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
width: 50%; |
|||
} |
|||
</style> |
|||
|
|||
|
After Width: | Height: | Size: 132 KiB |
@ -1,3 +1,3 @@ |
|||
docker build -t prod-apps-budi-live . |
|||
docker tag prod-apps-budi-live:latest 545012296077.dkr.ecr.eu-west-1.amazonaws.com/prod-apps-budi-live:latest |
|||
docker push 545012296077.dkr.ecr.eu-west-1.amazonaws.com/prod-apps-budi-live:latest |
|||
docker build -t prod-budi-app-server . |
|||
docker tag prod-budi-app-server:latest 545012296077.dkr.ecr.eu-west-1.amazonaws.com/prod-budi-app-server:latest |
|||
docker push 545012296077.dkr.ecr.eu-west-1.amazonaws.com/prod-budi-app-server:latest |
|||
|
|||
@ -1,83 +0,0 @@ |
|||
const fs = require("fs") |
|||
const AWS = require("aws-sdk") |
|||
const CouchDB = require("../../db") |
|||
const { |
|||
budibaseAppsDir, |
|||
} = require("../../utilities/budibaseDir") |
|||
|
|||
const s3 = new AWS.S3({ |
|||
params: { |
|||
Bucket: process.env.BUDIBASE_APP_ASSETS_BUCKET |
|||
} |
|||
}) |
|||
|
|||
async function uploadAppAssets({ clientId, appId }) { |
|||
const appAssetsPath = `${budibaseAppsDir()}/${appId}/public` |
|||
|
|||
const appPages = fs.readdirSync(appAssetsPath) |
|||
|
|||
const uploads = [] |
|||
|
|||
for (let page of appPages) { |
|||
for (let filename of fs.readdirSync(`${appAssetsPath}/${page}`)) { |
|||
const filePath = `${appAssetsPath}/${page}/${filename}` |
|||
const stat = await fs.lstatSync(filePath) |
|||
|
|||
// TODO: need to account for recursively traversing dirs
|
|||
if (stat.isFile()) { |
|||
const fileBytes = fs.readFileSync(`${appAssetsPath}/${page}/${filename}`) |
|||
|
|||
const upload = s3.upload({ |
|||
Key: `${clientId}/${appId}/${page}/${filename}`, |
|||
Body: fileBytes |
|||
}).promise() |
|||
|
|||
uploads.push(upload) |
|||
} |
|||
} |
|||
} |
|||
|
|||
try { |
|||
await Promise.all(uploads) |
|||
} catch (err) { |
|||
console.error("Error uploading budibase app assets to s3", err) |
|||
throw err |
|||
} |
|||
} |
|||
|
|||
function replicateCouch(instanceId) { |
|||
return new Promise((resolve, reject) => { |
|||
const localDb = new CouchDB(instanceId) |
|||
const remoteDb = new CouchDB(`${process.env.COUCH_DB_REMOTE}/${instanceId}`) |
|||
|
|||
const replication = localDb.replicate.to(remoteDb); |
|||
|
|||
replication.on("complete", () => resolve()) |
|||
replication.on("error", err => reject(err)) |
|||
}); |
|||
|
|||
} |
|||
|
|||
exports.deployApp = async function(ctx) { |
|||
const { |
|||
user = { |
|||
instanceId: "test_instance_id", |
|||
clientId: "test123", |
|||
appId: "24602c068a2d494cb09cb48f44bfdd8f" |
|||
} |
|||
} = ctx; |
|||
|
|||
// TODO: This should probably be async - it could take a while
|
|||
try { |
|||
// upload all the assets to s3
|
|||
await uploadAppAssets(user) |
|||
|
|||
// replicate the DB to the couchDB cluster in prod
|
|||
await replicateCouch(user.instanceId); |
|||
|
|||
ctx.body = "Deployment Successful!" |
|||
|
|||
} catch (err) { |
|||
ctx.throw(err.status || 500, `Deployment Failed: ${err.message}`); |
|||
} |
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
const fs = require("fs") |
|||
const AWS = require("aws-sdk") |
|||
const fetch = require("node-fetch") |
|||
const { |
|||
budibaseAppsDir, |
|||
} = require("../../../utilities/budibaseDir") |
|||
|
|||
async function fetchTemporaryCredentials() { |
|||
const CREDENTIALS_URL = "https://dt4mpwwap8.execute-api.eu-west-1.amazonaws.com/prod/" |
|||
|
|||
const response = await fetch(CREDENTIALS_URL, { |
|||
method: "POST", |
|||
body: JSON.stringify({ |
|||
apiKey: "d498278c-4ab4-144b-c212-b8f9e6da5c2b" |
|||
}) |
|||
}) |
|||
|
|||
if (response.status !== 200) { |
|||
throw new Error |
|||
} |
|||
|
|||
const json = await response.json() |
|||
|
|||
return json |
|||
} |
|||
|
|||
exports.uploadAppAssets = async function ({ appId }) { |
|||
const { credentials, accountId } = await fetchTemporaryCredentials() |
|||
console.log({ |
|||
credentials, |
|||
accountId |
|||
}); |
|||
|
|||
AWS.config.update({ |
|||
accessKeyId: credentials.AccessKeyId, |
|||
secretAccessKey: credentials.SecretAccessKey, |
|||
sessionToken: credentials.SessionToken |
|||
}); |
|||
|
|||
const s3 = new AWS.S3({ |
|||
params: { |
|||
Bucket: process.env.BUDIBASE_APP_ASSETS_BUCKET |
|||
} |
|||
}) |
|||
|
|||
const appAssetsPath = `${budibaseAppsDir()}/${appId}/public` |
|||
|
|||
const appPages = fs.readdirSync(appAssetsPath) |
|||
|
|||
const uploads = [] |
|||
|
|||
for (let page of appPages) { |
|||
for (let filename of fs.readdirSync(`${appAssetsPath}/${page}`)) { |
|||
const filePath = `${appAssetsPath}/${page}/${filename}` |
|||
const stat = await fs.lstatSync(filePath) |
|||
|
|||
// TODO: need to account for recursively traversing dirs
|
|||
if (stat.isFile()) { |
|||
const fileBytes = fs.readFileSync(`${appAssetsPath}/${page}/${filename}`) |
|||
|
|||
console.log(`${accountId}/${appId}/${page}/${filename}`) |
|||
|
|||
const upload = s3.upload({ |
|||
Key: `assets/${accountId}/${appId}/${page}/${filename}`, |
|||
Body: fileBytes |
|||
}).promise() |
|||
|
|||
uploads.push(upload) |
|||
} |
|||
} |
|||
} |
|||
|
|||
try { |
|||
await Promise.all(uploads) |
|||
} catch (err) { |
|||
console.error("Error uploading budibase app assets to s3", err) |
|||
throw err |
|||
} |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
const CouchDB = require("pouchdb") |
|||
const PouchDB = require("../../../db") |
|||
const { |
|||
uploadAppAssets, |
|||
} = require("./aws") |
|||
|
|||
function replicateCouch(instanceId) { |
|||
return new Promise((resolve, reject) => { |
|||
const localDb = new PouchDB(instanceId) |
|||
const remoteDb = new CouchDB(`${process.env.COUCH_DB_REMOTE}/${instanceId}`) |
|||
|
|||
const replication = localDb.replicate.to(remoteDb); |
|||
|
|||
replication.on("complete", () => resolve()) |
|||
replication.on("error", err => reject(err)) |
|||
}); |
|||
} |
|||
|
|||
exports.deployApp = async function(ctx) { |
|||
// TODO: This should probably be async - it could take a while
|
|||
try { |
|||
const clientAppLookupDB = new PouchDB("client_app_lookup") |
|||
console.log(ctx.user) |
|||
const { clientId } = await clientAppLookupDB.get(ctx.user.appId) |
|||
|
|||
ctx.log.info(`Uploading assets for appID ${ctx.user.appId} assets to s3..`); |
|||
await uploadAppAssets({ |
|||
clientId, |
|||
appId: ctx.user.appId |
|||
}) |
|||
|
|||
// replicate the DB to the couchDB cluster in prod
|
|||
ctx.log.info("Replicating local PouchDB to remote.."); |
|||
await replicateCouch(ctx.user.instanceId); |
|||
|
|||
ctx.body = { |
|||
status: "SUCCESS", |
|||
completed: Date.now() |
|||
} |
|||
|
|||
} catch (err) { |
|||
ctx.throw(err.status || 500, `Deployment Failed: ${err.message}`); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue