From 2210a05c865b6ccc5e22494315d3dfa384d2ae86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Wed, 7 Feb 2024 12:11:19 +0100 Subject: [PATCH] ci: Parallelize unit tests on the CI (no-changelog) --- .github/actions/build-n8n/action.yml | 37 ++++++++++ .github/workflows/ci-master.yml | 71 ++++--------------- .github/workflows/ci-postgres-mysql.yml | 6 +- .github/workflows/ci-pull-requests.yml | 58 +++------------ .github/workflows/e2e-tests-pr.yml | 2 +- .github/workflows/e2e-tests.yml | 2 +- .../{e2e-reusable.yml => reusable-e2e.yml} | 0 .github/workflows/reusable-linting.yml | 45 ++++++++++++ ...-reusable.yml => reusable-units-tests.yml} | 54 +++++++++----- .github/workflows/test-workflows.yml | 39 +++++++--- .github/workflows/units-tests-dispatch.yml | 20 +++++- package.json | 10 ++- 12 files changed, 202 insertions(+), 142 deletions(-) create mode 100644 .github/actions/build-n8n/action.yml rename .github/workflows/{e2e-reusable.yml => reusable-e2e.yml} (100%) create mode 100644 .github/workflows/reusable-linting.yml rename .github/workflows/{units-tests-reusable.yml => reusable-units-tests.yml} (52%) diff --git a/.github/actions/build-n8n/action.yml b/.github/actions/build-n8n/action.yml new file mode 100644 index 0000000000000..a3ca1d34df6dd --- /dev/null +++ b/.github/actions/build-n8n/action.yml @@ -0,0 +1,37 @@ +name: 'Build n8n' +description: 'Build n8n and cache the dist folder' +inputs: + ref: + description: 'GitHub ref to build' + required: true + type: string + cacheKey: + description: 'Cache key for modules and build artifacts' + required: true + type: string + nodeVersion: + description: 'Version of node to use.' + required: false + type: string + default: '18.x' + +runs: + using: 'composite' + steps: + - run: corepack enable + - uses: actions/setup-node@v4.0.1 + with: + node-version: ${{ inputs.nodeVersion }} + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm build + + - name: Cache build artifacts + uses: actions/cache/save@v4.0.0 + with: + path: ./packages/**/dist + key: ${{ inputs.cacheKey }} diff --git a/.github/workflows/ci-master.yml b/.github/workflows/ci-master.yml index 41ee830bd58ae..b729d5167e37c 100644 --- a/.github/workflows/ci-master.yml +++ b/.github/workflows/ci-master.yml @@ -6,83 +6,38 @@ on: - master jobs: - install-and-build: + build: runs-on: ubuntu-latest - - timeout-minutes: 30 - - strategy: - matrix: - node-version: [18.x, 20.x] - steps: - uses: actions/checkout@v4.1.1 - - - run: corepack enable - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.0.1 with: - node-version: ${{ matrix.node-version }} - cache: pnpm - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build - run: pnpm build + ref: ${{ github.sha }} - - name: Cache build artifacts - uses: actions/cache/save@v4.0.0 + - uses: ./.github/actions/build-n8n with: - path: ./packages/**/dist - key: ${{ github.sha }}-base:${{ matrix.node-version }}-test-lint + ref: ${{ github.sha }} + cacheKey: ${{ github.sha }}:build unit-test: name: Unit tests - uses: ./.github/workflows/units-tests-reusable.yml - needs: install-and-build + uses: ./.github/workflows/reusable-units-tests.yml + needs: build strategy: matrix: node-version: [18.x, 20.x] with: ref: ${{ inputs.branch }} nodeVersion: ${{ matrix.node-version }} - cacheKey: ${{ github.sha }}-base:${{ matrix.node-version }}-test-lint + cacheKey: ${{ github.sha }}:build collectCoverage: true lint: name: Lint changes - runs-on: ubuntu-latest - needs: install-and-build - strategy: - matrix: - node-version: [18.x, 20.x] - steps: - - uses: actions/checkout@v4.1.1 - with: - repository: n8n-io/n8n - ref: ${{ inputs.branch }} - - - run: corepack enable - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.0.1 - with: - node-version: ${{ matrix.node-version }} - cache: pnpm - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Restore cached build artifacts - uses: actions/cache/restore@v4.0.0 - with: - path: ./packages/**/dist - key: ${{ github.sha }}-base:${{ matrix.node-version }}-test-lint - - - name: Lint - env: - CI_LINT_MASTER: true - run: pnpm lint + uses: ./.github/workflows/reusable-linting.yml + needs: build + with: + ref: ${{ inputs.branch }} + cacheKey: ${{ github.sha }}:build notify-on-failure: name: Notify Slack on failure diff --git a/.github/workflows/ci-postgres-mysql.yml b/.github/workflows/ci-postgres-mysql.yml index b8d0395277286..0ab5d35c7d3cd 100644 --- a/.github/workflows/ci-postgres-mysql.yml +++ b/.github/workflows/ci-postgres-mysql.yml @@ -32,7 +32,7 @@ jobs: uses: actions/cache/save@v4.0.0 with: path: ./packages/**/dist - key: ${{ github.sha }}:db-tests + key: ${{ github.sha }}:build:backend mysql: name: MySQL @@ -54,7 +54,7 @@ jobs: uses: actions/cache/restore@v4.0.0 with: path: ./packages/**/dist - key: ${{ github.sha }}:db-tests + key: ${{ github.sha }}:build:backend - name: Start MySQL uses: isbang/compose-action@v1.5.1 @@ -87,7 +87,7 @@ jobs: uses: actions/cache/restore@v4.0.0 with: path: ./packages/**/dist - key: ${{ github.sha }}:db-tests + key: ${{ github.sha }}:build:backend - name: Start Postgres uses: isbang/compose-action@v1.5.1 diff --git a/.github/workflows/ci-pull-requests.yml b/.github/workflows/ci-pull-requests.yml index 17bfb05891725..46c319e5a2053 100644 --- a/.github/workflows/ci-pull-requests.yml +++ b/.github/workflows/ci-pull-requests.yml @@ -9,61 +9,25 @@ jobs: steps: - uses: actions/checkout@v4.1.1 with: - repository: n8n-io/n8n - ref: refs/pull/${{ github.event.pull_request.number }}/merge - - - run: corepack enable - - name: Use Node.js 18 - uses: actions/setup-node@v4.0.1 - with: - node-version: 18.x - cache: pnpm - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build - run: pnpm build + ref: ${{ github.sha }} - - name: Cache build artifacts - uses: actions/cache/save@v4.0.0 + - uses: ./.github/actions/build-n8n with: - path: ./packages/**/dist - key: ${{ github.sha }}-base:18-test-lint + ref: refs/pull/${{ github.event.pull_request.number }}/merge + cacheKey: ${{ github.sha }}:build unit-test: name: Unit tests - uses: ./.github/workflows/units-tests-reusable.yml + uses: ./.github/workflows/reusable-units-tests.yml needs: install with: ref: refs/pull/${{ github.event.pull_request.number }}/merge - cacheKey: ${{ github.sha }}-base:18-test-lint + cacheKey: ${{ github.sha }}:build lint: - name: Lint changes - runs-on: ubuntu-latest + name: Lint + uses: ./.github/workflows/reusable-linting.yml needs: install - steps: - - uses: actions/checkout@v4.1.1 - with: - repository: n8n-io/n8n - ref: refs/pull/${{ github.event.pull_request.number }}/merge - - - run: corepack enable - - name: Use Node.js 18 - uses: actions/setup-node@v4.0.1 - with: - node-version: 18.x - cache: pnpm - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Restore cached build artifacts - uses: actions/cache/restore@v4.0.0 - with: - path: ./packages/**/dist - key: ${{ github.sha }}-base:18-test-lint - - - name: Lint - run: pnpm lint + with: + ref: refs/pull/${{ github.event.pull_request.number }}/merge + cacheKey: ${{ github.sha }}:build diff --git a/.github/workflows/e2e-tests-pr.yml b/.github/workflows/e2e-tests-pr.yml index f845dbb06203f..e15e00628b75a 100644 --- a/.github/workflows/e2e-tests-pr.yml +++ b/.github/workflows/e2e-tests-pr.yml @@ -13,7 +13,7 @@ concurrency: jobs: run-e2e-tests: name: E2E [Electron/Node 18] - uses: ./.github/workflows/e2e-reusable.yml + uses: ./.github/workflows/reusable-e2e.yml if: ${{ github.event.review.state == 'approved' && !contains(github.event.pull_request.labels.*.name, 'community') }} with: pr_number: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index e7400adecbe25..92262486e7f04 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -41,7 +41,7 @@ jobs: run-e2e-tests: name: E2E [Electron/Node 18] - uses: ./.github/workflows/e2e-reusable.yml + uses: ./.github/workflows/reusable-e2e.yml with: branch: ${{ github.event.inputs.branch || 'master' }} user: ${{ github.event.inputs.user || 'PR User' }} diff --git a/.github/workflows/e2e-reusable.yml b/.github/workflows/reusable-e2e.yml similarity index 100% rename from .github/workflows/e2e-reusable.yml rename to .github/workflows/reusable-e2e.yml diff --git a/.github/workflows/reusable-linting.yml b/.github/workflows/reusable-linting.yml new file mode 100644 index 0000000000000..828f3f655c8bb --- /dev/null +++ b/.github/workflows/reusable-linting.yml @@ -0,0 +1,45 @@ +name: Reusable linting workflow + +on: + workflow_call: + inputs: + ref: + description: 'GitHub ref to lint.' + required: false + type: string + default: 'master' + cacheKey: + description: 'Cache key for modules and build artifacts.' + required: true + type: string + +jobs: + lint: + runs-on: ubuntu-latest + strategy: + matrix: + group: [backend, frontend, nodes] + steps: + - uses: actions/checkout@v4.1.1 + with: + repository: n8n-io/n8n + ref: ${{ inputs.ref }} + + - run: corepack enable + - name: Use Node.js 18 + uses: actions/setup-node@v4.0.1 + with: + node-version: 18.x + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Restore cached build artifacts + uses: actions/cache/restore@v4.0.0 + with: + path: ./packages/**/dist + key: ${{ inputs.cacheKey }} + + - name: Lint + run: pnpm lint:${{ matrix.group }} diff --git a/.github/workflows/units-tests-reusable.yml b/.github/workflows/reusable-units-tests.yml similarity index 52% rename from .github/workflows/units-tests-reusable.yml rename to .github/workflows/reusable-units-tests.yml index 386612678c1e5..740542b6936d2 100644 --- a/.github/workflows/units-tests-reusable.yml +++ b/.github/workflows/reusable-units-tests.yml @@ -1,4 +1,4 @@ -name: Reusable units test workflow +name: Reusable unit-test workflow on: workflow_call: @@ -15,8 +15,7 @@ on: default: '18.x' cacheKey: description: 'Cache key for modules and build artifacts.' - required: false - default: '' + required: true type: string collectCoverage: required: false @@ -25,10 +24,12 @@ on: jobs: unit-test: - name: Unit tests runs-on: ubuntu-latest env: COVERAGE_ENABLED: ${{ inputs.collectCoverage }} + strategy: + matrix: + group: [backend, frontend, nodes] steps: - uses: actions/checkout@v4.1.1 with: @@ -45,28 +46,43 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Build - if: ${{ inputs.cacheKey == '' }} - run: pnpm build - - name: Restore cached build artifacts - if: ${{ inputs.cacheKey != '' }} uses: actions/cache/restore@v4.0.0 with: path: ./packages/**/dist key: ${{ inputs.cacheKey }} - - name: Test Backend - run: pnpm test:backend - - - name: Test Nodes - run: pnpm test:nodes + - name: Test + run: pnpm test:${{ matrix.group }} - - name: Test Frontend - run: pnpm test:frontend + - name: Cache Coverage + if: ${{ inputs.collectCoverage == 'true' }} + uses: actions/cache/save@v4.0.0 + with: + path: ./packages/**/coverage + key: ${{ inputs.cacheKey }}:${{ matrix.group }}:coverage + upload-coverage: + name: Upload Coverage + if: ${{ inputs.collectCoverage == 'true' }} + runs-on: ubuntu-latest + needs: unit-test + steps: + - uses: actions/cache/restore@v4.0.0 + with: + path: ./packages/**/coverage + key: ${{ inputs.cacheKey }}:backend:coverage + - uses: actions/cache/restore@v4.0.0 + with: + path: ./packages/**/coverage + key: ${{ inputs.cacheKey }}:frontend:coverage + - uses: actions/cache/restore@v4.0.0 + with: + path: ./packages/**/coverage + key: ${{ inputs.cacheKey }}:nodes:coverage + - run: ls -R packages - name: Upload coverage to Codecov - if: ${{ inputs.collectCoverage == 'true' }} - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4.0.1 with: - files: packages/@n8n/chat/coverage/cobertura-coverage.xml,packages/@n8n/nodes-langchain/coverage/cobertura-coverage.xml,packages/@n8n/permissions/coverage/cobertura-coverage.xml,packages/@n8n/client-oauth2/coverage/cobertura-coverage.xml,packages/cli/coverage/cobertura-coverage.xml,packages/core/coverage/cobertura-coverage.xml,packages/design-system/coverage/cobertura-coverage.xml,packages/editor-ui/coverage/cobertura-coverage.xml,packages/nodes-base/coverage/cobertura-coverage.xml,packages/workflow/coverage/cobertura-coverage.xml + files: packages/**/coverage/cobertura-coverage.xml + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/test-workflows.yml b/.github/workflows/test-workflows.yml index 7856b42f4fd92..a315ee70611d0 100644 --- a/.github/workflows/test-workflows.yml +++ b/.github/workflows/test-workflows.yml @@ -6,11 +6,31 @@ on: workflow_dispatch: jobs: - run-test-workflows: + build: + name: Install & Build runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4.1.1 + - run: corepack enable + - uses: actions/setup-node@v4.0.1 + with: + node-version: 18.x + cache: 'pnpm' + - run: pnpm install --frozen-lockfile - timeout-minutes: 30 + - name: Build Backend + run: pnpm build:backend + - name: Cache build artifacts + uses: actions/cache/save@v4.0.0 + with: + path: ./packages/**/dist + key: ${{ github.sha }}:build:backend + + run-test-workflows: + runs-on: ubuntu-latest + needs: build + timeout-minutes: 30 steps: - name: Checkout uses: actions/checkout@v4.1.1 @@ -32,7 +52,7 @@ jobs: cache: 'pnpm' cache-dependency-path: 'n8n/pnpm-lock.yaml' - - name: Install dependencies + - name: Install OS dependencies run: | sudo apt update -y echo 'tzdata tzdata/Areas select Europe' | sudo debconf-set-selections @@ -40,12 +60,15 @@ jobs: DEBIAN_FRONTEND="noninteractive" sudo apt-get install -y graphicsmagick shell: bash - - name: pnpm install and build + - name: pnpm install working-directory: n8n - run: | - pnpm install --frozen-lockfile - pnpm build:backend - shell: bash + run: pnpm install --frozen-lockfile + + - name: Restore cached build artifacts + uses: actions/cache/restore@v4.0.0 + with: + path: ./packages/**/dist + key: ${{ github.sha }}:build:backend - name: Import credentials run: n8n/packages/cli/bin/n8n import:credentials --input=test-workflows/credentials.json diff --git a/.github/workflows/units-tests-dispatch.yml b/.github/workflows/units-tests-dispatch.yml index 5ad63f000e1fb..59a20797ad25d 100644 --- a/.github/workflows/units-tests-dispatch.yml +++ b/.github/workflows/units-tests-dispatch.yml @@ -31,9 +31,25 @@ jobs: fi echo "branch=$BRANCH_NAME" >> $GITHUB_OUTPUT + build: + name: Build + needs: prepare + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4.1.1 + with: + ref: ${{ needs.prepare.outputs.branch }} + + - uses: ./.github/actions/build-n8n + with: + ref: ${{ needs.prepare.outputs.branch }} + cacheKey: ${{ needs.prepare.outputs.branch }}:build + unit-test: name: Unit tests - needs: prepare - uses: ./.github/workflows/units-tests-reusable.yml + needs: [prepare, build] + uses: ./.github/workflows/reusable-units-tests.yml with: ref: ${{ needs.prepare.outputs.branch }} + cacheKey: ${{ needs.prepare.outputs.branch }}:build + collectCoverage: true # TODO: remove this before merging diff --git a/package.json b/package.json index 081e00282a197..fdb3426ffda6b 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "scripts": { "preinstall": "node scripts/block-npm-install.js", "build": "turbo run build", - "build:backend": "pnpm --filter=!@n8n/chat --filter=!n8n-design-system --filter=!n8n-editor-ui build", + "build:backend": "pnpm --filter=!@n8n/chat --filter=!n8n-design-system --filter=!n8n-editor-ui --filter=!n8n-nodes-base --filter=!@n8n/nodes-langchain build", + "build:nodes": "pnpm --filter=n8n-nodes-base --filter=@n8n/nodes-langchain build", "build:frontend": "pnpm --filter=@n8n/chat --filter=n8n-design-system --filter=n8n-editor-ui build", "typecheck": "turbo run typecheck", "dev": "turbo run dev --parallel --filter=!n8n-design-system --filter=!@n8n/chat", @@ -20,14 +21,17 @@ "format": "turbo run format && node scripts/format.mjs", "lint": "turbo run lint", "lintfix": "turbo run lintfix", + "lint:backend": "pnpm --filter=!@n8n/chat --filter=!n8n-design-system --filter=!n8n-editor-ui --filter=!n8n-nodes-base --filter=!@n8n/nodes-langchain lint", + "lint:nodes": "pnpm --filter=n8n-nodes-base --filter=@n8n/nodes-langchain lint", + "lint:frontend": "pnpm --filter=@n8n/chat --filter=n8n-design-system --filter=n8n-editor-ui lint", "optimize-svg": "find ./packages -name '*.svg' ! -name 'pipedrive.svg' -print0 | xargs -0 -P16 -L20 npx svgo", "start": "run-script-os", "start:default": "cd packages/cli/bin && ./n8n", "start:tunnel": "./packages/cli/bin/n8n start --tunnel", "start:windows": "cd packages/cli/bin && n8n", "test": "turbo run test", - "test:backend": "pnpm --filter=!@n8n/chat --filter=!n8n-design-system --filter=!n8n-editor-ui --filter=!n8n-nodes-base test", - "test:nodes": "pnpm --filter=n8n-nodes-base test", + "test:backend": "pnpm --filter=!@n8n/chat --filter=!n8n-design-system --filter=!n8n-editor-ui --filter=!n8n-nodes-base --filter=!@n8n/nodes-langchain test", + "test:nodes": "pnpm --filter=n8n-nodes-base --filter=@n8n/nodes-langchain test", "test:frontend": "pnpm --filter=@n8n/chat --filter=n8n-design-system --filter=n8n-editor-ui test", "watch": "turbo run watch --parallel", "webhook": "./packages/cli/bin/n8n webhook",