E2E matrix (Windows) #1131
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: E2E matrix (Windows) | |
on: | |
schedule: | |
- cron: "0 5 * * *" | |
workflow_dispatch: | |
inputs: | |
debug_enabled: | |
type: boolean | |
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)' | |
required: false | |
default: false | |
env: | |
CYPRESS_CACHE_FOLDER: ${{ github.workspace }}/.cypress | |
permissions: { } | |
jobs: | |
preinstall: | |
if: ${{ github.repository_owner == 'nrwl' }} | |
runs-on: windows-latest | |
strategy: | |
matrix: | |
node_version: | |
- 18 | |
- 20 | |
- 22 | |
# - 23 | |
name: Cache install (node v${{ matrix.node_version }}) | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- uses: pnpm/action-setup@v4 | |
name: Install pnpm | |
with: | |
version: 9.8.0 | |
run_install: false | |
- name: Set node | |
uses: actions/setup-node@v4 | |
with: | |
node-version: ${{ matrix.node_version }} | |
cache: 'pnpm' | |
- name: Cache node_modules | |
id: cache-modules | |
uses: actions/cache@v4 | |
with: | |
lookup-only: true | |
path: '**/node_modules' | |
key: ${{ runner.os }}-modules-${{ matrix.node_version }}-${{ hashFiles('pnpm-lock.yaml') }} | |
- name: Install packages | |
if: steps.cache-modules.outputs.cache-hit != 'true' | |
run: pnpm install --frozen-lockfile | |
- name: Cache Cypress | |
id: cache-cypress | |
uses: actions/cache@v4 | |
with: | |
lookup-only: true | |
path: '${{ github.workspace }}/.cypress' | |
key: windows-cypress | |
- name: Install Cypress | |
if: steps.cache-cypress.outputs.cache-hit != 'true' | |
run: pnpm cypress install | |
e2e: | |
if: ${{ github.repository_owner == 'nrwl' }} | |
needs: preinstall | |
permissions: | |
contents: read | |
runs-on: windows-latest | |
strategy: | |
matrix: | |
node_version: | |
- 18 | |
- 20 | |
- 22 | |
# - 23 | |
package_manager: | |
- npm | |
project: | |
- e2e-angular | |
- e2e-cypress | |
- e2e-esbuild | |
- e2e-eslint | |
- e2e-jest | |
- e2e-js | |
- e2e-lerna-smoke-tests | |
- e2e-next | |
- e2e-node | |
- e2e-nuxt | |
- e2e-nx-init | |
- e2e-nx | |
- e2e-playwright | |
- e2e-plugin | |
- e2e-react | |
- e2e-release | |
- e2e-remix | |
- e2e-rollup | |
- e2e-storybook | |
- e2e-vite | |
- e2e-vue | |
- e2e-web | |
- e2e-webpack | |
- e2e-workspace-create | |
include: | |
# codeowner groups | |
- project: e2e-angular | |
codeowners: 'S04SS457V38' | |
- project: e2e-cypress | |
codeowners: 'S04T16BTJJY' | |
- project: e2e-esbuild | |
codeowners: 'S04SJ6HHP0X' | |
- project: e2e-jest | |
codeowners: 'S04T16BTJJY' | |
- project: e2e-js | |
codeowners: 'S04SJ6HHP0X' | |
- project: e2e-lerna-smoke-tests | |
codeowners: 'S04TNCVEETS' | |
- project: e2e-eslint | |
codeowners: 'S04SYJGKSCT' | |
- project: e2e-next | |
codeowners: 'S04TNCNJG5N' | |
- project: e2e-node | |
codeowners: 'S04SJ6HHP0X' | |
- project: e2e-nx-init | |
codeowners: 'S04SYHYKGNP' | |
- project: e2e-nx | |
codeowners: 'S04SYHYKGNP' | |
- project: e2e-plugin | |
codeowners: 'S04SYHYKGNP' | |
- project: e2e-release | |
codeowners: 'S04SYHYKGNP' | |
- project: e2e-react | |
codeowners: 'S04TNCNJG5N' | |
- project: e2e-web | |
codeowners: 'S04SJ6PL98X' | |
- project: e2e-rollup | |
codeowners: 'S04SJ6PL98X' | |
- project: e2e-storybook | |
codeowners: 'S04SVQ8H0G5' | |
- project: e2e-playwright | |
codeowners: 'S04SVQ8H0G5' | |
- project: e2e-remix | |
codeowners: 'S04SVQ8H0G5' | |
- project: e2e-vite | |
codeowners: 'S04SJ6PL98X' | |
- project: e2e-vue | |
codeowners: 'S04SJ6PL98X' | |
- project: e2e-nuxt | |
codeowners: 'S04SJ6PL98X' | |
- project: e2e-webpack | |
codeowners: 'S04SJ6PL98X' | |
- project: e2e-workspace-create | |
codeowners: 'S04SYHYKGNP' | |
exclude: | |
# exclude non-CNW/Lerna tests from non-LTS node versions | |
- node_version: 18 | |
project: e2e-angular | |
- node_version: 18 | |
project: e2e-cypress | |
- node_version: 18 | |
project: e2e-esbuild | |
- node_version: 18 | |
project: e2e-jest | |
- node_version: 18 | |
project: e2e-js | |
- node_version: 18 | |
project: e2e-eslint | |
- node_version: 18 | |
project: e2e-next | |
- node_version: 18 | |
project: e2e-node | |
- node_version: 18 | |
project: e2e-nuxt | |
- node_version: 18 | |
project: e2e-nx-init | |
- node_version: 18 | |
project: e2e-nx | |
- node_version: 18 | |
project: e2e-plugin | |
- node_version: 18 | |
project: e2e-playwright | |
- node_version: 18 | |
project: e2e-react | |
- node_version: 18 | |
project: e2e-web | |
- node_version: 18 | |
project: e2e-remix | |
- node_version: 18 | |
project: e2e-rollup | |
- node_version: 18 | |
project: e2e-storybook | |
- node_version: 18 | |
project: e2e-vite | |
- node_version: 18 | |
project: e2e-vue | |
- node_version: 18 | |
project: e2e-webpack | |
- node_version: 22 | |
project: e2e-angular | |
- node_version: 22 | |
project: e2e-cypress | |
- node_version: 22 | |
project: e2e-esbuild | |
- node_version: 22 | |
project: e2e-jest | |
- node_version: 22 | |
project: e2e-js | |
- node_version: 22 | |
project: e2e-eslint | |
- node_version: 22 | |
project: e2e-next | |
- node_version: 22 | |
project: e2e-node | |
- node_version: 22 | |
project: e2e-nuxt | |
- node_version: 22 | |
project: e2e-nx-init | |
- node_version: 22 | |
project: e2e-nx | |
- node_version: 22 | |
project: e2e-plugin | |
- node_version: 22 | |
project: e2e-playwright | |
- node_version: 22 | |
project: e2e-react | |
- node_version: 22 | |
project: e2e-web | |
- node_version: 22 | |
project: e2e-remix | |
- node_version: 22 | |
project: e2e-rollup | |
- node_version: 22 | |
project: e2e-storybook | |
- node_version: 22 | |
project: e2e-vite | |
- node_version: 22 | |
project: e2e-vue | |
- node_version: 22 | |
project: e2e-webpack | |
# - node_version: 23 | |
# project: e2e-angular | |
# - node_version: 23 | |
# project: e2e-cypress | |
# - node_version: 23 | |
# project: e2e-esbuild | |
# - node_version: 23 | |
# project: e2e-jest | |
# - node_version: 23 | |
# project: e2e-js | |
# - node_version: 23 | |
# project: e2e-eslint | |
# - node_version: 23 | |
# project: e2e-next | |
# - node_version: 23 | |
# project: e2e-node | |
# - node_version: 23 | |
# project: e2e-nuxt | |
# - node_version: 23 | |
# project: e2e-nx-init | |
# - node_version: 23 | |
# project: e2e-nx | |
# - node_version: 23 | |
# project: e2e-plugin | |
# - node_version: 23 | |
# project: e2e-playwright | |
# - node_version: 23 | |
# project: e2e-react | |
# - node_version: 23 | |
# project: e2e-web | |
# - node_version: 23 | |
# project: e2e-remix | |
# - node_version: 23 | |
# project: e2e-rollup | |
# - node_version: 23 | |
# project: e2e-storybook | |
# - node_version: 23 | |
# project: e2e-vite | |
# - node_version: 23 | |
# project: e2e-vue | |
# - node_version: 23 | |
# project: e2e-webpack | |
fail-fast: false | |
name: ${{ matrix.project }} (v${{ matrix.node_version }}) | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Prepare dir for output | |
run: mkdir -p outputs | |
- uses: pnpm/action-setup@v4 | |
name: Install pnpm | |
with: | |
version: 9.8.0 | |
run_install: false | |
- name: Use Node.js ${{ matrix.node_version }} | |
uses: actions/setup-node@v4 | |
with: | |
node-version: ${{ matrix.node_version }} | |
cache: 'pnpm' | |
- name: Cache node_modules | |
id: cache-modules | |
uses: actions/cache@v4 | |
with: | |
path: '**/node_modules' | |
key: ${{ runner.os }}-modules-${{ matrix.node_version }}-${{ github.run_id }} | |
- name: Install packages | |
run: pnpm install --frozen-lockfile | |
- name: Cache Cypress | |
id: cache-cypress | |
uses: actions/cache@v4 | |
with: | |
path: '${{ github.workspace }}/.cypress' | |
key: ${{ runner.os }}-cypress | |
- name: Install Cypress | |
if: steps.cache-cypress.outputs.cache-hit != 'true' | |
run: npx cypress install | |
- name: Configure git metadata (needed for lerna smoke tests) | |
run: | | |
git config --global user.email test@test.com | |
git config --global user.name "Test Test" | |
- name: Run e2e tests | |
id: e2e-run | |
run: pnpm nx run ${{ matrix.project }}:e2e-local | |
shell: bash | |
timeout-minutes: 180 | |
env: | |
GIT_AUTHOR_EMAIL: test@test.com | |
GIT_AUTHOR_NAME: Test | |
GIT_COMMITTER_EMAIL: test@test.com | |
GIT_COMMITTER_NAME: Test | |
NX_E2E_CI_CACHE_KEY: e2e-gha-windows-${{ matrix.node_version }}-${{ matrix.package_manager }} | |
NODE_OPTIONS: --max_old_space_size=8192 | |
SELECTED_PM: ${{ matrix.package_manager }} | |
npm_config_registry: http://localhost:4872 | |
NX_CACHE_DIRECTORY: 'tmp' | |
NX_E2E_SKIP_CLEANUP: 'true' | |
NX_E2E_RUN_E2E: 'true' | |
NX_E2E_VERBOSE_LOGGING: 'true' | |
NX_PERF_LOGGING: 'false' | |
NX_DAEMON: 'true' | |
NX_SKIP_LOG_GROUPING: 'true' | |
- name: Save matrix config in file | |
if: ${{ always() }} | |
id: save-matrix | |
shell: bash | |
run: | | |
matrix=$(( | |
echo '${{ toJSON(matrix) }}' | |
) | jq -c '. + { "status": "${{ steps.e2e-run.outcome}}" }') | |
echo "$matrix" > matrix | |
path=outputs/windows-${{ matrix.node_version}}-${{ matrix.package_manager}}-${{ matrix.project }} | |
echo "path=$path" >> $GITHUB_OUTPUT | |
echo "$matrix" > $path | |
- name: Upload matrix config | |
uses: actions/upload-artifact@v4 | |
if: ${{ always() }} | |
with: | |
name: outputs | |
overwrite: true | |
if-no-files-found: 'ignore' | |
path: ${{ steps.save-matrix.outputs.path }} | |
- name: Setup tmate session | |
if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled && failure() }} | |
uses: mxschmitt/action-tmate@v3.8 | |
timeout-minutes: 15 | |
with: | |
sudo: false # disable sudo for windows debugging | |
process-result: | |
if: ${{ always() && github.repository_owner == 'nrwl' }} | |
runs-on: ubuntu-latest | |
needs: e2e | |
outputs: | |
message: ${{ steps.process-json.outputs.SLACK_MESSAGE }} | |
codeowners: ${{ steps.process-json.outputs.CODEOWNERS }} | |
steps: | |
- name: Load outputs | |
uses: actions/download-artifact@v4 | |
with: | |
name: outputs | |
path: outputs | |
- name: Join and stringify matrix configs | |
id: combine-json | |
shell: bash | |
run: | | |
combined=$((jq -s . outputs/*) | jq tostring) | |
echo "combined=$combined" >> $GITHUB_OUTPUT | |
- name: Make slack outputs | |
id: process-json | |
uses: actions/github-script@v7 | |
env: | |
GITHUB_TOKEN: ${{ github.token }} | |
with: | |
script: | | |
const combined = JSON.parse(${{ steps.combine-json.outputs.combined }}); | |
const failedProjects = combined.filter(c => c.status === 'failure').sort((a, b) => a.project.localeCompare(b.project)); | |
// codeowners | |
const codeowners = new Set(); | |
failedProjects.forEach(c => { | |
codeowners.add(c.codeowners); | |
}); | |
core.setOutput('CODEOWNERS', Array.from(codeowners).join(',')); | |
// message | |
let result = ` | |
*OS* Windows | |
*Package manager* npm | |
\`\`\` | |
| Failed project | Node | | |
|--------------------------------|------|`; | |
failedProjects.forEach(matrix => { | |
result += `\n| ${matrix.project.padEnd(30)} | v${matrix.node_version} |` | |
}); | |
result += `\`\`\``; | |
const message = result.split('\n').map(l => l.trim()).join('\n'); | |
core.setOutput('SLACK_MESSAGE', message); | |
report-failure: | |
if: ${{ failure() && github.repository_owner == 'nrwl' && github.event_name != 'workflow_dispatch' }} | |
needs: process-result | |
runs-on: ubuntu-latest | |
name: Report failure | |
steps: | |
- name: Send notification | |
uses: ravsamhq/notify-slack-action@v2 | |
with: | |
status: 'failure' | |
message_format: '{emoji} Workflow has {status_message} ${{ needs.process-result.outputs.message }}' | |
notification_title: '{workflow}' | |
footer: '<{run_url}|View Run> / Last commit <{commit_url}|{commit_sha}>' | |
mention_groups: ${{ needs.process-result.outputs.codeowners }} | |
env: | |
SLACK_WEBHOOK_URL: ${{ secrets.ACTION_MONITORING_SLACK }} | |
report-success: | |
if: ${{ success() && github.repository_owner == 'nrwl' && github.event_name != 'workflow_dispatch' }} | |
needs: e2e | |
runs-on: ubuntu-latest | |
name: Report success | |
steps: | |
- name: Send notification | |
uses: ravsamhq/notify-slack-action@v2 | |
with: | |
status: ${{ needs.e2e.result }} | |
message_format: '{emoji} Workflow has {status_message}' | |
notification_title: '{workflow}' | |
footer: '<{run_url}|View Run> / Last commit <{commit_url}|{commit_sha}>' | |
env: | |
SLACK_WEBHOOK_URL: ${{ secrets.ACTION_MONITORING_SLACK }} |