mirror of
https://github.com/n8n-io/n8n
synced 2026-04-21 15:47:20 +00:00
181 lines
7.1 KiB
YAML
181 lines
7.1 KiB
YAML
name: 'Test: E2E'
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
branch:
|
|
description: 'GitHub branch to test.'
|
|
required: false
|
|
type: string
|
|
test-mode:
|
|
description: 'Test mode: local (pnpm start from local), docker-build, or docker-pull'
|
|
required: false
|
|
default: 'local'
|
|
type: string
|
|
test-command:
|
|
description: 'Test command to run'
|
|
required: false
|
|
default: 'pnpm --filter=n8n-playwright test:local'
|
|
type: string
|
|
shards:
|
|
description: 'Number of parallel shards'
|
|
required: false
|
|
default: 8
|
|
type: number
|
|
docker-image:
|
|
description: 'Docker image to use (for docker-pull mode). The runners image is derived automatically from the n8n image.'
|
|
required: false
|
|
default: 'n8nio/n8n:nightly'
|
|
type: string
|
|
workers:
|
|
description: 'Number of parallel workers'
|
|
required: false
|
|
default: ''
|
|
type: string
|
|
runner:
|
|
description: 'GitHub runner to use'
|
|
required: false
|
|
default: 'blacksmith-2vcpu-ubuntu-2204'
|
|
type: string
|
|
use-custom-orchestration:
|
|
description: 'Use duration-based custom orchestration instead of Playwright sharding'
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
timeout-minutes:
|
|
description: 'Job timeout in minutes'
|
|
required: false
|
|
default: 30
|
|
type: number
|
|
upload-failure-artifacts:
|
|
description: 'Upload test failure artifacts (screenshots, traces, videos). Enable for community PRs without Currents access.'
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
currents-project-id:
|
|
description: 'Currents project ID for reporting'
|
|
required: false
|
|
default: 'LRxcNt'
|
|
type: string
|
|
pre-generated-matrix:
|
|
description: 'Pre-generated shard matrix JSON (skips matrix job if provided)'
|
|
required: false
|
|
default: ''
|
|
type: string
|
|
|
|
|
|
env:
|
|
NODE_OPTIONS: ${{ contains(inputs.runner, '2vcpu') && '--max-old-space-size=6144' || '' }}
|
|
PLAYWRIGHT_WORKERS: ${{ inputs.workers != '' && inputs.workers || '2' }}
|
|
# Browser cache location - must match install-browsers script
|
|
PLAYWRIGHT_BROWSERS_PATH: packages/testing/playwright/.playwright-browsers
|
|
TEST_IMAGE_N8N: ${{ inputs.test-mode == 'docker-build' && 'n8nio/n8n:local' || inputs.docker-image }}
|
|
N8N_SKIP_LICENSES: 'true'
|
|
CURRENTS_CI_BUILD_ID: ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}
|
|
CURRENTS_PROJECT_ID: ${{ inputs.currents-project-id }}
|
|
|
|
jobs:
|
|
matrix:
|
|
if: ${{ inputs.pre-generated-matrix == '' }}
|
|
runs-on: ${{ vars.RUNNER_PROVIDER == 'github' && 'ubuntu-latest' || 'blacksmith-2vcpu-ubuntu-2204' }}
|
|
outputs:
|
|
matrix: ${{ steps.generate.outputs.matrix }}
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
ref: ${{ inputs.branch || github.ref }}
|
|
fetch-depth: 1
|
|
|
|
- name: Setup Environment
|
|
uses: ./.github/actions/setup-nodejs
|
|
with:
|
|
build-command: ''
|
|
|
|
- name: Generate shard matrix
|
|
id: generate
|
|
run: echo "matrix=$(node packages/testing/playwright/scripts/distribute-tests.mjs --matrix ${{ inputs.shards }} ${{ inputs.use-custom-orchestration && '--orchestrate' || '' }})" >> "$GITHUB_OUTPUT"
|
|
|
|
test:
|
|
needs: matrix
|
|
if: ${{ !cancelled() }}
|
|
runs-on: ${{ vars.RUNNER_PROVIDER == 'github' && 'ubuntu-latest' || inputs.runner }}
|
|
timeout-minutes: ${{ inputs.timeout-minutes }}
|
|
permissions:
|
|
packages: read
|
|
contents: read
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include: ${{ fromJSON(inputs.pre-generated-matrix || needs.matrix.outputs.matrix) }}
|
|
name: Shard ${{ matrix.shard }}
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
fetch-depth: 1
|
|
ref: ${{ inputs.branch || github.ref }}
|
|
|
|
- name: Setup Environment
|
|
uses: ./.github/actions/setup-nodejs
|
|
with:
|
|
# docker-build: build app + docker image locally
|
|
# docker-pull: no build needed, image is pre-built
|
|
# local: build app for local server
|
|
build-command: ${{ inputs.test-mode == 'docker-build' && 'pnpm build:docker' || 'pnpm build' }}
|
|
enable-docker-cache: ${{ inputs.test-mode == 'docker-build' }}
|
|
env:
|
|
INCLUDE_TEST_CONTROLLER: ${{ inputs.test-mode == 'docker-build' && 'true' || '' }}
|
|
|
|
- name: Install Browsers
|
|
run: pnpm turbo run install-browsers --filter=n8n-playwright
|
|
|
|
- name: Login to GHCR
|
|
if: ${{ inputs.test-mode == 'docker-pull' }}
|
|
uses: ./.github/actions/docker-registry-login
|
|
|
|
- name: Pre-pull Test Container Images
|
|
if: ${{ !contains(inputs.test-command, 'test:local') }}
|
|
run: npx tsx packages/testing/containers/pull-test-images.ts ${{ matrix.images }} || true
|
|
|
|
- name: Run Tests
|
|
# Uses pre-distributed specs if orchestration enabled, otherwise falls back to Playwright sharding
|
|
run: ${{ inputs.test-command }} --workers=${{ env.PLAYWRIGHT_WORKERS }} ${{ matrix.specs || format('--shard={0}/{1}', matrix.shard, strategy.job-total) }}
|
|
env:
|
|
CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
|
|
QA_METRICS_WEBHOOK_URL: ${{ secrets.QA_METRICS_WEBHOOK_URL }}
|
|
QA_METRICS_WEBHOOK_USER: ${{ secrets.QA_METRICS_WEBHOOK_USER }}
|
|
QA_METRICS_WEBHOOK_PASSWORD: ${{ secrets.QA_METRICS_WEBHOOK_PASSWORD }}
|
|
N8N_LICENSE_ACTIVATION_KEY: ${{ secrets.N8N_LICENSE_ACTIVATION_KEY }}
|
|
N8N_LICENSE_CERT: ${{ secrets.N8N_LICENSE_CERT }}
|
|
N8N_ENCRYPTION_KEY: ${{ secrets.N8N_ENCRYPTION_KEY }}
|
|
|
|
- name: Upload Failure Artifacts
|
|
if: ${{ failure() && inputs.upload-failure-artifacts }}
|
|
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
|
with:
|
|
name: playwright-report-shard-${{ matrix.shard }}
|
|
path: |
|
|
packages/testing/playwright/test-results/
|
|
packages/testing/playwright/playwright-report/
|
|
retention-days: 7
|
|
|
|
- name: Cleanup cached CI images
|
|
if: ${{ inputs.test-mode == 'docker-pull' }}
|
|
continue-on-error: true
|
|
run: |
|
|
docker images --format '{{.Repository}}:{{.Tag}}' | grep -E 'ghcr\.io/n8n-io/(n8n|runners):(ci|pr)-' | xargs -r docker rmi || true
|
|
docker system prune -f || true
|
|
|
|
- name: Cancel Currents run if workflow is cancelled
|
|
if: ${{ cancelled() }}
|
|
env:
|
|
CURRENTS_API_KEY: ${{ secrets.CURRENTS_API_KEY }}
|
|
run: |
|
|
if [ -n "$CURRENTS_API_KEY" ]; then
|
|
curl --location --request PUT \
|
|
"https://api.currents.dev/v1/runs/cancel-ci/github" \
|
|
--header "Authorization: Bearer $CURRENTS_API_KEY" \
|
|
--header "Content-Type: application/json" \
|
|
--data "{\"githubRunId\": \"${{ github.run_id }}\", \"githubRunAttempt\": \"${{ github.run_attempt }}\"}"
|
|
fi
|