Skip to content

Commit

Permalink
Merge branch 'master' into ai-assistant-node-data-improvements
Browse files Browse the repository at this point in the history
* master:
  refactor(core): Set up worker server (#10814)
  fix(Google Vertex Chat Model Node): Clean service account private key (#10770)
  test(core): Mock filesystem in tests (#10823)
  test(core): Fix license mock in worker test (#10824)
  ci: Ignore certain paths for e2e tests for PRs (no-changelog) (#10533)
  fix(editor): Render image binary-data using img tags (#10829)
  refactor(core): Move `instanceType` to `InstanceSettings` (no-changelog) (#10640)
  ci(benchmark): Always perform az login before teardown (#10827)
  fix: Prevent copying workflow when copying outside of canvas (#10813)
  fix: Fix telemetry causing console error (#10828)
  refactor: Remove unused disable directives from `nodes-base` (#10825)
  refactor(core): Remove unused disable directives from backend packages (#10826)
  chore: Upgrade to TypeScript 5.6 (#10822)
  fix(editor): Prevent clipboard XSS injection (#10805)
  refactor(core): Simplify createDeferredPromise, and add tests (no-changelog) (#10811)
  fix(HTTP Request Tool Node): Fix subsequent tool calls reusung the same options (#10808)
  fix(editor): Make expression edit modal read-only in executions view (#10806)
  refactor(core): Move push message types to a new shared package (no-changelog) (#10742)
  fix(editor): Make schema view search copy more clear (#10807)
  • Loading branch information
MiloradFilipovic committed Sep 17, 2024
2 parents 60db641 + 94aa680 commit 29db847
Show file tree
Hide file tree
Showing 150 changed files with 2,089 additions and 1,454 deletions.
1 change: 1 addition & 0 deletions .github/workflows/benchmark-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ jobs:

# We need to login again because the access token expires
- name: Azure login
if: always()
uses: azure/login@v2.1.1
with:
client-id: ${{ env.ARM_CLIENT_ID }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/check-documentation-urls.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
run: pnpm install --frozen-lockfile

- name: Build relevant packages
run: pnpm --filter @n8n/client-oauth2 --filter @n8n/imap --filter n8n-workflow --filter n8n-core --filter n8n-nodes-base --filter @n8n/n8n-nodes-langchain build
run: pnpm build:nodes

- run: npm install --prefix=.github/scripts --no-package-lock

Expand Down
42 changes: 36 additions & 6 deletions .github/workflows/chromatic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,49 @@ on:
workflow_dispatch:
pull_request_review:
types: [submitted]
branches:
- 'master'
paths:
- packages/design-system/**
- .github/workflows/chromatic.yml

concurrency:
group: chromatic-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
get-metadata:
name: Get Metadata
runs-on: ubuntu-latest
steps:
- name: Check out current commit
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 2

- name: Determine changed files
uses: tomi/paths-filter-action@v3.0.2
id: changed
if: github.event_name == 'pull_request_review'
with:
filters: |
design_system:
- packages/design-system/**
- .github/workflows/chromatic.yml
outputs:
design_system_files_changed: ${{ steps.changed.outputs.design_system == 'true' }}
is_community_pr: ${{ contains(github.event.pull_request.labels.*.name, 'community') }}
is_pr_target_master: ${{ github.event.pull_request.base.ref == 'master' }}
is_dispatch: ${{ github.event_name == 'workflow_dispatch' }}
is_pr_approved: ${{ github.event.review.state == 'approved' }}

chromatic:
if: ${{ github.event.review.state == 'approved' && !contains(github.event.pull_request.labels.*.name, 'community') }}
needs: [get-metadata]
if: |
needs.get-metadata.outputs.is_dispatch == 'true' ||
(
needs.get-metadata.outputs.design_system_files_changed == 'true' &&
needs.get-metadata.outputs.is_community_pr == 'false' &&
needs.get-metadata.outputs.is_pr_target_master == 'true' &&
needs.get-metadata.outputs.is_pr_approved == 'true'
)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.1
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/ci-postgres-mysql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ on:
- .github/workflows/ci-postgres-mysql.yml
pull_request_review:
types: [submitted]
branches:
- 'release/*'

concurrency:
group: db-${{ github.event.pull_request.number || github.ref }}
Expand All @@ -21,6 +19,7 @@ jobs:
build:
name: Install & Build
runs-on: ubuntu-latest
if: github.event_name != 'pull_request_review' || startsWith(github.event.pull_request.base.ref, 'release/')
steps:
- uses: actions/checkout@v4.1.1
- run: corepack enable
Expand Down
44 changes: 38 additions & 6 deletions .github/workflows/e2e-tests-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,51 @@ name: PR E2E
on:
pull_request_review:
types: [submitted]
branches:
- 'master'
- 'release/*'

concurrency:
group: e2e-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
get-metadata:
name: Get Metadata
runs-on: ubuntu-latest
steps:
- name: Check out current commit
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 2

- name: Determine changed files
uses: tomi/paths-filter-action@v3.0.2
id: changed
with:
filters: |
not_ignored:
- '!.devcontainer/**'
- '!.github/*'
- '!.github/scripts/*'
- '!.github/workflows/benchmark-*'
- '!.github/workflows/check-*'
- '!.vscode/**'
- '!docker/**'
- '!packages/@n8n/benchmark/**'
- '!**/*.md'
predicate-quantifier: 'every'

outputs:
# The workflow should run when:
# - It has changes to files that are not ignored
# - It is not a community PR
# - It is targeting master or a release branch
should_run: ${{ steps.changed.outputs.not_ignored == 'true' && !contains(github.event.pull_request.labels.*.name, 'community') && (github.event.pull_request.base.ref == 'master' || startsWith(github.event.pull_request.base.ref, 'release/')) }}

run-e2e-tests:
name: E2E [Electron/Node 18]
uses: ./.github/workflows/e2e-reusable.yml
if: ${{ github.event.review.state == 'approved' && !contains(github.event.pull_request.labels.*.name, 'community') }}
needs: [get-metadata]
if: ${{ github.event.review.state == 'approved' && needs.get-metadata.outputs.should_run == 'true' }}
with:
pr_number: ${{ github.event.pull_request.number }}
user: ${{ github.event.pull_request.user.login || 'PR User' }}
Expand All @@ -25,11 +57,11 @@ jobs:
post-e2e-tests:
runs-on: ubuntu-latest
name: E2E [Electron/Node 18] - Checks
needs: [run-e2e-tests]
needs: [get-metadata, run-e2e-tests]
if: always()
steps:
- name: E2E success comment
if: ${{!contains(github.event.pull_request.labels.*.name, 'community') && needs.run-e2e-tests.outputs.tests_passed == 'true' }}
if: ${{ needs.get-metadata.outputs.should_run == 'true' && needs.run-e2e-tests.outputs.tests_passed == 'true' }}
uses: peter-evans/create-or-update-comment@v4.0.0
with:
issue-number: ${{ github.event.pull_request.number }}
Expand Down
55 changes: 55 additions & 0 deletions cypress/e2e/45-ai-assistant.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,3 +374,58 @@ describe('AI Assistant Credential Help', () => {
aiAssistant.getters.credentialEditAssistantButton().should('be.disabled');
});
});

describe('General help', () => {
beforeEach(() => {
aiAssistant.actions.enableAssistant();
wf.actions.visit();
});

it('assistant returns code snippet', () => {
cy.intercept('POST', '/rest/ai-assistant/chat', {
statusCode: 200,
fixture: 'aiAssistant/code_snippet_response.json',
}).as('chatRequest');

aiAssistant.getters.askAssistantFloatingButton().should('be.visible');
aiAssistant.getters.askAssistantFloatingButton().click();
aiAssistant.getters.askAssistantChat().should('be.visible');
aiAssistant.getters.placeholderMessage().should('be.visible');
aiAssistant.getters.chatInput().should('be.visible');

aiAssistant.getters.chatInput().type('Show me an expression');
aiAssistant.getters.sendMessageButton().click();

aiAssistant.getters.chatMessagesAll().should('have.length', 3);
aiAssistant.getters.chatMessagesUser().eq(0).should('contain.text', 'Show me an expression');

aiAssistant.getters
.chatMessagesAssistant()
.eq(0)
.should('contain.text', 'To use expressions in n8n, follow these steps:');

aiAssistant.getters
.chatMessagesAssistant()
.eq(0)
.should(
'include.html',
`<pre><code class="language-json">[
{
"headers": {
"host": "n8n.instance.address",
...
},
"params": {},
"query": {},
"body": {
"name": "Jim",
"age": 30,
"city": "New York"
}
}
]
</code></pre>`,
);
aiAssistant.getters.codeSnippet().should('have.text', '{{$json.body.city}}');
});
});
28 changes: 28 additions & 0 deletions cypress/fixtures/aiAssistant/code_snippet_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"sessionId": "f1d19ed5-0d55-4bad-b49a-f0c56bd6f76f-705b5dbf-12d4-4805-87a3-1e5b3c716d29-W1JgVNrpfitpSNF9rAjB4",
"messages": [
{
"role": "assistant",
"type": "message",
"text": "To use expressions in n8n, follow these steps:\n\n1. Hover over the parameter where you want to use an expression.\n2. Select **Expressions** in the **Fixed/Expression** toggle.\n3. Write your expression in the parameter, or select **Open expression editor** to open the expressions editor. You can browse the available data in the **Variable selector**. All expressions have the format `{{ your expression here }}`.\n\n### Example: Get data from webhook body\n\nIf your webhook data looks like this:\n\n```json\n[\n {\n \"headers\": {\n \"host\": \"n8n.instance.address\",\n ...\n },\n \"params\": {},\n \"query\": {},\n \"body\": {\n \"name\": \"Jim\",\n \"age\": 30,\n \"city\": \"New York\"\n }\n }\n]\n```\n\nYou can use the following expression to get the value of `city`:\n\n```js\n{{$json.body.city}}\n```\n\nThis expression accesses the incoming JSON-formatted data using n8n's custom `$json` variable and finds the value of `city` (in this example, \"New York\").",
"codeSnippet": "{{$json.body.city}}"
},
{
"role": "assistant",
"type": "message",
"text": "Did this answer solve your question?",
"quickReplies": [
{
"text": "Yes, thanks",
"type": "all-good",
"isFeedback": true
},
{
"text": "No, I am still stuck",
"type": "still-stuck",
"isFeedback": true
}
]
}
]
}
1 change: 1 addition & 0 deletions cypress/pages/features/ai-assistant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class AIAssistant extends BasePage {
cy.getByTestId('node-error-view-ask-assistant-button').find('button').first(),
credentialEditAssistantButton: () =>
cy.getByTestId('credentail-edit-ask-assistant-button').find('button').first(),
codeSnippet: () => cy.getByTestId('assistant-code-snippet'),
};

actions = {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"semver": "^7.5.4",
"tslib": "^2.6.2",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.5.2",
"typescript": "^5.6.2",
"ws": ">=8.17.1"
},
"patchedDependencies": {
Expand Down
7 changes: 7 additions & 0 deletions packages/@n8n/api-types/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const sharedOptions = require('@n8n_io/eslint-config/shared');

/** @type {import('@types/eslint').ESLint.ConfigData} */
module.exports = {
extends: ['@n8n_io/eslint-config/base'],
...sharedOptions(__dirname),
};
3 changes: 3 additions & 0 deletions packages/@n8n/api-types/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## @n8n/api-types

This package contains types and schema definitions for the n8n internal API, so that these can be shared between the backend and the frontend code.
2 changes: 2 additions & 0 deletions packages/@n8n/api-types/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/** @type {import('jest').Config} */
module.exports = require('../../../jest.config');
24 changes: 24 additions & 0 deletions packages/@n8n/api-types/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@n8n/api-types",
"version": "0.1.0",
"scripts": {
"clean": "rimraf dist .turbo",
"dev": "pnpm watch",
"typecheck": "tsc --noEmit",
"build": "tsc -p tsconfig.build.json",
"format": "prettier --write . --ignore-path ../../../.prettierignore",
"lint": "eslint .",
"lintfix": "eslint . --fix",
"watch": "tsc -p tsconfig.build.json --watch",
"test": "echo \"No tests yet\" && exit 0"
},
"main": "dist/index.js",
"module": "src/index.ts",
"types": "dist/index.d.ts",
"files": [
"dist/**/*"
],
"devDependencies": {
"n8n-workflow": "workspace:*"
}
}
2 changes: 2 additions & 0 deletions packages/@n8n/api-types/src/datetime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/** Date time in the ISO 8601 format, e.g. 2024-10-31T00:00:00.123Z */
export type Iso8601DateTimeString = string;
7 changes: 7 additions & 0 deletions packages/@n8n/api-types/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type * from './push';
export type * from './scaling';
export type * from './datetime';
export type * from './user';

export type { Collaborator } from './push/collaboration';
export type { SendWorkerStatusMessage } from './push/worker';
17 changes: 17 additions & 0 deletions packages/@n8n/api-types/src/push/collaboration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Iso8601DateTimeString } from '../datetime';
import type { MinimalUser } from '../user';

export type Collaborator = {
user: MinimalUser;
lastSeen: Iso8601DateTimeString;
};

type CollaboratorsChanged = {
type: 'collaboratorsChanged';
data: {
workflowId: string;
collaborators: Collaborator[];
};
};

export type CollaborationPushMessage = CollaboratorsChanged;
9 changes: 9 additions & 0 deletions packages/@n8n/api-types/src/push/debug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
type SendConsoleMessage = {
type: 'sendConsoleMessage';
data: {
source: string;
messages: unknown[];
};
};

export type DebugPushMessage = SendConsoleMessage;
53 changes: 53 additions & 0 deletions packages/@n8n/api-types/src/push/execution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { IRun, ITaskData, WorkflowExecuteMode } from 'n8n-workflow';

type ExecutionStarted = {
type: 'executionStarted';
data: {
executionId: string;
mode: WorkflowExecuteMode;
startedAt: Date;
workflowId: string;
workflowName?: string;
retryOf?: string;
};
};

type ExecutionFinished = {
type: 'executionFinished';
data: {
executionId: string;
data: IRun;
retryOf?: string;
};
};

type ExecutionRecovered = {
type: 'executionRecovered';
data: {
executionId: string;
};
};

type NodeExecuteBefore = {
type: 'nodeExecuteBefore';
data: {
executionId: string;
nodeName: string;
};
};

type NodeExecuteAfter = {
type: 'nodeExecuteAfter';
data: {
executionId: string;
nodeName: string;
data: ITaskData;
};
};

export type ExecutionPushMessage =
| ExecutionStarted
| ExecutionFinished
| ExecutionRecovered
| NodeExecuteBefore
| NodeExecuteAfter;
Loading

0 comments on commit 29db847

Please sign in to comment.