diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 07df3bd427..b3b2b01316 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -71,3 +71,57 @@ jobs: DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }} BUDIBASE_RELEASE_VERSION: ${{ steps.previoustag.outputs.tag }} + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: eu-west-1 + + - name: Tag and release Proxy service docker image + run: | + docker login -u $DOCKER_USER -p $DOCKER_PASSWORD + yarn build:docker:proxy:preprod + docker tag proxy-service budibase/proxy:$PREPROD_TAG + docker push budibase/proxy:$PREPROD_TAG + env: + DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }} + PREPROD_TAG: k8s-preprod + + - name: Pull values.yaml from budibase-infra + run: | + curl -H "Authorization: token ${{ secrets.GH_PERSONAL_TOKEN }}" \ + -H 'Accept: application/vnd.github.v3.raw' \ + -o values.preprod.yaml \ + -L https://api.github.com/repos/budibase/budibase-infra/contents/kubernetes/budibase-preprod/values.yaml + wc -l values.preprod.yaml + + - name: Deploy to Preprod Environment + uses: glopezep/helm@v1.7.1 + with: + release: budibase-preprod + namespace: budibase + chart: charts/budibase + token: ${{ github.token }} + helm: helm3 + values: | + globals: + appVersion: ${{ steps.previoustag.outputs.tag }} + ingress: + enabled: true + nginx: true + value-files: >- + [ + "values.preprod.yaml" + ] + env: + KUBECONFIG_FILE: '${{ secrets.PREPROD_KUBECONFIG }}' + + - name: Discord Webhook Action + uses: tsickert/discord-webhook@v4.0.0 + with: + webhook-url: ${{ secrets.PROD_DEPLOY_WEBHOOK_URL }} + content: "Preprod Deployment Complete: ${{ steps.previoustag.outputs.tag }} deployed to Budibase Pre-prod." + embed-title: ${{ steps.previoustag.outputs.tag }} diff --git a/hosting/docker-compose.dev.yaml b/hosting/docker-compose.dev.yaml index 43b8526e9e..be0bc74a26 100644 --- a/hosting/docker-compose.dev.yaml +++ b/hosting/docker-compose.dev.yaml @@ -27,6 +27,7 @@ services: image: nginx:latest volumes: - ./.generated-nginx.dev.conf:/etc/nginx/nginx.conf + - ./proxy/error.html:/usr/share/nginx/html/error.html ports: - "${MAIN_PORT}:10000" depends_on: diff --git a/hosting/nginx.dev.conf.hbs b/hosting/nginx.dev.conf.hbs index 9fc2345fb2..9398b7e719 100644 --- a/hosting/nginx.dev.conf.hbs +++ b/hosting/nginx.dev.conf.hbs @@ -28,6 +28,12 @@ http { ignore_invalid_headers off; proxy_buffering off; + error_page 502 503 504 /error.html; + location = /error.html { + root /usr/share/nginx/html; + internal; + } + location /db/ { proxy_pass http://couchdb-service:5984; rewrite ^/db/(.*)$ /$1 break; diff --git a/hosting/nginx.prod.conf.hbs b/hosting/nginx.prod.conf.hbs index 88570a4a2d..7ef597051b 100644 --- a/hosting/nginx.prod.conf.hbs +++ b/hosting/nginx.prod.conf.hbs @@ -56,6 +56,12 @@ http { set $csp_media "media-src 'self' https://js.intercomcdn.com"; set $csp_worker "worker-src 'none'"; + error_page 502 503 504 /error.html; + location = /error.html { + root /usr/share/nginx/html; + internal; + } + # Security Headers add_header X-Frame-Options SAMEORIGIN always; add_header X-Content-Type-Options nosniff always; diff --git a/hosting/proxy/Dockerfile b/hosting/proxy/Dockerfile index b577e3e40f..a2b17d3333 100644 --- a/hosting/proxy/Dockerfile +++ b/hosting/proxy/Dockerfile @@ -1,2 +1,3 @@ FROM nginx:latest -COPY .generated-nginx.prod.conf /etc/nginx/nginx.conf \ No newline at end of file +COPY .generated-nginx.prod.conf /etc/nginx/nginx.conf +COPY error.html /usr/share/nginx/html/error.html \ No newline at end of file diff --git a/hosting/proxy/error.html b/hosting/proxy/error.html new file mode 100644 index 0000000000..023c1ebaff --- /dev/null +++ b/hosting/proxy/error.html @@ -0,0 +1,175 @@ + + + + + Budibase + + + + + + + + + + +
+
+
+ Budibase Logo +
+
+
+

+

+ Houston we have a problem! +

+

+

+
+
+ + +
+
+
+
+ + + \ No newline at end of file diff --git a/lerna.json b/lerna.json index 5432452baf..f6bce3d611 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.0.105-alpha.39", + "version": "1.0.105-alpha.42", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 6254eeee70..b67ee44fbe 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "1.0.105-alpha.39", + "version": "1.0.105-alpha.42", "description": "Budibase backend core libraries used in server and worker", "main": "src/index.js", "author": "Budibase", diff --git a/packages/backend-core/src/middleware/passport/google.js b/packages/backend-core/src/middleware/passport/google.js index 5e95a906d8..b12a668327 100644 --- a/packages/backend-core/src/middleware/passport/google.js +++ b/packages/backend-core/src/middleware/passport/google.js @@ -2,7 +2,7 @@ const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy const { authenticateThirdParty } = require("./third-party-common") -const buildVerifyFn = async saveUserFn => { +const buildVerifyFn = saveUserFn => { return (accessToken, refreshToken, profile, done) => { const thirdPartyUser = { provider: profile.provider, // should always be 'google' diff --git a/packages/backend-core/src/utils.js b/packages/backend-core/src/utils.js index e4b358a676..56205f3487 100644 --- a/packages/backend-core/src/utils.js +++ b/packages/backend-core/src/utils.js @@ -176,11 +176,25 @@ exports.getGlobalUserByEmail = async email => { }) } -exports.getBuildersCount = async () => { +const getBuilders = async () => { const builders = await queryGlobalView(ViewNames.USER_BY_BUILDERS, { include_docs: false, }) - return builders ? builders.length : 0 + + if (!builders) { + return [] + } + + if (Array.isArray(builders)) { + return builders + } else { + return [builders] + } +} + +exports.getBuildersCount = async () => { + const builders = await getBuilders() + return builders.length } exports.saveUser = async ( diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 26bbe94a54..9d8bc88c6c 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/bbui", "description": "A UI solution used in the different Budibase projects.", - "version": "1.0.105-alpha.39", + "version": "1.0.105-alpha.42", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", @@ -38,7 +38,7 @@ ], "dependencies": { "@adobe/spectrum-css-workflow-icons": "^1.2.1", - "@budibase/string-templates": "^1.0.105-alpha.39", + "@budibase/string-templates": "^1.0.105-alpha.42", "@spectrum-css/actionbutton": "^1.0.1", "@spectrum-css/actiongroup": "^1.0.1", "@spectrum-css/avatar": "^3.0.2", diff --git a/packages/builder/package.json b/packages/builder/package.json index fe3510185c..9273e7566d 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "1.0.105-alpha.39", + "version": "1.0.105-alpha.42", "license": "GPL-3.0", "private": true, "scripts": { @@ -65,10 +65,10 @@ } }, "dependencies": { - "@budibase/bbui": "^1.0.105-alpha.39", - "@budibase/client": "^1.0.105-alpha.39", - "@budibase/frontend-core": "^1.0.105-alpha.39", - "@budibase/string-templates": "^1.0.105-alpha.39", + "@budibase/bbui": "^1.0.105-alpha.42", + "@budibase/client": "^1.0.105-alpha.42", + "@budibase/frontend-core": "^1.0.105-alpha.42", + "@budibase/string-templates": "^1.0.105-alpha.42", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index ef0a61646e..0829b85a90 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -48,10 +48,6 @@ $automationStore.selectedAutomation?.automation?.definition?.steps.length + 1 - $: hasCompletedInputs = Object.keys( - block.schema?.inputs?.properties || {} - ).every(x => block?.inputs[x]) - $: loopingSelected = $automationStore.selectedAutomation?.automation.definition.steps.find( x => x.blockToLoop === block.id @@ -290,13 +286,7 @@
- actionModal.show()} - disabled={!hasCompletedInputs} - hoverable - name="AddCircle" - size="S" -/> + actionModal.show()} hoverable name="AddCircle" size="S" /> {#if isTrigger ? totalBlocks > 1 : blockIdx !== totalBlocks - 2}
{/if} diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 856ab5f31a..4333e4a2e5 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -25,11 +25,11 @@ import QueryParamSelector from "./QueryParamSelector.svelte" import CronBuilder from "./CronBuilder.svelte" import Editor from "components/integration/QueryEditor.svelte" - import { debounce } from "lodash" import ModalBindableInput from "components/common/bindings/ModalBindableInput.svelte" import FilterDrawer from "components/design/PropertiesPanel/PropertyControls/FilterEditor/FilterDrawer.svelte" import { LuceneUtils } from "@budibase/frontend-core" import { getSchemaForTable } from "builderStore/dataBinding" + import { Utils } from "@budibase/frontend-core" export let block export let testData @@ -54,7 +54,7 @@ $: schema = getSchemaForTable(tableId, { searchableSchema: true }).schema $: schemaFields = Object.values(schema || {}) - const onChange = debounce(async function (e, key) { + const onChange = Utils.sequential(async (e, key) => { try { if (isTestModal) { // Special case for webhook, as it requires a body, but the schema already brings back the body's contents @@ -82,7 +82,7 @@ } catch (error) { notifications.error("Error saving automation") } - }, 800) + }) function getAvailableBindings(block, automation) { if (!block || !automation) { @@ -226,6 +226,7 @@ on:change={e => onChange(e, key)} {bindings} fillWidth + updateOnChange={false} /> {:else} onChange(e, key)} {bindings} allowJS={false} + updateOnChange={false} /> {/if} {:else if value.customType === "query"} @@ -310,6 +312,7 @@ type={value.customType} on:change={e => onChange(e, key)} {bindings} + updateOnChange={false} /> {:else}
@@ -321,6 +324,7 @@ value={inputData[key]} on:change={e => onChange(e, key)} {bindings} + updateOnChange={false} />
{/if} diff --git a/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte b/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte index 971a9cc51b..f91cd62bed 100644 --- a/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte +++ b/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte @@ -43,6 +43,11 @@ } const coerce = (value, type) => { + const re = new RegExp(/{{([^{].*?)}}/g) + if (re.test(value)) { + return value + } + if (type === "boolean") { if (typeof value === "boolean") { return value @@ -120,6 +125,7 @@ {bindings} fillWidth={true} allowJS={true} + updateOnChange={false} /> {/if} {:else if !rowControl} @@ -137,6 +143,7 @@ {bindings} fillWidth={true} allowJS={true} + updateOnChange={false} /> {/if} {/if} diff --git a/packages/builder/src/components/automation/SetupPanel/RowSelectorTypes.svelte b/packages/builder/src/components/automation/SetupPanel/RowSelectorTypes.svelte index 2a51e8d200..f66df3a9b1 100644 --- a/packages/builder/src/components/automation/SetupPanel/RowSelectorTypes.svelte +++ b/packages/builder/src/components/automation/SetupPanel/RowSelectorTypes.svelte @@ -60,5 +60,6 @@ {bindings} fillWidth={true} allowJS={true} + updateOnChange={false} /> {/if} diff --git a/packages/builder/src/components/automation/SetupPanel/SchemaSetup.svelte b/packages/builder/src/components/automation/SetupPanel/SchemaSetup.svelte index 71b10a3569..cb80072694 100644 --- a/packages/builder/src/components/automation/SetupPanel/SchemaSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/SchemaSetup.svelte @@ -30,6 +30,10 @@ label: "DateTime", value: "datetime", }, + { + label: "Array", + value: "array", + }, ] function addField() { @@ -70,6 +74,7 @@ secondary placeholder="Enter field name" on:change={fieldNameChanged(field.name)} + updateOnChange={false} />