Merge pull request #2471 from mslourens/rename_automation

Rename automation
This commit is contained in:
Martin McKeaveney 2021-09-17 09:51:54 +01:00 committed by GitHub
commit 73da6d9296
24 changed files with 154 additions and 82 deletions

View File

@ -1,6 +1,6 @@
name: Budibase Release name: Budibase Release
on: on:
push: push:
branches: branches:
- master - master
@ -9,20 +9,20 @@ env:
POSTHOG_TOKEN: ${{ secrets.POSTHOG_TOKEN }} POSTHOG_TOKEN: ${{ secrets.POSTHOG_TOKEN }}
POSTHOG_URL: ${{ secrets.POSTHOG_URL }} POSTHOG_URL: ${{ secrets.POSTHOG_URL }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
jobs: jobs:
release: release:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-node@v1 - uses: actions/setup-node@v1
with: with:
node-version: 12.x node-version: 12.x
- run: yarn - run: yarn
- run: yarn bootstrap - run: yarn bootstrap
- run: yarn lint - run: yarn lint
- run: yarn build - run: yarn build
- run: yarn test - run: yarn test
- name: Configure AWS Credentials - name: Configure AWS Credentials
@ -35,11 +35,11 @@ jobs:
- name: Publish budibase packages to NPM - name: Publish budibase packages to NPM
env: env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: | run: |
# setup the username and email. I tend to use 'GitHub Actions Bot' with no email by default # setup the username and email. I tend to use 'GitHub Actions Bot' with no email by default
git config user.name "Budibase Release Bot" git config user.name "Budibase Release Bot"
git config user.email "<>" git config user.email "<>"
echo //registry.npmjs.org/:_authToken=${NPM_TOKEN} >> .npmrc echo //registry.npmjs.org/:_authToken=${NPM_TOKEN} >> .npmrc
yarn release yarn release
- name: 'Get Previous tag' - name: 'Get Previous tag'
@ -47,7 +47,7 @@ jobs:
uses: "WyriHaximus/github-action-get-previous-tag@v1" uses: "WyriHaximus/github-action-get-previous-tag@v1"
- name: Build/release Docker images - name: Build/release Docker images
run: | run: |
docker login -u $DOCKER_USER -p $DOCKER_PASSWORD docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
yarn build yarn build
yarn build:docker yarn build:docker
@ -68,4 +68,3 @@ jobs:
charts_dir: docs charts_dir: docs
env: env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

View File

@ -6,6 +6,6 @@ builder: GPLv3
server: GPLv3 server: GPLv3
client: MPLv2.0 client: MPLv2.0
You can consider Budibase to be GPLv3 licensed. You can consider Budibase to be GPLv3 licensed.
The apps that you build with Budibase do not fall under GPLv3 - hence why our components and client library are licensed differently. The apps that you build with Budibase do not fall under GPLv3 - hence why our components and client library are licensed differently.

View File

@ -108,7 +108,7 @@ services:
depends_on: depends_on:
- couchdb-service - couchdb-service
command: ["sh","-c","sleep 10 && $${PUT_CALL}/_users && $${PUT_CALL}/_replicator; fg;"] command: ["sh","-c","sleep 10 && $${PUT_CALL}/_users && $${PUT_CALL}/_replicator; fg;"]
redis-service: redis-service:
restart: always restart: always
image: redis image: redis
@ -117,7 +117,7 @@ services:
- "${REDIS_PORT}:6379" - "${REDIS_PORT}:6379"
volumes: volumes:
- redis_data:/data - redis_data:/data
watchtower-service: watchtower-service:
image: containrrr/watchtower image: containrrr/watchtower
ports: ports:

View File

@ -44,7 +44,7 @@ ingress:
nginx: true nginx: true
certificateArn: "" certificateArn: ""
className: "" className: ""
annotations: annotations:
kubernetes.io/ingress.class: nginx kubernetes.io/ingress.class: nginx
hosts: hosts:
- host: # change if using custom domain - host: # change if using custom domain
@ -55,7 +55,7 @@ ingress:
service: service:
name: proxy-service name: proxy-service
port: port:
number: 10000 number: 10000
resources: {} resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious # We usually recommend not to specify default resources and to leave this as a conscious
@ -86,7 +86,7 @@ globals:
budibaseEnv: PRODUCTION budibaseEnv: PRODUCTION
enableAnalytics: false enableAnalytics: false
posthogToken: "" posthogToken: ""
sentryDSN: "" sentryDSN: ""
logLevel: info logLevel: info
selfHosted: 1 selfHosted: 1
accountPortalUrL: "" accountPortalUrL: ""
@ -121,7 +121,7 @@ services:
password: "" # only change if pointing to existing couch server password: "" # only change if pointing to existing couch server
port: 5984 port: 5984
storage: 100Mi storage: 100Mi
redis: redis:
enabled: true # disable if using external redis enabled: true # disable if using external redis
port: 6379 port: 6379
@ -129,15 +129,15 @@ services:
url: "" # only change if pointing to existing redis cluster and enabled: false url: "" # only change if pointing to existing redis cluster and enabled: false
password: "budibase" # recommended to override if using built-in redis password: "budibase" # recommended to override if using built-in redis
storage: 100Mi storage: 100Mi
objectStore: objectStore:
minio: true minio: true
browser: true browser: true
port: 9000 port: 9000
replicaCount: 1 replicaCount: 1
accessKey: "" # AWS_ACCESS_KEY if using S3 or existing minio access key accessKey: "" # AWS_ACCESS_KEY if using S3 or existing minio access key
secretKey: "" # AWS_SECRET_ACCESS_KEY if using S3 or existing minio secret secretKey: "" # AWS_SECRET_ACCESS_KEY if using S3 or existing minio secret
region: "" # AWS_REGION if using S3 or existing minio secret region: "" # AWS_REGION if using S3 or existing minio secret
url: "" # only change if pointing to existing minio cluster and minio: false url: "" # only change if pointing to existing minio cluster and minio: false
storage: 100Mi storage: 100Mi

View File

@ -28,7 +28,7 @@ static_resources:
- match: { prefix: "/builder" } - match: { prefix: "/builder" }
route: route:
cluster: app-service cluster: app-service
- match: { prefix: "/app_" } - match: { prefix: "/app_" }
route: route:
cluster: app-service cluster: app-service
@ -50,13 +50,13 @@ static_resources:
route: route:
cluster: app-service cluster: app-service
# special case for when API requests are made, can just forward, not to minio # special case for when API requests are made, can just forward, not to minio
- match: { prefix: "/api/" } - match: { prefix: "/api/" }
route: route:
cluster: app-service cluster: app-service
- match: { prefix: "/worker/" } - match: { prefix: "/worker/" }
route: route:
cluster: worker-service cluster: worker-service
prefix_rewrite: "/" prefix_rewrite: "/"
@ -85,7 +85,7 @@ static_resources:
- lb_endpoints: - lb_endpoints:
- endpoint: - endpoint:
address: address:
socket_address: socket_address:
address: app-service.budibase.svc.cluster.local address: app-service.budibase.svc.cluster.local
port_value: 4002 port_value: 4002
@ -113,7 +113,7 @@ static_resources:
- lb_endpoints: - lb_endpoints:
- endpoint: - endpoint:
address: address:
socket_address: socket_address:
address: worker-service.budibase.svc.cluster.local address: worker-service.budibase.svc.cluster.local
port_value: 4001 port_value: 4001

View File

@ -30,4 +30,4 @@
c0,7.1-5.8,12.9-12.9,12.9H82.2z"/> c0,7.1-5.8,12.9-12.9,12.9H82.2z"/>
</g> </g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -45,21 +45,24 @@ const automationActions = store => ({
return state return state
}) })
}, },
save: async ({ automation }) => { save: async automation => {
const UPDATE_AUTOMATION_URL = `/api/automations` const UPDATE_AUTOMATION_URL = `/api/automations`
const response = await api.put(UPDATE_AUTOMATION_URL, automation) const response = await api.put(UPDATE_AUTOMATION_URL, automation)
const json = await response.json() const json = await response.json()
store.update(state => { store.update(state => {
const newAutomation = json.automation
const existingIdx = state.automations.findIndex( const existingIdx = state.automations.findIndex(
existing => existing._id === automation._id existing => existing._id === automation._id
) )
state.automations.splice(existingIdx, 1, json.automation) if (existingIdx !== -1) {
state.automations = state.automations state.automations.splice(existingIdx, 1, newAutomation)
store.actions.select(json.automation) state.automations = [...state.automations]
return state store.actions.select(newAutomation)
return state
}
}) })
}, },
delete: async ({ automation }) => { delete: async automation => {
const { _id, _rev } = automation const { _id, _rev } = automation
const DELETE_AUTOMATION_URL = `/api/automations/${_id}/${_rev}` const DELETE_AUTOMATION_URL = `/api/automations/${_id}/${_rev}`
await api.delete(DELETE_AUTOMATION_URL) await api.delete(DELETE_AUTOMATION_URL)
@ -69,17 +72,17 @@ const automationActions = store => ({
existing => existing._id === _id existing => existing._id === _id
) )
state.automations.splice(existingIdx, 1) state.automations.splice(existingIdx, 1)
state.automations = state.automations state.automations = [...state.automations]
state.selectedAutomation = null state.selectedAutomation = null
state.selectedBlock = null state.selectedBlock = null
return state return state
}) })
}, },
trigger: async ({ automation }) => { trigger: async automation => {
const { _id } = automation const { _id } = automation
return await api.post(`/api/automations/${_id}/trigger`) return await api.post(`/api/automations/${_id}/trigger`)
}, },
test: async ({ automation }, testData) => { test: async (automation, testData) => {
const { _id } = automation const { _id } = automation
const response = await api.post(`/api/automations/${_id}/test`, testData) const response = await api.post(`/api/automations/${_id}/test`, testData)
const json = await response.json() const json = await response.json()

View File

@ -38,10 +38,9 @@
actionVal actionVal
) )
automationStore.actions.addBlockToAutomation(newBlock) automationStore.actions.addBlockToAutomation(newBlock)
await automationStore.actions.save({ await automationStore.actions.save(
instanceId, $automationStore.selectedAutomation?.automation
automation: $automationStore.selectedAutomation?.automation, )
})
} }
</script> </script>

View File

@ -32,16 +32,15 @@
} }
async function deleteAutomation() { async function deleteAutomation() {
await automationStore.actions.delete({ await automationStore.actions.delete(
instanceId, $automationStore.selectedAutomation?.automation
automation: $automationStore.selectedAutomation?.automation, )
})
} }
async function testAutomation() { async function testAutomation() {
const result = await automationStore.actions.trigger({ const result = await automationStore.actions.trigger(
automation: $automationStore.selectedAutomation.automation, $automationStore.selectedAutomation.automation
}) )
if (result.status === 200) { if (result.status === 200) {
notifications.success( notifications.success(
`Automation ${$automationStore.selectedAutomation.automation.name} triggered successfully.` `Automation ${$automationStore.selectedAutomation.automation.name} triggered successfully.`

View File

@ -52,10 +52,9 @@
async function deleteStep() { async function deleteStep() {
automationStore.actions.deleteAutomationBlock(block) automationStore.actions.deleteAutomationBlock(block)
await automationStore.actions.save({ await automationStore.actions.save(
instanceId, $automationStore.selectedAutomation?.automation
automation: $automationStore.selectedAutomation?.automation, )
})
} }
</script> </script>

View File

@ -42,7 +42,10 @@
disabled={isError} disabled={isError}
onConfirm={() => { onConfirm={() => {
automationStore.actions.addTestDataToAutomation(testData) automationStore.actions.addTestDataToAutomation(testData)
automationStore.actions.test($automationStore.selectedAutomation, testData) automationStore.actions.test(
$automationStore.selectedAutomation?.automation,
testData
)
}} }}
cancelText="Cancel" cancelText="Cancel"
> >

View File

@ -29,10 +29,9 @@
webhookModal.show webhookModal.show
} }
await automationStore.actions.save({ await automationStore.actions.save(
instanceId, $automationStore.selectedAutomation?.automation
automation: $automationStore.selectedAutomation?.automation, )
})
notifications.success(`Automation ${name} created.`) notifications.success(`Automation ${name} created.`)

View File

@ -1,20 +1,17 @@
<script> <script>
import { goto } from "@roxi/routify" import { goto } from "@roxi/routify"
import { automationStore } from "builderStore" import { automationStore } from "builderStore"
import { database } from "stores/backend"
import { ActionMenu, MenuItem, notifications, Icon } from "@budibase/bbui" import { ActionMenu, MenuItem, notifications, Icon } from "@budibase/bbui"
import ConfirmDialog from "components/common/ConfirmDialog.svelte" import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import UpdateAutomationModal from "components/automation/AutomationPanel/UpdateAutomationModal.svelte"
export let automation export let automation
let confirmDeleteDialog let confirmDeleteDialog
$: instanceId = $database._id let updateAutomationDialog
async function deleteAutomation() { async function deleteAutomation() {
await automationStore.actions.delete({ await automationStore.actions.delete(automation)
instanceId,
automation,
})
notifications.success("Automation deleted.") notifications.success("Automation deleted.")
$goto("../automate") $goto("../automate")
} }
@ -24,9 +21,8 @@
<div slot="control" class="icon"> <div slot="control" class="icon">
<Icon s hoverable name="MoreSmallList" /> <Icon s hoverable name="MoreSmallList" />
</div> </div>
<MenuItem noClose icon="Delete" on:click={confirmDeleteDialog.show}> <MenuItem icon="Edit" on:click={updateAutomationDialog.show}>Edit</MenuItem>
Delete <MenuItem icon="Delete" on:click={confirmDeleteDialog.show}>Delete</MenuItem>
</MenuItem>
</ActionMenu> </ActionMenu>
<ConfirmDialog <ConfirmDialog
@ -39,6 +35,7 @@
<i>{automation.name}?</i> <i>{automation.name}?</i>
This action cannot be undone. This action cannot be undone.
</ConfirmDialog> </ConfirmDialog>
<UpdateAutomationModal {automation} bind:this={updateAutomationDialog} />
<style> <style>
div.icon { div.icon {

View File

@ -0,0 +1,76 @@
<script>
import { automationStore } from "builderStore"
import { notifications } from "@budibase/bbui"
import { Icon, Input, ModalContent, Modal } from "@budibase/bbui"
import analytics from "analytics"
let name
let error = ""
let modal
export let automation
export let onCancel = undefined
export const show = () => {
name = automation?.name
modal.show()
}
export const hide = () => {
modal.hide()
}
async function saveAutomation() {
const updatedAutomation = {
...automation,
name,
}
await automationStore.actions.save(updatedAutomation)
notifications.success(`Automation ${name} updated successfully.`)
analytics.captureEvent("Automation Saved", { name })
hide()
}
function checkValid(evt) {
name = evt.target.value
if (!name) {
error = "Name is required"
return
}
error = ""
}
</script>
<Modal bind:this={modal} on:hide={onCancel}>
<ModalContent
title="Edit Automation"
confirmText="Save"
size="L"
onConfirm={saveAutomation}
disabled={error}
>
<Input bind:value={name} label="Name" on:input={checkValid} {error} />
<a
slot="footer"
target="_blank"
href="https://docs.budibase.com/automate/introduction-to-automate"
>
<Icon name="InfoOutline" />
<span>Learn about automations</span>
</a>
</ModalContent>
</Modal>
<style>
a {
color: var(--ink);
font-size: 14px;
vertical-align: middle;
display: flex;
align-items: center;
text-decoration: none;
}
a span {
text-decoration: underline;
margin-left: var(--spectrum-alias-item-padding-s);
}
</style>

View File

@ -56,10 +56,9 @@
testData[key] = e.detail testData[key] = e.detail
} else { } else {
block.inputs[key] = e.detail block.inputs[key] = e.detail
await automationStore.actions.save({ await automationStore.actions.save(
instanceId, $automationStore.selectedAutomation?.automation
automation: $automationStore.selectedAutomation?.automation, )
})
} }
}, },
isTestModal ? 0 : 800 isTestModal ? 0 : 800

View File

@ -18,10 +18,7 @@
onMount(async () => { onMount(async () => {
if (!automation?.definition?.trigger?.inputs.schemaUrl) { if (!automation?.definition?.trigger?.inputs.schemaUrl) {
// save the automation initially // save the automation initially
await automationStore.actions.save({ await automationStore.actions.save(automation)
instanceId,
automation,
})
} }
interval = setInterval(async () => { interval = setInterval(async () => {
await automationStore.actions.fetch() await automationStore.actions.fetch()

View File

@ -46,7 +46,9 @@
} }
automationStore.actions.addBlockToAutomation(newBlock) automationStore.actions.addBlockToAutomation(newBlock)
await automationStore.actions.save($automationStore.selectedAutomation) await automationStore.actions.save(
$automationStore.selectedAutomation?.automation
)
parameters.automationId = $automationStore.selectedAutomation.automation._id parameters.automationId = $automationStore.selectedAutomation.automation._id
delete parameters.newAutomationName delete parameters.newAutomationName
} }

View File

@ -2049,7 +2049,7 @@
"setting": "optionsSource", "setting": "optionsSource",
"value": "provider" "value": "provider"
} }
}, },
{ {
"type": "options", "type": "options",
"key": "customOptions", "key": "customOptions",

View File

@ -62,4 +62,4 @@ describe("/metadata", () => {
expect(metadata.test).toBeUndefined() expect(metadata.test).toBeUndefined()
}) })
}) })
}) })

View File

@ -83,4 +83,4 @@ describe("Run through some parts of the automations system", () => {
expect(output.d).toBe(1) expect(output.d).toBe(1)
expect(output.e).toBe("help") expect(output.e).toBe("help")
}) })
}) })

View File

@ -9,4 +9,4 @@ describe("test the delay logic", () => {
// divide by two just so that test will always pass as long as there was some sort of delay // divide by two just so that test will always pass as long as there was some sort of delay
expect(now - before).toBeGreaterThanOrEqual(time / 2) expect(now - before).toBeGreaterThanOrEqual(time / 2)
}) })
}) })

View File

@ -45,4 +45,4 @@ describe("test the filter logic", () => {
it("check objects always false", async () => { it("check objects always false", async () => {
await checkFilter({}, FilterConditions.EQUAL, {}, false) await checkFilter({}, FilterConditions.EQUAL, {}, false)
}) })
}) })

View File

@ -48,4 +48,4 @@ describe("Test a query step automation", () => {
expect(res.rows.length).toBe(2) expect(res.rows.length).toBe(2)
expect(res.rows[0].name).toBe(NAME) expect(res.rows[0].name).toBe(NAME)
}) })
}) })

View File

@ -1219,4 +1219,4 @@
"description": "<p>Produce a humanized duration left/until given an amount of time and the type of time measurement.</p>\n" "description": "<p>Produce a humanized duration left/until given an amount of time and the type of time measurement.</p>\n"
} }
} }
} }