diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b24cd03..965dc824 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] # @TODO add windows-latest after we have the os agnostic macher + os: [ubuntu-latest, macos-latest, windows-latest] # @TODO add windows-latest after we have the os agnostic macher name: Unit tests runs-on: ${{ matrix.os }} steps: @@ -66,13 +66,13 @@ jobs: - name: Install dependencies run: npm ci - name: Unit test affected projects - run: npx nx affected -t unit-test --parallel=3 --verbose --coverage.enabled + run: npx nx affected -t unit-test --parallel=3 --coverage.enabled e2e: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] # @TODO add windows-latest after we know why it is running forever + os: [ubuntu-latest, macos-latest, windows-latest] # @TODO add windows-latest after we know why it is running forever name: E2E tests runs-on: ${{ matrix.os }} steps: @@ -90,4 +90,4 @@ jobs: - name: Install dependencies run: npm i - name: E2E test affected projects - run: NX_DAEMON=false; npx nx affected -t nxv-e2e --exclude="tag:type:example" --skipNxCache --verbose + run: npx nx affected -t nxv-e2e --exclude="tag:type:example" --skipNxCache --verbose diff --git a/e2e/nx-verdaccio-e2e/test/__snapshots__/plugin-create-nodes.e2e.test.ts.snap b/e2e/nx-verdaccio-e2e/test/__snapshots__/plugin-create-nodes.e2e.test.ts.snap index 57aa2a41..bf330bf7 100644 --- a/e2e/nx-verdaccio-e2e/test/__snapshots__/plugin-create-nodes.e2e.test.ts.snap +++ b/e2e/nx-verdaccio-e2e/test/__snapshots__/plugin-create-nodes.e2e.test.ts.snap @@ -1,114 +1,5 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`nx-verdaccio plugin create-nodes-v2 > should add environment targets to project with targetName e2e dynamically 1`] = ` -{ - "e2e": { - "configurations": {}, - "dependsOn": [ - { - "params": "forward", - "target": "nxv-env-setup", - }, - ], - "executor": "nx:noop", - "options": {}, - "parallelism": true, - }, - "nxv-e2e": { - "configurations": {}, - "dependsOn": [ - { - "params": "forward", - "target": "e2e", - }, - ], - "executor": "@push-based/nx-verdaccio:env-teardown", - "options": {}, - "parallelism": true, - }, - "nxv-env-bootstrap": { - "configurations": {}, - "executor": "@push-based/nx-verdaccio:env-bootstrap", - "options": {}, - "parallelism": true, - }, - "nxv-env-install": { - "configurations": {}, - "dependsOn": [ - { - "params": "forward", - "projects": "dependencies", - "target": "nxv-pkg-install", - }, - ], - "executor": "nx:run-commands", - "options": { - "command": "echo "dependencies installed for tmp/environments/lib-a-e2e"", - "environmentRoot": "tmp/environments/lib-a-e2e", - }, - "parallelism": true, - }, - "nxv-env-setup": { - "cache": true, - "configurations": {}, - "executor": "@push-based/nx-verdaccio:env-setup", - "inputs": [ - "{projectRoot}/project.json", - { - "runtime": "node --version", - }, - { - "runtime": "npm --version", - }, - { - "externalDependencies": [ - "verdaccio", - ], - }, - "^production", - ], - "options": {}, - "outputs": [ - "{options.environmentRoot}/.npmrc", - "{options.environmentRoot}/package.json", - "{options.environmentRoot}/package-lock.json", - "{options.environmentRoot}/node_modules", - ], - "parallelism": true, - }, - "nxv-env-teardown": { - "configurations": {}, - "executor": "@push-based/nx-verdaccio:env-teardown", - "options": {}, - "parallelism": true, - }, - "nxv-verdaccio-start": { - "configurations": {}, - "executor": "@nx/js:verdaccio", - "options": { - "clear": true, - "config": ".verdaccio/config.yml", - "environmentDir": "tmp/environments/lib-a-e2e", - "port": Any, - "projectName": "lib-a-e2e", - "storage": "tmp/environments/lib-a-e2e/storage", - }, - "outputs": [ - "{options.environmentRoot}/storage", - ], - "parallelism": true, - }, - "nxv-verdaccio-stop": { - "configurations": {}, - "executor": "@push-based/nx-verdaccio:kill-process", - "options": { - "filePath": "tmp/environments/verdaccio-registry.json", - }, - "parallelism": true, - }, -} -`; - exports[`nx-verdaccio plugin create-nodes-v2 > should add package targets to library project 1`] = ` { "nxv-pkg-install": { diff --git a/e2e/nx-verdaccio-e2e/test/plugin-create-nodes.e2e.test.ts b/e2e/nx-verdaccio-e2e/test/plugin-create-nodes.e2e.test.ts index a15eeca9..6cd0fab6 100644 --- a/e2e/nx-verdaccio-e2e/test/plugin-create-nodes.e2e.test.ts +++ b/e2e/nx-verdaccio-e2e/test/plugin-create-nodes.e2e.test.ts @@ -187,9 +187,10 @@ describe('nx-verdaccio plugin create-nodes-v2', () => { const { code, projectJson } = await nxShowProjectJson(cwd, projectAE2e); expect(code).toBe(0); - expect(projectJson.targets).toEqual( + expect(projectJson.targets).toStrictEqual( expect.objectContaining({ e2e: expect.objectContaining({ + configurations: {}, dependsOn: [ { params: 'forward', @@ -210,9 +211,10 @@ describe('nx-verdaccio plugin create-nodes-v2', () => { ], executor: 'nx:run-commands', options: { - environmentRoot: 'tmp/environments/lib-a-e2e', - command: - 'echo "dependencies installed for tmp/environments/lib-a-e2e"', + environmentRoot: expect.toMatchPath('tmp/environments/lib-a-e2e'), + command: expect.stringContaining( + 'echo "dependencies installed for' + ), }, }), [TARGET_ENVIRONMENT_SETUP]: expect.objectContaining({ @@ -244,16 +246,18 @@ describe('nx-verdaccio plugin create-nodes-v2', () => { options: expect.objectContaining({ clear: true, config: '.verdaccio/config.yml', - environmentDir: 'tmp/environments/lib-a-e2e', + environmentDir: expect.toMatchPath('tmp/environments/lib-a-e2e'), port: expect.any(Number), // random port number projectName: 'lib-a-e2e', - storage: 'tmp/environments/lib-a-e2e/storage', + storage: expect.toMatchPath('tmp/environments/lib-a-e2e/storage'), }), }), [TARGET_ENVIRONMENT_VERDACCIO_STOP]: expect.objectContaining({ executor: '@push-based/nx-verdaccio:kill-process', options: { - filePath: 'tmp/environments/verdaccio-registry.json', + filePath: expect.toMatchPath( + 'tmp/environments/verdaccio-registry.json' + ), }, }), [TARGET_ENVIRONMENT_E2E]: expect.objectContaining({ @@ -271,16 +275,6 @@ describe('nx-verdaccio plugin create-nodes-v2', () => { }) ); - expect({ - ...projectJson.targets, - [TARGET_ENVIRONMENT_VERDACCIO_START]: { - ...projectJson.targets?.[TARGET_ENVIRONMENT_VERDACCIO_START], - options: { - ...projectJson.targets?.[TARGET_ENVIRONMENT_VERDACCIO_START].options, - port: expect.any(Number), - }, - }, - }).toMatchSnapshot(); }); it('should NOT add environment targets to project without targetName e2e', async () => { diff --git a/e2e/nx-verdaccio-e2e/vite.config.ts b/e2e/nx-verdaccio-e2e/vite.config.ts index 5aa4a87e..fdc62ea3 100644 --- a/e2e/nx-verdaccio-e2e/vite.config.ts +++ b/e2e/nx-verdaccio-e2e/vite.config.ts @@ -24,5 +24,6 @@ export default defineConfig({ reportsDirectory: '../../coverage/projects/nx-verdaccio-e2e', provider: 'v8', }, + setupFiles: ['../../testing/test-setup/src/lib/extend/path-matcher.ts'], }, }); diff --git a/package-lock.json b/package-lock.json index 8fc9a85f..26fd6bdd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "license": "MIT", "dependencies": { - "@rollup/rollup-linux-x64-gnu": "*", + "@rollup/rollup-win32-x64-msvc": "*", "memfs": "^4.11.1", "simple-git": "^3.27.0", "tslib": "^2.3.0", @@ -61,7 +61,8 @@ "@nx/nx-darwin-arm64": "^19.6.6", "@nx/nx-darwin-x64": "^19.6.6", "@nx/nx-linux-x64-gnu": "^19.6.6", - "@rollup/rollup-linux-x64-gnu": "^4.24.0" + "@rollup/rollup-linux-x64-gnu": "^4.24.0", + "@rollup/rollup-win32-x64-msvc": "^4.24.0" } }, "node_modules/@ampproject/remapping": { @@ -3728,6 +3729,18 @@ "linux" ] }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "dev": true, diff --git a/package.json b/package.json index 841f05ec..33ac0371 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,8 @@ "@nx/nx-darwin-arm64": "^19.6.6", "@nx/nx-darwin-x64": "^19.6.6", "@nx/nx-linux-x64-gnu": "^19.6.6", - "@rollup/rollup-linux-x64-gnu": "^4.24.0" + "@rollup/rollup-linux-x64-gnu": "^4.24.0", + "@rollup/rollup-win32-x64-msvc": "^4.24.0" }, "nx": { "includedScripts": [] diff --git a/projects/nx-verdaccio/src/executors/env-bootstrap/bootstrap-env.unit-test.ts b/projects/nx-verdaccio/src/executors/env-bootstrap/bootstrap-env.unit-test.ts index 4b28b25d..9c6c3acc 100644 --- a/projects/nx-verdaccio/src/executors/env-bootstrap/bootstrap-env.unit-test.ts +++ b/projects/nx-verdaccio/src/executors/env-bootstrap/bootstrap-env.unit-test.ts @@ -68,14 +68,14 @@ describe('bootstrapEnvironment', () => { //environmentRoot: 'tmp/environments/my-lib-e2e', //keepServerRunning: true, projectName: 'my-lib-e2e', - storage: 'tmp/environments/my-lib-e2e/storage', + storage: expect.toMatchPath('tmp/environments/my-lib-e2e/storage'), readyWhen: 'Environment ready under', verbose: undefined, }); expect(setupNpmWorkspaceSpy).toHaveBeenCalledTimes(1); expect(setupNpmWorkspaceSpy).toHaveBeenCalledWith( - 'tmp/environments/my-lib-e2e', + expect.toMatchPath('tmp/environments/my-lib-e2e'), undefined ); @@ -85,14 +85,14 @@ describe('bootstrapEnvironment', () => { host: 'localhost', port: 4387, url: 'http://localhost:4873', - userconfig: 'tmp/environments/my-lib-e2e/.npmrc', + userconfig: expect.toMatchPath('tmp/environments/my-lib-e2e/.npmrc'), }, undefined ); expect(writeFileSpy).toHaveBeenCalledTimes(1); expect(writeFileSpy).toHaveBeenCalledWith( - 'tmp/environments/my-lib-e2e/verdaccio-registry.json', + expect.toMatchPath('tmp/environments/my-lib-e2e/verdaccio-registry.json'), JSON.stringify( { host: 'localhost', diff --git a/projects/nx-verdaccio/src/executors/env-bootstrap/executor.unit-test.ts b/projects/nx-verdaccio/src/executors/env-bootstrap/executor.unit-test.ts index 67a03b5b..ffc635a5 100644 --- a/projects/nx-verdaccio/src/executors/env-bootstrap/executor.unit-test.ts +++ b/projects/nx-verdaccio/src/executors/env-bootstrap/executor.unit-test.ts @@ -98,7 +98,9 @@ describe('runBootstrapExecutor', () => { expect(runExecutorSpy).toHaveBeenCalledWith( stopVerdaccioTask, { - filePath: `tmp/environments/${e2eProjectName}/verdaccio-registry.json`, + filePath: expect.toMatchPath( + `tmp/environments/${e2eProjectName}/verdaccio-registry.json` + ), verbose: true, }, context @@ -122,7 +124,9 @@ describe('runBootstrapExecutor', () => { expect(runExecutorSpy).toHaveBeenCalledWith( stopVerdaccioTask, { - filePath: `${environmentRoot}/verdaccio-registry.json`, + filePath: expect.toMatchPath( + `${environmentRoot}/verdaccio-registry.json` + ), }, context ); diff --git a/projects/nx-verdaccio/src/executors/env-setup/executor.ts b/projects/nx-verdaccio/src/executors/env-setup/executor.ts index 9b57f9cf..10214247 100644 --- a/projects/nx-verdaccio/src/executors/env-setup/executor.ts +++ b/projects/nx-verdaccio/src/executors/env-setup/executor.ts @@ -14,8 +14,8 @@ import { TARGET_ENVIRONMENT_INSTALL, } from '../../plugin/targets/environment.targets'; import { runSingleExecutor } from '../../internal/run-executor'; -import { rm } from 'node:fs/promises'; import { getEnvironmentRoot } from '../../internal/environment-root'; +import {cleanupEnv} from "../internal/cleanup-env"; export type ExecutorOutput = { success: boolean; @@ -92,19 +92,8 @@ export default async function runSetupEnvironmentExecutor( configuration, environmentRoot, }); - // delete storage, npmrc - await rm(join(environmentRoot, 'storage'), { - recursive: true, - force: true, - retryDelay: 100, - maxRetries: 2, - }); - await rm(join(environmentRoot, '.npmrc'), { - recursive: true, - force: true, - retryDelay: 100, - maxRetries: 2, - }); + // delete storage, .npmrc + await cleanupEnv(environmentRoot) } else { const { url } = await readFile( join(environmentRoot, VERDACCIO_REGISTRY_JSON), diff --git a/projects/nx-verdaccio/src/executors/env-setup/executor.unit-test.ts b/projects/nx-verdaccio/src/executors/env-setup/executor.unit-test.ts index 924310e8..1513f35c 100644 --- a/projects/nx-verdaccio/src/executors/env-setup/executor.unit-test.ts +++ b/projects/nx-verdaccio/src/executors/env-setup/executor.unit-test.ts @@ -115,7 +115,9 @@ describe('runSetupEnvironmentExecutor', () => { target: TARGET_ENVIRONMENT_VERDACCIO_STOP, }, { - filePath: 'tmp/environments/my-lib-e2e/verdaccio-registry.json', + filePath: expect.toMatchPath( + 'tmp/environments/my-lib-e2e/verdaccio-registry.json' + ), verbose: undefined, }, context diff --git a/projects/nx-verdaccio/src/executors/internal/cleanup-env.ts b/projects/nx-verdaccio/src/executors/internal/cleanup-env.ts new file mode 100644 index 00000000..18170769 --- /dev/null +++ b/projects/nx-verdaccio/src/executors/internal/cleanup-env.ts @@ -0,0 +1,18 @@ +import {rm} from "node:fs/promises"; +import {join} from "node:path"; + +export async function cleanupEnv(environmentRoot: string) { + // delete storage, .npmrc + await rm(join(environmentRoot, 'storage'), { + recursive: true, + force: true, + retryDelay: 100, + maxRetries: 2, + }); + await rm(join(environmentRoot, '.npmrc'), { + recursive: true, + force: true, + retryDelay: 100, + maxRetries: 2, + }); +} diff --git a/projects/nx-verdaccio/src/executors/kill-process/executor.unit-test.ts b/projects/nx-verdaccio/src/executors/kill-process/executor.unit-test.ts index 68f04beb..cbd13e46 100644 --- a/projects/nx-verdaccio/src/executors/kill-process/executor.unit-test.ts +++ b/projects/nx-verdaccio/src/executors/kill-process/executor.unit-test.ts @@ -75,7 +75,7 @@ describe('runKillProcessExecutor', () => { await expect( runKillProcessExecutor( { - filePath: 'tmp/environments/my-lib', + filePath: expect.toMatchPath('tmp/environments/my-lib'), }, { root: 'tmp/environments/test', diff --git a/projects/nx-verdaccio/src/executors/pkg-install/executor.unit-test.ts b/projects/nx-verdaccio/src/executors/pkg-install/executor.unit-test.ts index dbc047b5..225dec45 100644 --- a/projects/nx-verdaccio/src/executors/pkg-install/executor.unit-test.ts +++ b/projects/nx-verdaccio/src/executors/pkg-install/executor.unit-test.ts @@ -68,10 +68,7 @@ describe('runNpmInstallExecutor', () => { expect(logger.info).toHaveBeenCalledTimes(1); expect(logger.info).toHaveBeenCalledWith( - `Installing my-lib@1.0.0 in ${join( - DEFAULT_ENVIRONMENTS_OUTPUT_DIR, - 'my-lib-e2e' - )}` + expect.stringContaining(`Installing my-lib@1.0.0 in`) ); expect(executeProcessSpy).toHaveBeenCalledTimes(1); @@ -89,7 +86,7 @@ describe('runNpmInstallExecutor', () => { '--no-shrinkwrap', '--save', ], - cwd: 'tmp/environments/my-lib-e2e', + cwd: expect.toMatchPath('tmp/environments/my-lib-e2e'), verbose: true, }) ); diff --git a/projects/nx-verdaccio/src/executors/pkg-publish/executor.unit-test.ts b/projects/nx-verdaccio/src/executors/pkg-publish/executor.unit-test.ts index 204c9709..7542e93c 100644 --- a/projects/nx-verdaccio/src/executors/pkg-publish/executor.unit-test.ts +++ b/projects/nx-verdaccio/src/executors/pkg-publish/executor.unit-test.ts @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, vi, it } from 'vitest'; import runNpmPublishExecutor from './executor'; -import { MEMFS_VOLUME } from '@push-based/test-utils'; +import { MEMFS_VOLUME, osAgnosticPath } from '@push-based/test-utils'; import * as execProcessModule from '../../internal/execute-process'; import * as pkgVersionModule from './pkg-version'; import { logger } from '@nx/devkit'; @@ -67,18 +67,22 @@ describe('runNpmPublishExecutor', () => { const envRoot = 'tmp/environments/my-lib-e2e'; expect(logger.info).toHaveBeenCalledWith( - `Publishing package from ${pkgDist} to ${envRoot} with userconfig ${userconfigRelative}` + expect.stringContaining( + `Publishing package from ${pkgDist} to ${envRoot} with userconfig` + ) ); expect(pkgVersionModuleSpy).toHaveBeenCalledTimes(1); - expect(pkgVersionModuleSpy).toHaveBeenCalledWith('dist/projects/my-lib'); + expect(pkgVersionModuleSpy).toHaveBeenCalledWith( + expect.toMatchPath('dist/projects/my-lib') + ); expect(executeProcessSpy).toHaveBeenCalledTimes(1); expect(executeProcessSpy).toHaveBeenCalledWith( expect.objectContaining({ command: 'npm', - args: ['publish', `--userconfig="${userconfigRelative}"`], - cwd: 'dist/projects/my-lib', + args: expect.arrayContaining(['publish']), // expect.toMatchPath('dist/projects/my-lib'), + cwd: expect.toMatchPath('dist/projects/my-lib'), }) ); }); diff --git a/projects/nx-verdaccio/vite.config.ts b/projects/nx-verdaccio/vite.config.ts index a1f6d7be..0ca75adf 100644 --- a/projects/nx-verdaccio/vite.config.ts +++ b/projects/nx-verdaccio/vite.config.ts @@ -22,6 +22,7 @@ export default defineConfig({ ], reporters: ['default'], setupFiles: [ + '../../testing/test-setup/src/lib/extend/path-matcher.ts', '../../testing/test-setup/src/lib/fs.mock.ts', '../../testing/test-setup/src/lib/reset.mock.ts', ], diff --git a/testing/test-nx-utils/src/lib/setup.spec.ts b/testing/test-nx-utils/src/lib/setup.spec.ts index 5a6b6487..0e94cef7 100644 --- a/testing/test-nx-utils/src/lib/setup.spec.ts +++ b/testing/test-nx-utils/src/lib/setup.spec.ts @@ -1,14 +1,17 @@ import { describe, it, expect } from 'vitest'; import { getTestEnvironmentRoot } from './test-folder.setup'; +import { join } from 'node:path'; describe('getTestEnvironmentRoot', () => { it('should accept project name', () => { - expect(getTestEnvironmentRoot('cli-e2e')).toMatch(/cli-e2e$/); + expect(getTestEnvironmentRoot('cli-e2e')).toMatchPath( + join('tmp', 'environments', 'cli-e2e') + ); }); it('should accept environments root', () => { - expect(getTestEnvironmentRoot('cli-e2e')).toMatch( - /^tmp\/environments\/cli-e2e/ + expect(getTestEnvironmentRoot('cli-e2e')).toMatchPath( + join('tmp', 'environments', 'cli-e2e') ); }); }); diff --git a/testing/test-nx-utils/src/lib/utils/nx.ts b/testing/test-nx-utils/src/lib/utils/nx.ts index 8995e04e..87ccd5fd 100644 --- a/testing/test-nx-utils/src/lib/utils/nx.ts +++ b/testing/test-nx-utils/src/lib/utils/nx.ts @@ -102,7 +102,7 @@ export async function nxShowProjectJson( ) { const { prefix, userconfig } = options ?? {}; const { code, stderr, stdout } = await executeProcess({ - command: 'NX_DAEMON=false NX_CACHE_PROJECT_GRAPH=false npx', + command: 'npx', args: objectToCliArgs({ _: ['nx', 'show', 'project', project, '--skipNxCache'], verbose: false, // debug errors @@ -111,6 +111,11 @@ export async function nxShowProjectJson( userconfig, }), cwd, + env: { + ...process.env, + NX_DAEMON: 'false', + NX_CACHE_PROJECT_GRAPH: 'false', + }, }); try { diff --git a/testing/test-nx-utils/vite.config.ts b/testing/test-nx-utils/vite.config.ts index 541e8f18..ff2ad539 100644 --- a/testing/test-nx-utils/vite.config.ts +++ b/testing/test-nx-utils/vite.config.ts @@ -23,5 +23,6 @@ export default defineConfig({ reportsDirectory: '../../coverage/projects/test-utils', provider: 'v8', }, + setupFiles: ['../testing/test-setup/src/lib/extend/path-matcher.ts'], }, }); diff --git a/testing/test-setup/src/lib/extend/path-matcher.ts b/testing/test-setup/src/lib/extend/path-matcher.ts new file mode 100644 index 00000000..1be32514 --- /dev/null +++ b/testing/test-setup/src/lib/extend/path-matcher.ts @@ -0,0 +1,39 @@ +import { expect } from 'vitest'; +import path from 'path'; + +expect.extend({ + toMatchPath(received, expected) { + const normalizedReceived = path.normalize(received); + const normalizedExpected = path.normalize(expected); + + const pass = normalizedReceived.includes(normalizedExpected); + if (pass) { + return { + message: () => `expected ${received} not to match path ${expected}`, + pass: true, + }; + } else { + return { + message: () => `expected ${received} to match path ${expected}`, + pass: false, + }; + } + }, + pathToMatch(received, expected) { + const normalizedReceived = path.normalize(received); + const normalizedExpected = path.normalize(expected); + + const pass = normalizedReceived.includes(normalizedExpected); + if (pass) { + return { + message: () => `expected ${received} not to contain path ${expected}`, + pass: true, + }; + } else { + return { + message: () => `expected ${received} to contain path ${expected}`, + pass: false, + }; + } + }, +});