diff --git a/.github/workflows/docker-images-nightly.yml b/.github/workflows/docker-images-nightly.yml new file mode 100644 index 0000000000..c3a7829432 --- /dev/null +++ b/.github/workflows/docker-images-nightly.yml @@ -0,0 +1,38 @@ +name: Docker Nightly Image CI + +on: + schedule: + - cron: "0 2 * * *" + workflow_dispatch: + +jobs: + + build: + + runs-on: ubuntu-latest + + steps: + - + name: Checkout + uses: actions/checkout@v2 + - + name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - + name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - + name: Build and push + uses: docker/build-push-action@v2 + with: + context: . + file: ./docker/images/n8n-custom/Dockerfile + platforms: linux/amd64 + push: true + tags: n8nio/n8n:nightly diff --git a/.github/workflows/docker-images-rpi.yml b/.github/workflows/docker-images-rpi.yml index e2990e0d2c..155fd61158 100644 --- a/.github/workflows/docker-images-rpi.yml +++ b/.github/workflows/docker-images-rpi.yml @@ -26,8 +26,9 @@ jobs: - name: Run Buildx (push image) if: success() run: | - docker buildx build --platform linux/arm/v7 --build-arg N8N_VERSION=${{steps.vars.outputs.tag}} -t n8nio/n8n:${{steps.vars.outputs.tag}}-rpi --output type=image,push=true docker/images/n8n-rpi - - name: Tag Docker image with latest - run: docker tag n8nio/n8n:${{steps.vars.outputs.tag}}-rpi n8nio/n8n:latest-rpi - - name: Push docker images of latest - run: docker push n8nio/n8n:latest-rpi + docker buildx build \ + --platform linux/arm/v7 \ + --build-arg N8N_VERSION=${{steps.vars.outputs.tag}} \ + -t ${{ secrets.DOCKER_USERNAME }}/n8n:${{steps.vars.outputs.tag}}-rpi \ + -t ${{ secrets.DOCKER_USERNAME }}/n8n:latest-rpi \ + --output type=image,push=true docker/images/n8n-rpi diff --git a/.github/workflows/docker-images.yml b/.github/workflows/docker-images.yml index 8d034b5b91..6b5da8106b 100644 --- a/.github/workflows/docker-images.yml +++ b/.github/workflows/docker-images.yml @@ -28,7 +28,7 @@ jobs: - name: Push docker images of latest run: docker push n8nio/n8n:latest - - name: Build the Docker image of version (Ubuntu) - run: docker build --build-arg N8N_VERSION=${{steps.vars.outputs.tag}} -t n8nio/n8n:${{steps.vars.outputs.tag}}-ubuntu docker/images/n8n-ubuntu - - name: Push Docker image of version (Ubuntu) - run: docker push n8nio/n8n:${{steps.vars.outputs.tag}}-ubuntu + - name: Build the Docker image of version (Debian) + run: docker build --build-arg N8N_VERSION=${{steps.vars.outputs.tag}} -t n8nio/n8n:${{steps.vars.outputs.tag}}-debian docker/images/n8n-debian + - name: Push Docker image of version (Debian) + run: docker push n8nio/n8n:${{steps.vars.outputs.tag}}-debian diff --git a/README.md b/README.md index a0b4885a49..7fa03385ac 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![n8n.io - Workflow Automation](https://raw.githubusercontent.com/n8n-io/n8n/master/assets/n8n-logo.png) -n8n is an extendable workflow automation tool. With a [fair-code](http://faircode.io) distribution model, n8n will always have visible source code, be available to self-host, and allow you to add your own custom functions, logic and apps. n8n's node-based approach makes it highly versatile, enabling you to connect anything to everything. +n8n is an extendable workflow automation tool. With a [fair-code](http://faircode.io) distribution model, n8n will always have visible source code, be available to self-host, and allow you to add your own custom functions, logic and apps. n8n's node-based approach makes it highly versatile, enabling you to connect anything to everything. n8n.io - Screenshot @@ -16,7 +16,7 @@ received or lost a star. ## Available integrations -n8n has 170+ different nodes to automate workflows. The list can be found on: [https://n8n.io/nodes](https://n8n.io/nodes) +n8n has 200+ different nodes to automate workflows. The list can be found on: [https://n8n.io/nodes](https://n8n.io/nodes) ## Documentation @@ -91,6 +91,6 @@ Have you found a bug :bug: ? Or maybe you have a nice feature :sparkles: to cont ## License -n8n is [fair-code](http://faircode.io) licensed under [**Apache 2.0 with Commons Clause**](https://github.com/n8n-io/n8n/blob/master/packages/cli/LICENSE.md). +n8n is [fair-code](http://faircode.io) distributed under [**Apache 2.0 with Commons Clause**](https://github.com/n8n-io/n8n/blob/master/packages/cli/LICENSE.md) license. Additional information about license can be found in the [FAQ](https://docs.n8n.io/#/faq?id=license). diff --git a/docker/images/n8n-ubuntu/Dockerfile b/docker/images/n8n-debian/Dockerfile similarity index 100% rename from docker/images/n8n-ubuntu/Dockerfile rename to docker/images/n8n-debian/Dockerfile diff --git a/docker/images/n8n-ubuntu/README.md b/docker/images/n8n-debian/README.md similarity index 79% rename from docker/images/n8n-ubuntu/README.md rename to docker/images/n8n-debian/README.md index 3ee9b5bb69..525ac41c41 100644 --- a/docker/images/n8n-ubuntu/README.md +++ b/docker/images/n8n-debian/README.md @@ -1,6 +1,6 @@ -## n8n - Ubuntu Docker Image +## n8n - Debian Docker Image -Dockerfile to build n8n with Ubuntu. +Dockerfile to build n8n with Debian. For information about how to run n8n with Docker check the generic [Docker-Readme](https://github.com/n8n-io/n8n/tree/master/docker/images/n8n/README.md) @@ -10,12 +10,12 @@ For information about how to run n8n with Docker check the generic docker build --build-arg N8N_VERSION= -t n8nio/n8n: . # For example: -docker build --build-arg N8N_VERSION=0.43.0 -t n8nio/n8n:0.43.0-ubuntu . +docker build --build-arg N8N_VERSION=0.43.0 -t n8nio/n8n:0.43.0-debian . ``` ``` docker run -it --rm \ --name n8n \ -p 5678:5678 \ - n8nio/n8n:0.43.0-ubuntu + n8nio/n8n:0.43.0-debian ``` diff --git a/docker/images/n8n-ubuntu/docker-entrypoint.sh b/docker/images/n8n-debian/docker-entrypoint.sh similarity index 100% rename from docker/images/n8n-ubuntu/docker-entrypoint.sh rename to docker/images/n8n-debian/docker-entrypoint.sh diff --git a/docker/images/n8n-rpi/README.md b/docker/images/n8n-rpi/README.md index 9eca14e3f6..cc15b0c9d8 100644 --- a/docker/images/n8n-rpi/README.md +++ b/docker/images/n8n-rpi/README.md @@ -17,5 +17,6 @@ docker build --build-arg N8N_VERSION=0.43.0 -t n8nio/n8n:0.43.0-rpi . docker run -it --rm \ --name n8n \ -p 5678:5678 \ + -v ~/.n8n:/home/node/.n8n \ n8nio/n8n:0.70.0-rpi ``` diff --git a/docker/images/n8n/README.md b/docker/images/n8n/README.md index a23a63cef5..5a8198ed9d 100644 --- a/docker/images/n8n/README.md +++ b/docker/images/n8n/README.md @@ -2,7 +2,7 @@ ![n8n.io - Workflow Automation](https://raw.githubusercontent.com/n8n-io/n8n/master/assets/n8n-logo.png) -n8n is a free and open [fair-code](http://faircode.io) licensed node based Workflow Automation Tool. It can be self-hosted, easily extended, and so also used with internal tools. +n8n is a free and open [fair-code](http://faircode.io) distributed node based Workflow Automation Tool. It can be self-hosted, easily extended, and so also used with internal tools. n8n.io - Screenshot @@ -33,7 +33,7 @@ Slack notification every time a Github repository received or lost a star. ## Available integrations -n8n has 100+ different nodes to automate workflows. The list can be found on: [https://n8n.io/nodes](https://n8n.io/nodes) +n8n has 200+ different nodes to automate workflows. The list can be found on: [https://n8n.io/nodes](https://n8n.io/nodes) ## Documentation @@ -305,6 +305,6 @@ Before you upgrade to the latest version make sure to check here if there are an ## License -n8n is [fair-code](http://faircode.io) licensed under [**Apache 2.0 with Commons Clause**](https://github.com/n8n-io/n8n/blob/master/packages/cli/LICENSE.md) +n8n is [fair-code](http://faircode.io) distributed under [**Apache 2.0 with Commons Clause**](https://github.com/n8n-io/n8n/blob/master/packages/cli/LICENSE.md) license Additional information about license can be found in the [FAQ](https://docs.n8n.io/#/faq?id=license) diff --git a/docker/images/n8n/docker-entrypoint.sh b/docker/images/n8n/docker-entrypoint.sh index 153d01690d..fa81b3713c 100755 --- a/docker/images/n8n/docker-entrypoint.sh +++ b/docker/images/n8n/docker-entrypoint.sh @@ -6,6 +6,8 @@ if [ -d /root/.n8n ] ; then ln -s /root/.n8n /home/node/ fi +chown -R node /home/node + if [ "$#" -gt 0 ]; then # Got started with arguments exec su-exec node "$@" diff --git a/packages/cli/README.md b/packages/cli/README.md index b7cbd5417d..e7f951bbbe 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -2,7 +2,7 @@ ![n8n.io - Workflow Automation](https://raw.githubusercontent.com/n8n-io/n8n/master/assets/n8n-logo.png) -n8n is a free and open [fair-code](http://faircode.io) licensed node based Workflow Automation Tool. It can be self-hosted, easily extended, and so also used with internal tools. +n8n is a free and open [fair-code](http://faircode.io) distributed node based Workflow Automation Tool. It can be self-hosted, easily extended, and so also used with internal tools. n8n.io - Screenshot @@ -32,7 +32,7 @@ Slack notification every time a Github repository received or lost a star. ## Available integrations -n8n has 100+ different nodes to automate workflows. The list can be found on: [https://n8n.io/nodes](https://n8n.io/nodes) +n8n has 200+ different nodes to automate workflows. The list can be found on: [https://n8n.io/nodes](https://n8n.io/nodes) ## Documentation @@ -100,7 +100,7 @@ Before you upgrade to the latest version make sure to check here if there are an ## License -n8n is [fair-code](http://faircode.io) licensed under [**Apache 2.0 with Commons Clause**](https://github.com/n8n-io/n8n/blob/master/packages/cli/LICENSE.md) +n8n is [fair-code](http://faircode.io) distributed under [**Apache 2.0 with Commons Clause**](https://github.com/n8n-io/n8n/blob/master/packages/cli/LICENSE.md) license Additional information about license can be found in the [FAQ](https://docs.n8n.io/#/faq?id=license) diff --git a/packages/cli/commands/start.ts b/packages/cli/commands/start.ts index d6e16b7cb3..b6f0a39b3e 100644 --- a/packages/cli/commands/start.ts +++ b/packages/cli/commands/start.ts @@ -121,10 +121,16 @@ export class Start extends Command { const { flags } = this.parse(Start); // Wrap that the process does not close but we can still use async - (async () => { + await (async () => { try { // Start directly with the init of the database to improve startup time - const startDbInitPromise = Db.init(); + const startDbInitPromise = Db.init().catch(error => { + console.error(`There was an error initializing DB: ${error.message}`); + + processExistCode = 1; + // @ts-ignore + process.emit('SIGINT'); + }); // Make sure the settings exist const userSettings = await UserSettings.prepareUserSettings(); diff --git a/packages/cli/package.json b/packages/cli/package.json index a2e3a200aa..ac7c6ce5a3 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "n8n", - "version": "0.96.0", + "version": "0.99.1", "description": "n8n Workflow Automation Tool", "license": "SEE LICENSE IN LICENSE.md", "homepage": "https://n8n.io", @@ -103,9 +103,9 @@ "lodash.get": "^4.4.2", "mongodb": "^3.5.5", "mysql2": "~2.1.0", - "n8n-core": "~0.54.0", - "n8n-editor-ui": "~0.66.0", - "n8n-nodes-base": "~0.91.0", + "n8n-core": "~0.56.0", + "n8n-editor-ui": "~0.68.1", + "n8n-nodes-base": "~0.94.0", "n8n-workflow": "~0.47.0", "oauth-1.0a": "^2.2.6", "open": "^7.0.0", diff --git a/packages/cli/src/ResponseHelper.ts b/packages/cli/src/ResponseHelper.ts index d09011eac0..4458316dcf 100644 --- a/packages/cli/src/ResponseHelper.ts +++ b/packages/cli/src/ResponseHelper.ts @@ -64,7 +64,11 @@ export function sendSuccessResponse(res: Response, data: any, raw?: boolean, res } if (raw === true) { - res.json(data); + if (typeof data === 'string') { + res.send(data); + } else { + res.json(data); + } } else { res.json({ data, diff --git a/packages/cli/src/WorkflowExecuteAdditionalData.ts b/packages/cli/src/WorkflowExecuteAdditionalData.ts index 38916e89dc..a99c168407 100644 --- a/packages/cli/src/WorkflowExecuteAdditionalData.ts +++ b/packages/cli/src/WorkflowExecuteAdditionalData.ts @@ -44,9 +44,11 @@ import * as config from '../config'; import { LessThanOrEqual } from "typeorm"; +const ERROR_TRIGGER_TYPE = config.get('nodes.errorTriggerType') as string; + /** - * Checks if there was an error and if errorWorkflow is defined. If so it collects + * Checks if there was an error and if errorWorkflow or a trigger is defined. If so it collects * all the data and executes it * * @param {IWorkflowBase} workflowData The workflow which got executed @@ -55,14 +57,14 @@ import { LessThanOrEqual } from "typeorm"; * @param {string} [executionId] The id the execution got saved as */ function executeErrorWorkflow(workflowData: IWorkflowBase, fullRunData: IRun, mode: WorkflowExecuteMode, executionId?: string, retryOf?: string): void { - // Check if there was an error and if so if an errorWorkflow is set + // Check if there was an error and if so if an errorWorkflow or a trigger is set let pastExecutionUrl: string | undefined = undefined; if (executionId !== undefined) { pastExecutionUrl = `${WebhookHelpers.getWebhookBaseUrl()}execution/${executionId}`; } - if (fullRunData.data.resultData.error !== undefined && workflowData.settings !== undefined && workflowData.settings.errorWorkflow) { + if (fullRunData.data.resultData.error !== undefined) { const workflowErrorData = { execution: { id: executionId, @@ -77,8 +79,16 @@ function executeErrorWorkflow(workflowData: IWorkflowBase, fullRunData: IRun, mo name: workflowData.name, }, }; + // Run the error workflow - WorkflowHelpers.executeErrorWorkflow(workflowData.settings.errorWorkflow as string, workflowErrorData); + // To avoid an infinite loop do not run the error workflow again if the error-workflow itself failed and it is its own error-workflow. + if (workflowData.settings !== undefined && workflowData.settings.errorWorkflow && !(mode === 'error' && workflowData.id && workflowData.settings.errorWorkflow.toString() === workflowData.id.toString())) { + // If a specific error workflow is set run only that one + WorkflowHelpers.executeErrorWorkflow(workflowData.settings.errorWorkflow as string, workflowErrorData); + } else if (mode !== 'error' && workflowData.id !== undefined && workflowData.nodes.some((node) => node.type === ERROR_TRIGGER_TYPE)) { + // If the workflow contains + WorkflowHelpers.executeErrorWorkflow(workflowData.id.toString(), workflowErrorData); + } } } diff --git a/packages/core/package.json b/packages/core/package.json index cd8b36298e..6dd5793c99 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "n8n-core", - "version": "0.54.0", + "version": "0.56.0", "description": "Core functionality of n8n", "license": "SEE LICENSE IN LICENSE.md", "homepage": "https://n8n.io", diff --git a/packages/core/src/NodeExecuteFunctions.ts b/packages/core/src/NodeExecuteFunctions.ts index fcca59d9fe..e6bcbd24cb 100644 --- a/packages/core/src/NodeExecuteFunctions.ts +++ b/packages/core/src/NodeExecuteFunctions.ts @@ -172,6 +172,10 @@ export function requestOAuth2(this: IAllExecuteFunctions, credentialsType: strin client_secret: credentials.clientSecret as string, }; tokenRefreshOptions.body = body; + // Override authorization property so the credentails are not included in it + tokenRefreshOptions.headers = { + Authorization: '', + }; } const newToken = await token.refresh(tokenRefreshOptions); @@ -241,6 +245,15 @@ export function requestOAuth1(this: IAllExecuteFunctions, credentialsType: strin //@ts-ignore requestOptions.data = { ...requestOptions.qs, ...requestOptions.form }; + // Fixes issue that OAuth1 library only works with "url" property and not with "uri" + // @ts-ignore + if (requestOptions.uri && !requestOptions.url) { + // @ts-ignore + requestOptions.url = requestOptions.uri; + // @ts-ignore + delete requestOptions.uri; + } + //@ts-ignore requestOptions.headers = oauth.toHeader(oauth.authorize(requestOptions, token)); diff --git a/packages/editor-ui/package.json b/packages/editor-ui/package.json index 514c8d6d49..f42602a956 100644 --- a/packages/editor-ui/package.json +++ b/packages/editor-ui/package.json @@ -1,6 +1,6 @@ { "name": "n8n-editor-ui", - "version": "0.66.0", + "version": "0.68.1", "description": "Workflow Editor UI for n8n", "license": "SEE LICENSE IN LICENSE.md", "homepage": "https://n8n.io", @@ -61,7 +61,7 @@ "flatted": "^2.0.0", "jquery": "^3.4.1", "jshint": "^2.9.7", - "jsplumb": "^2.10.0", + "jsplumb": "2.15.4", "lodash.debounce": "^4.0.8", "lodash.get": "^4.4.2", "lodash.set": "^4.3.2", @@ -79,7 +79,7 @@ "uuid": "^8.1.0", "vue": "^2.6.9", "vue-cli-plugin-webpack-bundle-analyzer": "^2.0.0", - "vue-json-tree": "^0.4.1", + "vue-json-pretty": "^1.7.1", "vue-prism-editor": "^0.3.0", "vue-router": "^3.0.6", "vue-template-compiler": "^2.5.17", diff --git a/packages/editor-ui/src/components/BinaryDataDisplay.vue b/packages/editor-ui/src/components/BinaryDataDisplay.vue index c9aca4856d..c6ab2aa748 100644 --- a/packages/editor-ui/src/components/BinaryDataDisplay.vue +++ b/packages/editor-ui/src/components/BinaryDataDisplay.vue @@ -11,10 +11,10 @@
-
+
Data to display did not get found
- +
diff --git a/packages/editor-ui/src/components/FixedCollectionParameter.vue b/packages/editor-ui/src/components/FixedCollectionParameter.vue index 83ab3eda57..9588e51a80 100644 --- a/packages/editor-ui/src/components/FixedCollectionParameter.vue +++ b/packages/editor-ui/src/components/FixedCollectionParameter.vue @@ -10,8 +10,12 @@
-
+
+
+ + +
@@ -19,7 +23,7 @@
-
+
@@ -111,6 +115,9 @@ export default mixins(genericHelpers) } return []; }, + sortable (): string { + return this.parameter.typeOptions && this.parameter.typeOptions.sortable; + }, }, methods: { deleteOption (optionName: string, index?: number) { @@ -133,6 +140,26 @@ export default mixins(genericHelpers) return undefined; }, + moveOptionDown (optionName: string, index: number) { + this.values[optionName].splice(index + 1, 0, this.values[optionName].splice(index, 1)[0]); + + const parameterData = { + name: this.getPropertyPath(optionName), + value: this.values[optionName], + }; + + this.$emit('valueChanged', parameterData); + }, + moveOptionUp (optionName: string, index: number) { + this.values[optionName].splice(index - 1, 0, this.values[optionName].splice(index, 1)[0]); + + const parameterData = { + name: this.getPropertyPath(optionName), + value: this.values[optionName], + }; + + this.$emit('valueChanged', parameterData); + }, optionSelected (optionName: string) { const option = this.getOptionProperties(optionName); if (option === undefined) { diff --git a/packages/editor-ui/src/components/MultipleParameter.vue b/packages/editor-ui/src/components/MultipleParameter.vue index 7ba38ad738..b7423b1bf1 100644 --- a/packages/editor-ui/src/components/MultipleParameter.vue +++ b/packages/editor-ui/src/components/MultipleParameter.vue @@ -10,8 +10,12 @@
-
- +
+ +
+ + +
@@ -67,6 +71,9 @@ export default mixins(genericHelpers) hideDelete (): boolean { return this.parameter.options.length === 1; }, + sortable (): string { + return this.parameter.typeOptions && this.parameter.typeOptions.sortable; + }, }, methods: { addItem () { @@ -97,6 +104,26 @@ export default mixins(genericHelpers) getPath (index?: number): string { return this.path + (index !== undefined ? `[${index}]` : ''); }, + moveOptionDown (index: number) { + this.values.splice(index + 1, 0, this.values.splice(index, 1)[0]); + + const parameterData = { + name: this.path, + value: this.values, + }; + + this.$emit('valueChanged', parameterData); + }, + moveOptionUp (index: number) { + this.values.splice(index - 1, 0, this.values.splice(index, 1)[0]); + + const parameterData = { + name: this.path, + value: this.values, + }; + + this.$emit('valueChanged', parameterData); + }, valueChanged (parameterData: IUpdateInformation) { this.$emit('valueChanged', parameterData); }, @@ -125,6 +152,7 @@ export default mixins(genericHelpers) top: .3em; z-index: 999; color: #f56c6c; + width: 15px; :hover { color: #ff0000; diff --git a/packages/editor-ui/src/components/Node.vue b/packages/editor-ui/src/components/Node.vue index d8af701f4c..ab134df115 100644 --- a/packages/editor-ui/src/components/Node.vue +++ b/packages/editor-ui/src/components/Node.vue @@ -12,7 +12,7 @@
-
+
diff --git a/packages/editor-ui/src/components/RunData.vue b/packages/editor-ui/src/components/RunData.vue index b08f52e3dd..8ce435b6d6 100644 --- a/packages/editor-ui/src/components/RunData.vue +++ b/packages/editor-ui/src/components/RunData.vue @@ -62,6 +62,21 @@
+
+ + + + + + + + Copy Item Path + Copy Parameter Path + Copy Value + + + +
@@ -104,10 +119,18 @@
-
@@ -171,8 +194,8 @@