dev mode E2E
This commit is contained in:
parent
3ad1e9a5b2
commit
c3e7548255
|
@ -0,0 +1,78 @@
|
|||
const { getDB } = require(".")
|
||||
|
||||
class Replication {
|
||||
/**
|
||||
*
|
||||
* @param {String} source - the DB you want to replicate or rollback to
|
||||
* @param {String} target - the DB you want to replicate to, or rollback from
|
||||
*/
|
||||
constructor({ source, target }) {
|
||||
this.source = getDB(source)
|
||||
this.target = getDB(target)
|
||||
}
|
||||
|
||||
sync(opts) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.source
|
||||
.sync(this.target, opts)
|
||||
.on("change", function (info) {
|
||||
// handle change
|
||||
})
|
||||
.on("paused", function (err) {
|
||||
// replication paused (e.g. replication up to date, user went offline)
|
||||
})
|
||||
.on("active", function () {
|
||||
// replicate resumed (e.g. new changes replicating, user went back online)
|
||||
})
|
||||
.on("denied", function (err) {
|
||||
// a document failed to replicate (e.g. due to permissions)
|
||||
return reject(
|
||||
new Error(`Denied: Document failed to replicate ${err}`)
|
||||
)
|
||||
})
|
||||
.on("complete", function (info) {
|
||||
return resolve(info)
|
||||
})
|
||||
.on("error", function (err) {
|
||||
return reject(new Error(`Replication Error: ${err}`))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
replicate() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.replication = this.source.replicate
|
||||
.to(this.target)
|
||||
// .on("change", function (info) {
|
||||
// // handle change
|
||||
// })
|
||||
// .on("paused", function (err) {
|
||||
// // replication paused (e.g. replication up to date, user went offline)
|
||||
// })
|
||||
// .on("active", function () {
|
||||
// // replicate resumed (e.g. new changes replicating, user went back online)
|
||||
// })
|
||||
.on("denied", function (err) {
|
||||
// a document failed to replicate (e.g. due to permissions)
|
||||
throw new Error(`Denied: Document failed to replicate ${err}`)
|
||||
})
|
||||
.on("complete", function (info) {
|
||||
return resolve(info)
|
||||
})
|
||||
.on("error", function (err) {
|
||||
throw new Error(`Replication Error: ${err}`)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async rollback() {
|
||||
await this.target.destroy()
|
||||
await this.replicate()
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.replication.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Replication
|
|
@ -1,4 +1,5 @@
|
|||
const { newid } = require("../hashing")
|
||||
const Replication = require("./Replication")
|
||||
|
||||
exports.ViewNames = {
|
||||
USER_BY_EMAIL: "by_email",
|
||||
|
@ -165,6 +166,7 @@ async function getScopedConfig(db, params) {
|
|||
return configDoc && configDoc.config ? configDoc.config : configDoc
|
||||
}
|
||||
|
||||
exports.Replication = Replication
|
||||
exports.getScopedConfig = getScopedConfig
|
||||
exports.generateConfigID = generateConfigID
|
||||
exports.getConfigParams = getConfigParams
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<div class="title">
|
||||
<Link href={$url(`../../app/${app._id}`)}>
|
||||
<Heading size="XS">
|
||||
{app.name}
|
||||
{app._id} {app.name}
|
||||
</Heading>
|
||||
</Link>
|
||||
<ActionMenu align="right">
|
||||
|
|
|
@ -15,11 +15,9 @@
|
|||
$: appId = $store.appId
|
||||
|
||||
async function deployApp() {
|
||||
const DEPLOY_URL = `/api/deploy`
|
||||
|
||||
try {
|
||||
notifications.info(`Deployment started. Please wait.`)
|
||||
const response = await api.post(DEPLOY_URL)
|
||||
const response = await api.post("/api/deploy")
|
||||
const json = await response.json()
|
||||
if (response.status !== 200) {
|
||||
throw new Error()
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
import AppRow from "components/start/AppRow.svelte"
|
||||
|
||||
let layout = "grid"
|
||||
let appStatus = "deployed"
|
||||
let template
|
||||
let appToDelete
|
||||
let creationModal
|
||||
|
@ -32,6 +33,8 @@
|
|||
let creatingApp = false
|
||||
let loaded = false
|
||||
|
||||
$: appStatus && apps.load(appStatus)
|
||||
|
||||
const checkKeys = async () => {
|
||||
const response = await api.get(`/api/keys/`)
|
||||
const keys = await response.json()
|
||||
|
@ -107,7 +110,13 @@
|
|||
</div>
|
||||
<div class="filter">
|
||||
<div class="select">
|
||||
<Select quiet placeholder="Filter by groups" />
|
||||
<Select
|
||||
bind:value={appStatus}
|
||||
options={[
|
||||
{ label: "Deployed", value: "deployed" },
|
||||
{ label: "In Development", value: "dev" },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<ActionGroup>
|
||||
<ActionButton
|
||||
|
|
|
@ -4,9 +4,9 @@ import { get } from "builderStore/api"
|
|||
export function createAppStore() {
|
||||
const store = writable([])
|
||||
|
||||
async function load() {
|
||||
async function load(status = "") {
|
||||
try {
|
||||
const res = await get("/api/applications")
|
||||
const res = await get(`/api/applications?status=${status}`)
|
||||
const json = await res.json()
|
||||
if (res.ok && Array.isArray(json)) {
|
||||
store.set(json)
|
||||
|
|
|
@ -2873,7 +2873,7 @@ svelte-spa-router@^3.0.5:
|
|||
dependencies:
|
||||
regexparam "1.3.0"
|
||||
|
||||
svelte@^3.37.0:
|
||||
svelte@^3.38.2:
|
||||
version "3.38.2"
|
||||
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.38.2.tgz#55e5c681f793ae349b5cc2fe58e5782af4275ef5"
|
||||
integrity sha512-q5Dq0/QHh4BLJyEVWGe7Cej5NWs040LWjMbicBGZ+3qpFWJ1YObRmUDZKbbovddLC9WW7THTj3kYbTOFmU9fbg==
|
||||
|
|
|
@ -16,6 +16,9 @@ const {
|
|||
getLayoutParams,
|
||||
getScreenParams,
|
||||
generateScreenID,
|
||||
generateDevAppID,
|
||||
DocumentTypes,
|
||||
AppStatus,
|
||||
} = require("../../db/utils")
|
||||
const {
|
||||
BUILTIN_ROLE_IDS,
|
||||
|
@ -84,7 +87,10 @@ async function getAppUrlIfNotInUse(ctx) {
|
|||
}
|
||||
|
||||
async function createInstance(template) {
|
||||
const appId = generateAppID()
|
||||
// TODO: Do we need the normal app ID?
|
||||
const baseAppId = generateAppID()
|
||||
const appId = generateDevAppID(baseAppId)
|
||||
|
||||
const db = new CouchDB(appId)
|
||||
await db.put({
|
||||
_id: "_design/database",
|
||||
|
@ -114,7 +120,20 @@ async function createInstance(template) {
|
|||
}
|
||||
|
||||
exports.fetch = async function (ctx) {
|
||||
ctx.body = await getAllApps()
|
||||
let apps = await getAllApps()
|
||||
|
||||
const appStatus = ctx.query.status
|
||||
if (appStatus) {
|
||||
apps = apps.filter(app => {
|
||||
if (appStatus === AppStatus.DEV) {
|
||||
return app._id.startsWith(DocumentTypes.APP_DEV)
|
||||
}
|
||||
|
||||
return !app._id.startsWith(DocumentTypes.APP_DEV)
|
||||
})
|
||||
}
|
||||
|
||||
ctx.body = apps
|
||||
}
|
||||
|
||||
exports.fetchAppDefinition = async function (ctx) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const PouchDB = require("../../../db")
|
||||
const Deployment = require("./Deployment")
|
||||
const { Replication } = require("@budibase/auth").db
|
||||
// the max time we can wait for an invalidation to complete before considering it failed
|
||||
const MAX_PENDING_TIME_MS = 30 * 60000
|
||||
const DeploymentStatus = {
|
||||
|
@ -56,7 +57,24 @@ async function storeLocalDeploymentHistory(deployment) {
|
|||
|
||||
async function deployApp(deployment) {
|
||||
try {
|
||||
// TODO: DB replication was here but wasn't accurate to new system
|
||||
const deployTarget = deployment.appId.replace("_dev", "")
|
||||
|
||||
const replication = new Replication({
|
||||
source: deployment.appId,
|
||||
target: deployTarget,
|
||||
})
|
||||
|
||||
await replication.replicate()
|
||||
|
||||
// Strip the _dev prefix and update the appID document in the new DB
|
||||
const db = new PouchDB(deployTarget)
|
||||
const appDoc = await db.get(deployment.appId)
|
||||
await db.remove(appDoc)
|
||||
appDoc._id = deployTarget
|
||||
delete appDoc._rev
|
||||
appDoc.instance._id = deployTarget
|
||||
await db.put(appDoc)
|
||||
|
||||
deployment.setStatus(DeploymentStatus.SUCCESS)
|
||||
await storeLocalDeploymentHistory(deployment)
|
||||
} catch (err) {
|
||||
|
|
|
@ -37,7 +37,7 @@ router
|
|||
})
|
||||
)
|
||||
.use(currentApp)
|
||||
.use(development)
|
||||
// .use(development)
|
||||
|
||||
// error handling middleware
|
||||
router.use(async (ctx, next) => {
|
||||
|
|
|
@ -10,6 +10,11 @@ const StaticDatabases = {
|
|||
},
|
||||
}
|
||||
|
||||
const AppStatus = {
|
||||
DEV: "dev",
|
||||
DEPLOYED: "deployed",
|
||||
}
|
||||
|
||||
const DocumentTypes = {
|
||||
TABLE: "ta",
|
||||
ROW: "ro",
|
||||
|
@ -49,6 +54,7 @@ exports.DocumentTypes = DocumentTypes
|
|||
exports.SEPARATOR = SEPARATOR
|
||||
exports.UNICODE_MAX = UNICODE_MAX
|
||||
exports.SearchIndexes = SearchIndexes
|
||||
exports.AppStatus = AppStatus
|
||||
|
||||
exports.getQueryIndex = viewName => {
|
||||
return `database/${viewName}`
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -226,7 +226,7 @@ svelte-hmr@^0.13.3:
|
|||
resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.13.3.tgz#fba5739b477ea44caf70e542a24a4352bee2b897"
|
||||
integrity sha512-gagW62pLQ2lULmvNA3pIZu9pBCYOaGu3rQikUOv6Nokz5VxUgT9/mQLfMxj9phDEKHCg/lgr3i6PkqZDbO9P2Q==
|
||||
|
||||
svelte@^3.37.0:
|
||||
svelte@^3.38.2:
|
||||
version "3.38.2"
|
||||
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.38.2.tgz#55e5c681f793ae349b5cc2fe58e5782af4275ef5"
|
||||
integrity sha512-q5Dq0/QHh4BLJyEVWGe7Cej5NWs040LWjMbicBGZ+3qpFWJ1YObRmUDZKbbovddLC9WW7THTj3kYbTOFmU9fbg==
|
||||
|
|
Loading…
Reference in New Issue