diff --git a/.github/workflows/release-develop.yml b/.github/workflows/release-develop.yml index 21c74851e1..cd39148bdc 100644 --- a/.github/workflows/release-develop.yml +++ b/.github/workflows/release-develop.yml @@ -1,5 +1,5 @@ name: Budibase Prerelease -concurrency: release-prerelease +#concurrency: release-prerelease on: push: @@ -26,7 +26,7 @@ env: FEATURE_PREVIEW_URL: https://budirelease.live jobs: - release: + release-images: runs-on: ubuntu-latest steps: @@ -44,19 +44,12 @@ jobs: run: yarn install:pro develop - run: yarn - - run: yarn bootstrap + - run: yarn bootstrap - run: yarn lint - run: yarn build - run: yarn build:sdk - run: yarn test - - 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: Publish budibase packages to NPM env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} @@ -76,12 +69,6 @@ jobs: DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }} - - name: Get the latest budibase release version - id: version - run: | - release_version=$(cat lerna.json | jq -r '.version') - echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV - - name: Tag and release Proxy service docker image run: | docker login -u $DOCKER_USER -p $DOCKER_PASSWORD @@ -93,6 +80,26 @@ jobs: DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }} RELEASE_TAG: k8s-release + deploy-to-release-env: + needs: [release-images] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Get the current budibase release version + id: version + run: | + release_version=$(cat lerna.json | jq -r '.version') + echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV + + - 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: Pull values.yaml from budibase-infra run: | curl -H "Authorization: token ${{ secrets.GH_PERSONAL_TOKEN }}" \ @@ -149,3 +156,53 @@ jobs: webhook-url: ${{ secrets.PROD_DEPLOY_WEBHOOK_URL }} content: "Release Env Deployment Complete: ${{ env.RELEASE_VERSION }} deployed to Budibase Release Env." embed-title: ${{ env.RELEASE_VERSION }} + + release-helm-chart: + needs: [release-images] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Setup Helm + uses: azure/setup-helm@v1 + id: helm-install + + # due to helm repo index issue: https://github.com/helm/helm/issues/7363 + # we need to create new package in a different dir, merge the index and move the package back + - name: Build and release helm chart + run: | + git config user.name "Budibase Helm Bot" + git config user.email "<>" + git reset --hard + git pull + mkdir sync + echo "Packaging chart to sync dir" + helm package charts/budibase --version 0.0.0-develop --app-version develop --destination sync + echo "Packaging successful" + git checkout gh-pages + echo "Indexing helm repo" + helm repo index --merge docs/index.yaml sync + mv -f sync/* docs + rm -rf sync + echo "Pushing new helm release" + git add -A + git commit -m "Helm Release: develop" + git push + + trigger-deploy-to-qa: + needs: [release-helm-chart] + runs-on: ubuntu-latest + steps: + - name: Get the current budibase release version + id: version + run: | + release_version=$(cat lerna.json | jq -r '.version') + echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV + + - uses: passeidireto/trigger-external-workflow-action@main + env: + PAYLOAD_VERSION: ${{ env.RELEASE_VERSION }} + with: + repository: budibase/budibase-deploys + event: deploy-develop-to-qa + github_pat: ${{ secrets.GH_ACCESS_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release-selfhost.yml b/.github/workflows/release-selfhost.yml index d78180fdc7..cbf8a002f4 100644 --- a/.github/workflows/release-selfhost.yml +++ b/.github/workflows/release-selfhost.yml @@ -73,7 +73,7 @@ jobs: git config user.email "<>" git reset --hard git pull - helm package charts/budibase + helm package charts/budibase --version "$RELEASE_VERSION" --app-version "$RELEASE_VERSION" git checkout gh-pages mv *.tgz docs helm repo index docs diff --git a/.gitignore b/.gitignore index 654b483288..45bfe8b4c4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ builder/* packages/server/runtime_apps/ .idea/ bb-airgapped.tar.gz +*.iml # Logs logs diff --git a/charts/budibase/Chart.yaml b/charts/budibase/Chart.yaml index 570aa04d8e..9d02e19506 100644 --- a/charts/budibase/Chart.yaml +++ b/charts/budibase/Chart.yaml @@ -11,8 +11,10 @@ sources: - https://github.com/Budibase/budibase - https://budibase.com type: application -version: 0.2.11 -appVersion: 1.0.214 +# populates on packaging +version: 0.0.0 +# populates on packaging +appVersion: 0.0.0 dependencies: - name: couchdb version: 3.6.1 diff --git a/lerna.json b/lerna.json index 439190499e..17b8ec3cee 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.2.4-alpha.2", + "version": "2.2.4-alpha.7", "npmClient": "yarn", "packages": [ "packages/*" @@ -15,4 +15,4 @@ ] } } -} +} \ No newline at end of file diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index dd36746391..316f6f65db 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "2.2.4-alpha.2", + "version": "2.2.4-alpha.7", "description": "Budibase backend core libraries used in server and worker", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -21,7 +21,7 @@ }, "dependencies": { "@budibase/nano": "10.1.1", - "@budibase/types": "2.2.4-alpha.2", + "@budibase/types": "2.2.4-alpha.7", "@shopify/jest-koa-mocks": "5.0.1", "@techpass/passport-openidconnect": "0.3.2", "aws-cloudfront-sign": "2.2.0", @@ -79,4 +79,4 @@ "typescript": "4.7.3" }, "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc" -} +} \ No newline at end of file diff --git a/packages/backend-core/src/objectStore/objectStore.ts b/packages/backend-core/src/objectStore/objectStore.ts index 89e1c88e10..1cc8ad3add 100644 --- a/packages/backend-core/src/objectStore/objectStore.ts +++ b/packages/backend-core/src/objectStore/objectStore.ts @@ -86,7 +86,7 @@ export const ObjectStore = ( // custom S3 is in use i.e. minio if (env.MINIO_URL) { - if (opts.presigning && !env.MINIO_ENABLED) { + if (opts.presigning && env.MINIO_ENABLED) { // IMPORTANT: Signed urls will inspect the host header of the request. // Normally a signed url will need to be generated with a specified host in mind. // To support dynamic hosts, e.g. some unknown self-hosted installation url, diff --git a/packages/backend-core/src/redis/redlock.ts b/packages/backend-core/src/redis/redlock.ts index 586302c9b1..54b2c0a8d1 100644 --- a/packages/backend-core/src/redis/redlock.ts +++ b/packages/backend-core/src/redis/redlock.ts @@ -13,6 +13,18 @@ const getClient = async (type: LockType): Promise => { } return noRetryRedlock } + case LockType.DEFAULT: { + if (!noRetryRedlock) { + noRetryRedlock = await newRedlock(OPTIONS.DEFAULT) + } + return noRetryRedlock + } + case LockType.DELAY_500: { + if (!noRetryRedlock) { + noRetryRedlock = await newRedlock(OPTIONS.DELAY_500) + } + return noRetryRedlock + } default: { throw new Error(`Could not get redlock client: ${type}`) } @@ -41,6 +53,9 @@ export const OPTIONS = { // see https://www.awsarchitectureblog.com/2015/03/backoff.html retryJitter: 100, // time in ms }, + DELAY_500: { + retryDelay: 500, + }, } export const newRedlock = async (opts: Options = {}) => { @@ -55,19 +70,17 @@ export const doWithLock = async (opts: LockOptions, task: any) => { let lock try { // aquire lock - let name: string - if (opts.systemLock) { - name = opts.name - } else { - name = `${tenancy.getTenantId()}_${opts.name}` - } + let name: string = `lock:${tenancy.getTenantId()}_${opts.name}` if (opts.nameSuffix) { name = name + `_${opts.nameSuffix}` } lock = await redlock.lock(name, opts.ttl) // perform locked task - return task() + // need to await to ensure completion before unlocking + const result = await task() + return result } catch (e: any) { + console.log("lock error") // lock limit exceeded if (e.name === "LockError") { if (opts.type === LockType.TRY_ONCE) { diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 20e727f0c6..6536f65dd5 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": "2.2.4-alpha.2", + "version": "2.2.4-alpha.7", "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": "2.2.4-alpha.2", + "@budibase/string-templates": "2.2.4-alpha.7", "@spectrum-css/actionbutton": "1.0.1", "@spectrum-css/actiongroup": "1.0.1", "@spectrum-css/avatar": "3.0.2", @@ -89,4 +89,4 @@ "loader-utils": "1.4.1" }, "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc" -} +} \ No newline at end of file diff --git a/packages/bbui/src/Badge/Badge.svelte b/packages/bbui/src/Badge/Badge.svelte index 4bc701d983..8b54045297 100644 --- a/packages/bbui/src/Badge/Badge.svelte +++ b/packages/bbui/src/Badge/Badge.svelte @@ -10,10 +10,13 @@ export let green = false export let active = false export let inactive = false + export let hoverable = false + + diff --git a/packages/bbui/src/Table/RelationshipRenderer.svelte b/packages/bbui/src/Table/RelationshipRenderer.svelte index 4db0c63d95..b70eaeb07d 100644 --- a/packages/bbui/src/Table/RelationshipRenderer.svelte +++ b/packages/bbui/src/Table/RelationshipRenderer.svelte @@ -1,6 +1,7 @@ @@ -157,7 +181,7 @@ Connect to an external datasource
- {#each Object.entries(integrations).filter(([key, val]) => key !== IntegrationTypes.INTERNAL && !val.custom) as [integrationType, schema]} + {#each sortedIntegrations.filter(([key, val]) => key !== IntegrationTypes.INTERNAL && !val.custom) as [integrationType, schema]} selectIntegration(evt.detail)} {schema} diff --git a/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte b/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte index 82721e4ab1..82a2aa8066 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte @@ -64,7 +64,6 @@ // reload await datasources.fetch() await queries.fetch() - await datasources.select(datasourceId) if (navigateDatasource) { $goto(`./datasource/${datasourceId}`) diff --git a/packages/builder/src/components/backend/DatasourceNavigator/popovers/EditDatasourcePopover.svelte b/packages/builder/src/components/backend/DatasourceNavigator/popovers/EditDatasourcePopover.svelte index 165ed18ad8..344bfab4e4 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/popovers/EditDatasourcePopover.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/popovers/EditDatasourcePopover.svelte @@ -1,6 +1,6 @@ {#if $database?._id} @@ -44,8 +23,9 @@ border={idx > 0} icon={table._id === TableNames.USERS ? "UserGroup" : "Table"} text={table.name} - selected={$tables.selected?._id === table._id} - on:click={() => selectTable(table)} + selected={$isActive("./table/:tableId") && + $tables.selected?._id === table._id} + on:click={() => $goto(`./table/${table._id}`)} > {#if table._id !== TableNames.USERS} @@ -56,8 +36,9 @@ indentLevel={2} icon="Remove" text={viewName} - selected={selectedView === viewName} - on:click={() => onClickView(table, viewName)} + selected={$isActive("./view/:viewName") && + $views.selected?.name === viewName} + on:click={() => $goto(`./view/${viewName}`)} > - import { goto } from "@roxi/routify" + import { goto, params } from "@roxi/routify" import { store } from "builderStore" import { cloneDeep } from "lodash/fp" import { tables, datasources } from "stores/backend" @@ -41,17 +41,16 @@ } async function deleteTable() { - const wasSelectedTable = $tables.selected + const isSelected = $params.tableId === table._id try { await tables.delete(table) await store.actions.screens.delete(templateScreens) - await tables.fetch() if (table.type === "external") { await datasources.fetch() } notifications.success("Table deleted") - if (wasSelectedTable && wasSelectedTable._id === table._id) { - $goto("./table") + if (isSelected) { + $goto(`./datasource/${table.datasourceId}`) } } catch (error) { notifications.error("Error deleting table") diff --git a/packages/builder/src/components/backend/TableNavigator/popovers/EditViewPopover.svelte b/packages/builder/src/components/backend/TableNavigator/popovers/EditViewPopover.svelte index f543b34ddc..44eb1e9b7b 100644 --- a/packages/builder/src/components/backend/TableNavigator/popovers/EditViewPopover.svelte +++ b/packages/builder/src/components/backend/TableNavigator/popovers/EditViewPopover.svelte @@ -1,5 +1,5 @@ - - - - .panel { width: 260px; + flex: 0 0 260px; background: var(--background); display: flex; flex-direction: column; @@ -66,6 +67,7 @@ } .panel.wide { width: 420px; + flex: 0 0 420px; } .header { flex: 0 0 48px; diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/PromptUser.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/PromptUser.svelte new file mode 100644 index 0000000000..85d395e4f4 --- /dev/null +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/PromptUser.svelte @@ -0,0 +1,50 @@ + + +
+ Enter the message you wish to display to the user. +
+ + + + +
+
+ + diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/index.js b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/index.js index 4a9640312d..90ce1607e4 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/index.js +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/index.js @@ -16,5 +16,6 @@ export { default as ExportData } from "./ExportData.svelte" export { default as ContinueIf } from "./ContinueIf.svelte" export { default as UpdateFieldValue } from "./UpdateFieldValue.svelte" export { default as ShowNotification } from "./ShowNotification.svelte" +export { default as PromptUser } from "./PromptUser.svelte" export { default as OpenSidePanel } from "./OpenSidePanel.svelte" export { default as CloseSidePanel } from "./CloseSidePanel.svelte" diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/manifest.json b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/manifest.json index 521ad85f0a..7497990304 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/manifest.json +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/manifest.json @@ -117,6 +117,11 @@ "component": "ShowNotification", "dependsOnFeature": "showNotificationAction" }, + { + "name": "Prompt User", + "type": "application", + "component": "PromptUser" + }, { "name": "Open Side Panel", "type": "application", diff --git a/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/_components/DynamicVariableModal.svelte b/packages/builder/src/components/integration/DynamicVariableModal.svelte similarity index 100% rename from packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/_components/DynamicVariableModal.svelte rename to packages/builder/src/components/integration/DynamicVariableModal.svelte diff --git a/packages/builder/src/components/integration/QueryViewer.svelte b/packages/builder/src/components/integration/QueryViewer.svelte index 6a49ffa634..2109356c74 100644 --- a/packages/builder/src/components/integration/QueryViewer.svelte +++ b/packages/builder/src/components/integration/QueryViewer.svelte @@ -29,11 +29,12 @@ export let query + const transformerDocs = "https://docs.budibase.com/docs/transformers" + let fields = query?.schema ? schemaToFields(query.schema) : [] let parameters let data = [] let saveId - const transformerDocs = "https://docs.budibase.com/docs/transformers" $: datasource = $datasources.list.find(ds => ds._id === query.datasourceId) $: query.schema = fieldsToSchema(fields) @@ -94,132 +95,144 @@ try { const { _id } = await queries.save(query.datasourceId, query) saveId = _id - notifications.success(`Query saved successfully.`) - $goto(`../${_id}`) + notifications.success(`Query saved successfully`) + + // Go to the correct URL if we just created a new query + if (!query._rev) { + $goto(`../../${_id}`) + } } catch (error) { - notifications.error("Error creating query") + notifications.error("Error saving query") } } - - Query {integrationInfo?.friendlyName} - - Config -
-
- - -
- {#if queryConfig} -
- -
- Add a JavaScript function to transform the query result. - (query.transformer = e.detail)} - /> - -
-
- Results - - - - -
- - Below, you can preview the results from your query and change the schema. - -
- {#if data} - - - - - - - - - - - + {#if queryConfig} +
+ +