From e45b7cb4c1ba29ee8fe72ddfb3631fd55ebadc2c Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 18:08:40 +0100 Subject: [PATCH 1/8] refactor cleanup --- examples/e2e/cli-static-e2e/project.json | 5 ++++ .../test/cli-command-sort.spec.ts | 26 +++++++------------ .../executors/env-teardown/teardown-env.ts | 4 +-- .../src/internal/environment-root.ts | 4 +-- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/examples/e2e/cli-static-e2e/project.json b/examples/e2e/cli-static-e2e/project.json index 2ce212a..908aeed 100644 --- a/examples/e2e/cli-static-e2e/project.json +++ b/examples/e2e/cli-static-e2e/project.json @@ -7,6 +7,11 @@ "implicitDependencies": ["cli"], "targets": { "lint": {}, + "nxv-env-setup": { + "options": { + "environmentRoot": "static-environments/user-lists" + } + }, "e2e-static": { "executor": "@nx/vite:test", "inputs": ["default", "^production"], diff --git a/examples/e2e/cli-static-e2e/test/cli-command-sort.spec.ts b/examples/e2e/cli-static-e2e/test/cli-command-sort.spec.ts index 5996edd..bd587e4 100644 --- a/examples/e2e/cli-static-e2e/test/cli-command-sort.spec.ts +++ b/examples/e2e/cli-static-e2e/test/cli-command-sort.spec.ts @@ -1,28 +1,22 @@ -import { dirname, join, basename } from 'node:path'; +import { basename, dirname, join } from 'node:path'; import { afterEach, describe, expect, it } from 'vitest'; -import { mkdir, readFile, rm, writeFile } from 'node:fs/promises'; +import { readFile, rm } from 'node:fs/promises'; import { executeProcess, objectToCliArgs } from '@push-based/test-utils'; -import { - getTestFixturesDist, - getTestEnvironmentRoot, -} from '@push-based/test-utils'; +import type { SimpleGit } from 'simple-git'; +import { simpleGit } from 'simple-git'; describe('CLI command - sort', () => { - const fixturesDist = getTestFixturesDist('cli-command-sort', { - root: getTestEnvironmentRoot(process.env['NX_TASK_TARGET_PROJECT']), - }); + const envRoot = join('static-environments', 'user-lists'); + const baseDir = join(envRoot, 'src', 'lib'); + export const gitClient: SimpleGit = simpleGit(process.cwd()); afterEach(async () => { - await rm(fixturesDist, { recursive: true, force: true }); + await gitClient.checkout([envRoot]); + await gitClient.clean('f', [envRoot]); }); it('should execute CLI command sort when param file is given', async () => { - const testPath = join(fixturesDist, 'execute-sort-command', 'users.json'); - await mkdir(dirname(testPath), { recursive: true }); - await writeFile( - testPath, - JSON.stringify([{ name: 'Michael' }, { name: 'Alice' }]) - ); + const testPath = join(baseDir, 'unsorted-users.json'); const { code } = await executeProcess({ command: 'npx', diff --git a/projects/nx-verdaccio/src/executors/env-teardown/teardown-env.ts b/projects/nx-verdaccio/src/executors/env-teardown/teardown-env.ts index 2dfe9b0..87f3892 100644 --- a/projects/nx-verdaccio/src/executors/env-teardown/teardown-env.ts +++ b/projects/nx-verdaccio/src/executors/env-teardown/teardown-env.ts @@ -33,8 +33,8 @@ export async function teardownEnvironment( const environmentRootInRepo = await isFolderInGit(environmentRoot); if (environmentRootInRepo) { - // await git.checkout([environmentRoot]); - // await git.clean('f', [environmentRoot]); + await gitClient.checkout([environmentRoot]); + await gitClient.clean('f', [environmentRoot]); logger.info(`Cleaned git history in ${environmentRoot}`); } else { try { diff --git a/projects/nx-verdaccio/src/internal/environment-root.ts b/projects/nx-verdaccio/src/internal/environment-root.ts index aedc862..7b6bd6c 100644 --- a/projects/nx-verdaccio/src/internal/environment-root.ts +++ b/projects/nx-verdaccio/src/internal/environment-root.ts @@ -21,7 +21,7 @@ export function getEnvironmentRoot( context: ExecutorContext, options: Partial ) { - const { environmentRoot: optEnvironmentRoot } = options; + const { environmentRoot } = options; const environmentsDir = getEnvironmentDir(context); - return optEnvironmentRoot ?? join(environmentsDir, context.projectName); + return environmentRoot ?? join(environmentsDir, context.projectName); } From b74b86eaee2bf9ef4770b986eee3d2438865ef4e Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 00:56:14 +0100 Subject: [PATCH 2/8] fix static e2e --- README.md | 7 +++- examples/e2e/cli-static-e2e/project.json | 15 ++++---- .../test/cli-command-sort.spec.ts | 35 ++++++++++++++++--- nx.json | 1 + .../nx-verdaccio/docs/static-environments.md | 25 +++++++++++++ .../executors/env-teardown/teardown-env.ts | 15 ++++++++ .../src/executors/pkg-install/executor.ts | 7 ++-- static-environments/user-lists/package.json | 8 ++++- 8 files changed, 97 insertions(+), 16 deletions(-) create mode 100644 projects/nx-verdaccio/docs/static-environments.md diff --git a/README.md b/README.md index f1ff6f7..c619cb3 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ [![commit activity](https://img.shields.io/github/commit-activity/m/push-based/nx-verdaccio)](https://github.com/push-based/nx-verdaccio/pulse/monthly) [![CI](https://github.com/push-based/nx-verdaccio/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/push-based/nx-verdaccio/actions/workflows/ci.yml?query=branch%3Amain) - Welcome to the **Verdaccio Testing Environments Nx Plugin** — your one-stop solution for running **blazingly fast**, **isolated**, and **scalable** end-to-end (e2e) tests with zero configuration. Yeah, you heard that right: **ZERO configuration**. With this plugin, say goodbye to the old days of waiting around for your tests and hello to _next-level speed_. Plug it in, and you're good to go. @@ -240,6 +239,12 @@ This is a first draft of how the benchmarks will look. ATM the data set it not b | Graph Nodes | 1 | 13 | n/a | n/a | | Parallelism | ❌ | ✅ | n/a | n/a | +## Next Steps + +- [configure cacheable environments](./projects/nx-verdaccio/docs/static-environments.md) +- [static environments](.) +- [debugging](.) + ## Stay Connected! 🔗 - [Check out our services](https://push-based.io) diff --git a/examples/e2e/cli-static-e2e/project.json b/examples/e2e/cli-static-e2e/project.json index 908aeed..7df8504 100644 --- a/examples/e2e/cli-static-e2e/project.json +++ b/examples/e2e/cli-static-e2e/project.json @@ -7,18 +7,19 @@ "implicitDependencies": ["cli"], "targets": { "lint": {}, - "nxv-env-setup": { + "nxv-e2e": { "options": { - "environmentRoot": "static-environments/user-lists" + "envRoot": "static-environments/user-lists" } }, - "e2e-static": { - "executor": "@nx/vite:test", - "inputs": ["default", "^production"], - "outputs": ["{options.reportsDirectory}"], + "nxv-env-setup": { "options": { - "reportsDirectory": "../../../coverage/projects/cli-static-e2e" + "envRoot": "static-environments/user-lists" } + }, + "e2e": { + "executor": "@nx/vite:test", + "inputs": ["default", "^production"] } } } diff --git a/examples/e2e/cli-static-e2e/test/cli-command-sort.spec.ts b/examples/e2e/cli-static-e2e/test/cli-command-sort.spec.ts index bd587e4..7c59148 100644 --- a/examples/e2e/cli-static-e2e/test/cli-command-sort.spec.ts +++ b/examples/e2e/cli-static-e2e/test/cli-command-sort.spec.ts @@ -8,11 +8,11 @@ import { simpleGit } from 'simple-git'; describe('CLI command - sort', () => { const envRoot = join('static-environments', 'user-lists'); const baseDir = join(envRoot, 'src', 'lib'); - export const gitClient: SimpleGit = simpleGit(process.cwd()); + const gitClient: SimpleGit = simpleGit(process.cwd()); afterEach(async () => { - await gitClient.checkout([envRoot]); - await gitClient.clean('f', [envRoot]); + await gitClient.checkout([baseDir]); + await gitClient.clean('f', [baseDir]); }); it('should execute CLI command sort when param file is given', async () => { @@ -31,7 +31,34 @@ describe('CLI command - sort', () => { expect(code).toBe(0); const content = (await readFile(testPath)).toString(); - expect(JSON.parse(content)).toEqual([ + expect(JSON.parse(content)).toStrictEqual([ + { name: 'Alice' }, + { name: 'Michael' }, + ]); + }); + + it('should execute CLI command sort on sorted file', async () => { + const testPath = join(baseDir, 'sorted-users.json'); + + const contentBefore = (await readFile(testPath)).toString(); + expect(JSON.parse(contentBefore)).toStrictEqual([ + { name: 'Alice' }, + { name: 'Michael' }, + ]); + + const { code } = await executeProcess({ + command: 'npx', + args: objectToCliArgs({ + _: ['cli', 'sort'], + filePath: basename(testPath), + }), + cwd: baseDir, + }); + + expect(code).toBe(0); + + const content = (await readFile(testPath)).toString(); + expect(JSON.parse(content)).toStrictEqual([ { name: 'Alice' }, { name: 'Michael' }, ]); diff --git a/nx.json b/nx.json index 8f9f843..c6b312a 100644 --- a/nx.json +++ b/nx.json @@ -29,6 +29,7 @@ "cache": true, "inputs": ["default", "^production"] }, + "nxv-e2e": {}, "nxv-env-setup": { "cache": true, "inputs": [ diff --git a/projects/nx-verdaccio/docs/static-environments.md b/projects/nx-verdaccio/docs/static-environments.md new file mode 100644 index 0000000..ee07568 --- /dev/null +++ b/projects/nx-verdaccio/docs/static-environments.md @@ -0,0 +1,25 @@ +# Configure Static environments + +The plugin can be configured to use static environments. +This is useful when you want to have existing test projects managed in your git history. + +To use static environments, you need to configure the `environmentRoot` option in the related targets your `project.json` file. + +```jsonc +// project.json +{ + "nxv-e2e": { + "options": { + "envRoot": "examples/my-env" // needed for clenaup + } + }, + "nxv-env-setup": { + "options": { + "envRoot": "examples/my-env" // needed for install + } + } +} +``` + +The `environmentRoot` will be used as root folder for package installation. +After the test the teardown function will delete the created folders and revert changes in the git history. diff --git a/projects/nx-verdaccio/src/executors/env-teardown/teardown-env.ts b/projects/nx-verdaccio/src/executors/env-teardown/teardown-env.ts index 87f3892..6a19aac 100644 --- a/projects/nx-verdaccio/src/executors/env-teardown/teardown-env.ts +++ b/projects/nx-verdaccio/src/executors/env-teardown/teardown-env.ts @@ -36,6 +36,21 @@ export async function teardownEnvironment( await gitClient.checkout([environmentRoot]); await gitClient.clean('f', [environmentRoot]); logger.info(`Cleaned git history in ${environmentRoot}`); + + const nodeModules = join(environmentRoot, 'node_modules'); + try { + await rm(nodeModules, { + recursive: true, + force: true, + retryDelay: 100, + maxRetries: 2, + }); + logger.info(`deleted folder ${nodeModules}.`); + } catch (error) { + throw new Error( + `Error cleaning history of folder ${nodeModules}. ${error.message}` + ); + } } else { try { await rm(environmentRoot, { diff --git a/projects/nx-verdaccio/src/executors/pkg-install/executor.ts b/projects/nx-verdaccio/src/executors/pkg-install/executor.ts index b7e7176..9aa3d45 100644 --- a/projects/nx-verdaccio/src/executors/pkg-install/executor.ts +++ b/projects/nx-verdaccio/src/executors/pkg-install/executor.ts @@ -36,9 +36,10 @@ export default async function runNpmInstallExecutor( 'install', `${packageNameAndVersion}`, '--include=prod', - '--include=dev', - '--include=optional', - '--include=peer', // install all the deps of the package + '--include=peer', + // @TODO: implement options for dev and optional dependencies + //'--include=dev', + //'--include=optional', ], fund: false, // avoid polluted terminal shrinkwrap: false, // avoid package-lock creation or update diff --git a/static-environments/user-lists/package.json b/static-environments/user-lists/package.json index df42d59..962db80 100644 --- a/static-environments/user-lists/package.json +++ b/static-environments/user-lists/package.json @@ -7,5 +7,11 @@ "keywords": [], "author": "", "license": "ISC", - "description": "" + "description": "", + "dependencies": { + "@push-based/cli": "^0.0.1", + "@push-based/core": "^0.0.1", + "@push-based/models": "^0.0.1", + "@push-based/utils": "^0.0.1" + } } From 39ee01cd3155f1fecc63c17e7909d3226334628f Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 02:24:46 +0100 Subject: [PATCH 3/8] add plugin example to cli --- examples/e2e/plugin-1-e2e/.eslintrc.json | 30 +++++++++++ examples/e2e/plugin-1-e2e/project.json | 19 +++++++ .../test/cli-plugin-1-sort.spec.ts | 50 +++++++++++++++++++ examples/e2e/plugin-1-e2e/tsconfig.json | 19 +++++++ examples/e2e/plugin-1-e2e/tsconfig.spec.json | 26 ++++++++++ examples/e2e/plugin-1-e2e/vite.config.ts | 27 ++++++++++ examples/projects/cli/src/lib/cli.ts | 20 ++++++-- examples/projects/plugin-1/.eslintrc.json | 30 +++++++++++ examples/projects/plugin-1/README.md | 11 ++++ examples/projects/plugin-1/package.json | 7 +++ examples/projects/plugin-1/project.json | 37 ++++++++++++++ examples/projects/plugin-1/src/index.ts | 4 ++ .../projects/plugin-1/src/lib/plugin.spec.ts | 21 ++++++++ examples/projects/plugin-1/src/lib/plugin.ts | 13 +++++ examples/projects/plugin-1/tsconfig.json | 22 ++++++++ examples/projects/plugin-1/tsconfig.lib.json | 10 ++++ examples/projects/plugin-1/tsconfig.spec.json | 26 ++++++++++ examples/projects/plugin-1/vite.config.ts | 30 +++++++++++ tsconfig.base.json | 1 + 19 files changed, 400 insertions(+), 3 deletions(-) create mode 100644 examples/e2e/plugin-1-e2e/.eslintrc.json create mode 100644 examples/e2e/plugin-1-e2e/project.json create mode 100644 examples/e2e/plugin-1-e2e/test/cli-plugin-1-sort.spec.ts create mode 100644 examples/e2e/plugin-1-e2e/tsconfig.json create mode 100644 examples/e2e/plugin-1-e2e/tsconfig.spec.json create mode 100644 examples/e2e/plugin-1-e2e/vite.config.ts create mode 100644 examples/projects/plugin-1/.eslintrc.json create mode 100644 examples/projects/plugin-1/README.md create mode 100644 examples/projects/plugin-1/package.json create mode 100644 examples/projects/plugin-1/project.json create mode 100644 examples/projects/plugin-1/src/index.ts create mode 100644 examples/projects/plugin-1/src/lib/plugin.spec.ts create mode 100644 examples/projects/plugin-1/src/lib/plugin.ts create mode 100644 examples/projects/plugin-1/tsconfig.json create mode 100644 examples/projects/plugin-1/tsconfig.lib.json create mode 100644 examples/projects/plugin-1/tsconfig.spec.json create mode 100644 examples/projects/plugin-1/vite.config.ts diff --git a/examples/e2e/plugin-1-e2e/.eslintrc.json b/examples/e2e/plugin-1-e2e/.eslintrc.json new file mode 100644 index 0000000..75d7c5f --- /dev/null +++ b/examples/e2e/plugin-1-e2e/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "extends": ["../../../.eslintrc.base.json", "../../../.eslintrc.base.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/vite.config.{js,ts,mjs,mts}"] + } + ] + } + } + ] +} diff --git a/examples/e2e/plugin-1-e2e/project.json b/examples/e2e/plugin-1-e2e/project.json new file mode 100644 index 0000000..2f43aaf --- /dev/null +++ b/examples/e2e/plugin-1-e2e/project.json @@ -0,0 +1,19 @@ +{ + "name": "plugin-1-e2e", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "projects/cli-e2e/test", + "projectType": "application", + "tags": ["type:e2e", "type:e2e-vi", "type:example"], + "implicitDependencies": ["cli", "plugin-1"], + "targets": { + "lint": {}, + "e2e": { + "executor": "@nx/vite:test", + "inputs": ["default", "^production"], + "outputs": ["{options.reportsDirectory}"], + "options": { + "reportsDirectory": "../../../coverage/projects/cli-e2e" + } + } + } +} diff --git a/examples/e2e/plugin-1-e2e/test/cli-plugin-1-sort.spec.ts b/examples/e2e/plugin-1-e2e/test/cli-plugin-1-sort.spec.ts new file mode 100644 index 0000000..723fc1b --- /dev/null +++ b/examples/e2e/plugin-1-e2e/test/cli-plugin-1-sort.spec.ts @@ -0,0 +1,50 @@ +import { dirname, join, basename } from 'node:path'; +import { afterEach, describe, expect, it } from 'vitest'; +import { mkdir, readFile, rm, writeFile } from 'node:fs/promises'; +import { executeProcess, objectToCliArgs } from '@push-based/test-utils'; +import { + getTestFixturesDist, + getTestEnvironmentRoot, +} from '@push-based/test-utils'; + +describe('CLI command - sort -p plugin-1', () => { + const fixturesDist = getTestFixturesDist('cli-command-sort', { + root: getTestEnvironmentRoot(process.env['NX_TASK_TARGET_PROJECT']), + }); + + afterEach(async () => { + await rm(fixturesDist, { recursive: true, force: true }); + }); + + it('should execute CLI command sort when param file is given', async () => { + const testPath = join( + fixturesDist, + 'execute-sort-command-with-plugin', + 'users.json' + ); + await mkdir(dirname(testPath), { recursive: true }); + await writeFile( + testPath, + JSON.stringify([{ name: 'B' }, { name: 'A' }, { name: 'C' }]) + ); + + const { code } = await executeProcess({ + command: 'npx', + args: objectToCliArgs({ + _: ['cli', 'sort', '-p @push-based/plugin-1'], + filePath: basename(testPath), + }), + cwd: dirname(testPath), + verbose: true, + }); + + expect(code).toBe(0); + + const content = (await readFile(testPath)).toString(); + expect(JSON.parse(content)).toStrictEqual([ + { name: 'C' }, + { name: 'B' }, + { name: 'A' }, + ]); + }); +}); diff --git a/examples/e2e/plugin-1-e2e/tsconfig.json b/examples/e2e/plugin-1-e2e/tsconfig.json new file mode 100644 index 0000000..2ea3517 --- /dev/null +++ b/examples/e2e/plugin-1-e2e/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "module": "esnext", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/examples/e2e/plugin-1-e2e/tsconfig.spec.json b/examples/e2e/plugin-1-e2e/tsconfig.spec.json new file mode 100644 index 0000000..f70d587 --- /dev/null +++ b/examples/e2e/plugin-1-e2e/tsconfig.spec.json @@ -0,0 +1,26 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "vitest.config.ts", + "test/**/*.test.ts", + "test/**/*.spec.ts", + "test/**/*.test.tsx", + "test/**/*.spec.tsx", + "test/**/*.test.js", + "test/**/*.spec.js", + "test/**/*.test.jsx", + "test/**/*.spec.jsx", + "test/**/*.d.ts" + ] +} diff --git a/examples/e2e/plugin-1-e2e/vite.config.ts b/examples/e2e/plugin-1-e2e/vite.config.ts new file mode 100644 index 0000000..b00714e --- /dev/null +++ b/examples/e2e/plugin-1-e2e/vite.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vite'; + +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; + +export default defineConfig({ + root: __dirname, + cacheDir: '../../../node_modules/.vite/projects/cli-e2e', + + plugins: [nxViteTsPaths()], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + + test: { + globals: true, + cache: { dir: '../../../node_modules/.vitest' }, + environment: 'node', + include: ['test/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + reporters: ['default'], + coverage: { + reportsDirectory: '../../../coverage/projects/cli-e2e', + provider: 'v8', + }, + }, +}); diff --git a/examples/projects/cli/src/lib/cli.ts b/examples/projects/cli/src/lib/cli.ts index 54cd9bc..40db093 100644 --- a/examples/projects/cli/src/lib/cli.ts +++ b/examples/projects/cli/src/lib/cli.ts @@ -3,6 +3,7 @@ import { sortUserFile } from '@push-based/core'; export type CliArgs = { filePath: string; + plugin?: string; }; const NOOP_BUILDER = (_: Argv) => void 0; @@ -17,13 +18,26 @@ export function cli(args: string[]) { description: 'Path to the user file', demandOption: true, }, + plugin: { + type: 'string', + description: 'Path to the user file', + alias: 'p', + }, } satisfies Record) .command('*', 'Sort users', NOOP_BUILDER, sortCommandHandle) .command('sort', 'Sort users', NOOP_BUILDER, sortCommandHandle); } export async function sortCommandHandle(args: CliArgs) { - const { filePath } = args; - await sortUserFile(filePath); - console.log(`Sorted users in ${filePath}`); + const { filePath, plugin } = args; + try { + const sortFn = plugin + ? await import(plugin).then(({ default: d }) => d) + : sortUserFile; + await sortFn(filePath); + console.log(`Sorted users in ${filePath}`); + } catch (error) { + console.error(`Failed to load plugin: ${plugin}`); + throw error; + } } diff --git a/examples/projects/plugin-1/.eslintrc.json b/examples/projects/plugin-1/.eslintrc.json new file mode 100644 index 0000000..75d7c5f --- /dev/null +++ b/examples/projects/plugin-1/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "extends": ["../../../.eslintrc.base.json", "../../../.eslintrc.base.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/vite.config.{js,ts,mjs,mts}"] + } + ] + } + } + ] +} diff --git a/examples/projects/plugin-1/README.md b/examples/projects/plugin-1/README.md new file mode 100644 index 0000000..c91516a --- /dev/null +++ b/examples/projects/plugin-1/README.md @@ -0,0 +1,11 @@ +# plugin-1 + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build plugin-1` to build the library. + +## Running unit tests + +Run `nx test plugin-1` to execute the unit tests via [Vitest](https://vitest.dev/). diff --git a/examples/projects/plugin-1/package.json b/examples/projects/plugin-1/package.json new file mode 100644 index 0000000..70c8f9a --- /dev/null +++ b/examples/projects/plugin-1/package.json @@ -0,0 +1,7 @@ +{ + "name": "@push-based/plugin-1", + "version": "0.0.1", + "dependencies": { + "@push-based/models": "0.0.1" + } +} diff --git a/examples/projects/plugin-1/project.json b/examples/projects/plugin-1/project.json new file mode 100644 index 0000000..aa110fa --- /dev/null +++ b/examples/projects/plugin-1/project.json @@ -0,0 +1,37 @@ +{ + "name": "plugin-1", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "examples/projects/plugin-1/src", + "projectType": "library", + "release": { + "version": { + "generatorOptions": { + "packageRoot": "dist/{projectRoot}", + "currentVersionResolver": "git-tag" + } + } + }, + "tags": ["type:app", "type:unit-test-vi", "publishable", "type:example"], + "targets": { + "lint": {}, + "build": { + "executor": "@nx/esbuild:esbuild", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/examples/projects/plugin-1", + "main": "examples/projects/plugin-1/src/index.ts", + "tsConfig": "examples/projects/plugin-1/tsconfig.lib.json", + "assets": ["examples/projects/plugin-1/*.md"], + "generatePackageJson": true, + "format": ["esm"] + } + }, + "unit-test": { + "executor": "@nx/vite:test", + "outputs": ["{options.reportsDirectory}"], + "options": { + "reportsDirectory": "../../../coverage/examples/projects/cli" + } + } + } +} diff --git a/examples/projects/plugin-1/src/index.ts b/examples/projects/plugin-1/src/index.ts new file mode 100644 index 0000000..7037c96 --- /dev/null +++ b/examples/projects/plugin-1/src/index.ts @@ -0,0 +1,4 @@ +export { sortDesc } from './lib/plugin'; +import { sortDesc } from './lib/plugin'; + +export default sortDesc; diff --git a/examples/projects/plugin-1/src/lib/plugin.spec.ts b/examples/projects/plugin-1/src/lib/plugin.spec.ts new file mode 100644 index 0000000..2813bbb --- /dev/null +++ b/examples/projects/plugin-1/src/lib/plugin.spec.ts @@ -0,0 +1,21 @@ +import { join } from 'node:path'; +import plugin1 from './plugin'; +import { vol } from 'memfs'; +import { MEMFS_VOLUME } from '@push-based/test-utils'; + +describe('plugin', () => { + it('should sort file of users', async () => { + const testPath = join('sort', 'users.json'); + vol.fromJSON( + { + [testPath]: JSON.stringify([{ name: 'b' }, { name: 'a' }]), + }, + MEMFS_VOLUME + ); + + await expect(plugin1(testPath)).resolves.not.toThrow(); + + const content = JSON.parse(await vol.promises.readFile(testPath)); + expect(content).toStrictEqual([{ name: 'a' }, { name: 'b' }]); + }); +}); diff --git a/examples/projects/plugin-1/src/lib/plugin.ts b/examples/projects/plugin-1/src/lib/plugin.ts new file mode 100644 index 0000000..c36f5a2 --- /dev/null +++ b/examples/projects/plugin-1/src/lib/plugin.ts @@ -0,0 +1,13 @@ +import { readFile, writeFile } from 'node:fs/promises'; +import { parseUser, User } from '@push-based/models'; + +export async function sortDesc(filePath: string): Promise { + const userJson: string = (await readFile(filePath)).toString(); + const parsedUsers: User[] = JSON.parse(userJson).map(parseUser); + const sortedUsers: User[] = parsedUsers.sort((a, b) => + b.name.localeCompare(a.name) + ); + await writeFile(filePath, JSON.stringify(sortedUsers, null, 2)); +} + +export default sortDesc; diff --git a/examples/projects/plugin-1/tsconfig.json b/examples/projects/plugin-1/tsconfig.json new file mode 100644 index 0000000..c50bbbc --- /dev/null +++ b/examples/projects/plugin-1/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "module": "esnext", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/examples/projects/plugin-1/tsconfig.lib.json b/examples/projects/plugin-1/tsconfig.lib.json new file mode 100644 index 0000000..1f66ef5 --- /dev/null +++ b/examples/projects/plugin-1/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/examples/projects/plugin-1/tsconfig.spec.json b/examples/projects/plugin-1/tsconfig.spec.json new file mode 100644 index 0000000..05a0e18 --- /dev/null +++ b/examples/projects/plugin-1/tsconfig.spec.json @@ -0,0 +1,26 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "vitest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/examples/projects/plugin-1/vite.config.ts b/examples/projects/plugin-1/vite.config.ts new file mode 100644 index 0000000..ede8ab3 --- /dev/null +++ b/examples/projects/plugin-1/vite.config.ts @@ -0,0 +1,30 @@ +import { defineConfig } from 'vite'; +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; + +export default defineConfig({ + root: __dirname, + cacheDir: '../../../node_modules/.vite/projects/cli', + + plugins: [nxViteTsPaths()], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + + test: { + globals: true, + cache: { dir: '../../../node_modules/.vitest' }, + environment: 'node', + include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + reporters: ['default'], + coverage: { + reportsDirectory: '../../../coverage/projects/cli', + provider: 'v8', + }, + setupFiles: [ + '../../../testing/test-setup/src/lib/reset.mock.ts', + '../../../testing/test-setup/src/lib/fs.mock.ts', + ], + }, +}); diff --git a/tsconfig.base.json b/tsconfig.base.json index dd799ce..e6d36de 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -19,6 +19,7 @@ "@push-based/core": ["examples/projects/core/src/index.ts"], "@push-based/models": ["examples/projects/models/src/index.ts"], "@push-based/nx-verdaccio": ["projects/nx-verdaccio/src/index.ts"], + "@push-based/plugin-1": ["projects/plugin-1/src/index.ts"], "@push-based/test-nx-utils": ["testing/test-nx-utils/src/index.ts"], "@push-based/test-setup": ["testing/test-setup/src/index.ts"], "@push-based/test-utils": ["testing/test-utils/src/index.ts"], From fdc957953fc504931f481e3d8159db01d8461c0e Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 02:37:50 +0100 Subject: [PATCH 4/8] fix tests --- examples/projects/plugin-1/src/lib/plugin.spec.ts | 12 ++++++++++-- .../src/executors/pkg-install/executor.unit-test.ts | 5 +++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/examples/projects/plugin-1/src/lib/plugin.spec.ts b/examples/projects/plugin-1/src/lib/plugin.spec.ts index 2813bbb..2b2733b 100644 --- a/examples/projects/plugin-1/src/lib/plugin.spec.ts +++ b/examples/projects/plugin-1/src/lib/plugin.spec.ts @@ -8,7 +8,11 @@ describe('plugin', () => { const testPath = join('sort', 'users.json'); vol.fromJSON( { - [testPath]: JSON.stringify([{ name: 'b' }, { name: 'a' }]), + [testPath]: JSON.stringify([ + { name: 'B' }, + { name: 'A' }, + { name: 'C' }, + ]), }, MEMFS_VOLUME ); @@ -16,6 +20,10 @@ describe('plugin', () => { await expect(plugin1(testPath)).resolves.not.toThrow(); const content = JSON.parse(await vol.promises.readFile(testPath)); - expect(content).toStrictEqual([{ name: 'a' }, { name: 'b' }]); + expect(content).toStrictEqual([ + { name: 'C' }, + { name: 'B' }, + { name: 'A' }, + ]); }); }); 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 225dec4..9bc4abb 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 @@ -79,8 +79,9 @@ describe('runNpmInstallExecutor', () => { 'install', 'my-lib@1.0.0', '--include=prod', - '--include=dev', - '--include=optional', + // @TODO implement options + //'--include=dev', + //'--include=optional', '--include=peer', '--no-fund', '--no-shrinkwrap', From 5bc6ce71cbaba6b60e37b12b135d9735c2355d13 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 02:45:32 +0100 Subject: [PATCH 5/8] add cp folk gh action --- .github/workflows/code-pushup-fork.yml | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/code-pushup-fork.yml diff --git a/.github/workflows/code-pushup-fork.yml b/.github/workflows/code-pushup-fork.yml new file mode 100644 index 0000000..27d9c04 --- /dev/null +++ b/.github/workflows/code-pushup-fork.yml @@ -0,0 +1,38 @@ +name: Code PushUp (fork) + +# separated from code-pushup.yml for security reasons +# => requires permissions to create PR comment +# => for PRs from forks, needs to run on `pull_request_target`, not `pull_request` +# => `pull_request_target` is a security risk when secrets are being used +# => secrets needed for code-pushup upload +# => code-pushup for forks runs in separate workflow with no secrets access + +on: + pull_request_target: + branches: [main] + +env: + NX_NON_NATIVE_HASHER: true + +permissions: + pull-requests: write + +jobs: + code-pushup: + runs-on: ubuntu-latest + name: Code PushUp + if: github.event.pull_request.head.repo.fork + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: npm + - name: Install dependencies + run: npm ci + - name: Run Code PushUp action + uses: code-pushup/github-action@v0 + with: + bin: npx nx code-pushup -- From f187b57fc36dc1a479c7e8525004329105a0c977 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 02:53:05 +0100 Subject: [PATCH 6/8] wip CP --- .github/workflows/code-pushup.yml | 2 +- code-pushup.config.ts | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/code-pushup.yml b/.github/workflows/code-pushup.yml index f434c66..f169b36 100644 --- a/.github/workflows/code-pushup.yml +++ b/.github/workflows/code-pushup.yml @@ -36,4 +36,4 @@ jobs: - name: Run Code PushUp action uses: code-pushup/github-action@v0 with: - bin: npx nx run code-pushup + bin: npx nx run code-pushup -- --verbose diff --git a/code-pushup.config.ts b/code-pushup.config.ts index 99f40a4..153548e 100644 --- a/code-pushup.config.ts +++ b/code-pushup.config.ts @@ -6,20 +6,21 @@ import nxPerformancePlugin, { import {TaskTimeAuditOption} from './tooling/measures/nx-performance'; const onlyAudits: OnlyAudit[] = [ - 'graph-time-project', - 'graph-time-task', - 'cache-size', + // 'graph-time-project', + // 'graph-time-task', + // 'cache-size', 'task-time', ]; const taskGraphTasks = ['cli-e2e:nxv-env-install']; const taskTimeTasks: TaskTimeAuditOption[] = [ - {task: 'models-e2e:nxv-env-teardown'}, - {task: 'models-e2e:nxv-env-bootstrap'}, - {task: 'models-e2e:nxv-env-setup'}, {task: 'models-e2e:e2e'}, - {task: 'models-e2e:nxv-e2e'}, - {task: 'nx-verdaccio-e2e:nxv-e2e'}, - {task: 'cli-e2e-original:original-e2e', options: { exclude: ["nx-verdaccio"]}}, + /* {task: 'models-e2e:nxv-env-teardown'}, + {task: 'models-e2e:nxv-env-bootstrap'}, + {task: 'models-e2e:nxv-env-setup'}, + {task: 'models-e2e:e2e'}, + {task: 'models-e2e:nxv-e2e'}, + {task: 'nx-verdaccio-e2e:nxv-e2e'}, + {task: 'cli-e2e-original:original-e2e', options: { exclude: ["nx-verdaccio"]}},*/ ]; const cacheSizeTasks = [ 'models-e2e:nxv-env-setup', From db39ff75f4385dca53c6f5d8e974a5744f46c100 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 02:57:55 +0100 Subject: [PATCH 7/8] wip CP --- code-pushup.config.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/code-pushup.config.ts b/code-pushup.config.ts index 153548e..99f40a4 100644 --- a/code-pushup.config.ts +++ b/code-pushup.config.ts @@ -6,21 +6,20 @@ import nxPerformancePlugin, { import {TaskTimeAuditOption} from './tooling/measures/nx-performance'; const onlyAudits: OnlyAudit[] = [ - // 'graph-time-project', - // 'graph-time-task', - // 'cache-size', + 'graph-time-project', + 'graph-time-task', + 'cache-size', 'task-time', ]; const taskGraphTasks = ['cli-e2e:nxv-env-install']; const taskTimeTasks: TaskTimeAuditOption[] = [ + {task: 'models-e2e:nxv-env-teardown'}, + {task: 'models-e2e:nxv-env-bootstrap'}, + {task: 'models-e2e:nxv-env-setup'}, {task: 'models-e2e:e2e'}, - /* {task: 'models-e2e:nxv-env-teardown'}, - {task: 'models-e2e:nxv-env-bootstrap'}, - {task: 'models-e2e:nxv-env-setup'}, - {task: 'models-e2e:e2e'}, - {task: 'models-e2e:nxv-e2e'}, - {task: 'nx-verdaccio-e2e:nxv-e2e'}, - {task: 'cli-e2e-original:original-e2e', options: { exclude: ["nx-verdaccio"]}},*/ + {task: 'models-e2e:nxv-e2e'}, + {task: 'nx-verdaccio-e2e:nxv-e2e'}, + {task: 'cli-e2e-original:original-e2e', options: { exclude: ["nx-verdaccio"]}}, ]; const cacheSizeTasks = [ 'models-e2e:nxv-env-setup', From 0a5c2ae7a5b242ebc6169f38df327b0c8f2ac733 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 02:59:18 +0100 Subject: [PATCH 8/8] update CP --- package-lock.json | 74 +++++++++++++++++++++++++++++++++-------------- package.json | 8 ++--- 2 files changed, 56 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index 26fd6bd..d196705 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,17 +9,16 @@ "version": "0.0.0", "license": "MIT", "dependencies": { - "@rollup/rollup-win32-x64-msvc": "*", "memfs": "^4.11.1", "simple-git": "^3.27.0", "tslib": "^2.3.0", "yargs": "^17.7.2" }, "devDependencies": { - "@code-pushup/cli": "^0.50.0", - "@code-pushup/core": "^0.50.0", - "@code-pushup/models": "^0.50.0", - "@code-pushup/utils": "^0.50.0", + "@code-pushup/cli": "^0.54.0", + "@code-pushup/core": "^0.54.0", + "@code-pushup/models": "^0.54.0", + "@code-pushup/utils": "^0.54.0", "@nx/devkit": "19.8.0", "@nx/esbuild": "19.8.0", "@nx/eslint": "19.8.0", @@ -1824,13 +1823,14 @@ "license": "MIT" }, "node_modules/@code-pushup/cli": { - "version": "0.50.0", + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@code-pushup/cli/-/cli-0.54.0.tgz", + "integrity": "sha512-5BpfYKxlQPQQeQeVppt9hSnleQRBI4lY+4CS7HrcjvubXKNAO5LhAVPsbPtpc0WoZ8swRcx+yrajdB5jZIeeew==", "dev": true, - "license": "MIT", "dependencies": { - "@code-pushup/core": "0.50.0", - "@code-pushup/models": "0.50.0", - "@code-pushup/utils": "0.50.0", + "@code-pushup/core": "0.54.0", + "@code-pushup/models": "0.54.0", + "@code-pushup/utils": "0.54.0", "ansis": "^3.3.0", "simple-git": "^3.20.0", "yargs": "^17.7.2" @@ -1840,20 +1840,29 @@ } }, "node_modules/@code-pushup/core": { - "version": "0.50.0", + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@code-pushup/core/-/core-0.54.0.tgz", + "integrity": "sha512-cpRHhrmeeMRQ6Sy7lUVNubhc9VQrR0SLNBFYQL5kTXaZsWqwNPba6W2wwxOsv2sP5696UzEkDtv/oS6lBPZyqA==", "dev": true, - "license": "MIT", "dependencies": { - "@code-pushup/models": "0.50.0", - "@code-pushup/portal-client": "^0.9.0", - "@code-pushup/utils": "0.50.0", + "@code-pushup/models": "0.54.0", + "@code-pushup/utils": "0.54.0", "ansis": "^3.3.0" + }, + "peerDependencies": { + "@code-pushup/portal-client": "^0.9.0" + }, + "peerDependenciesMeta": { + "@code-pushup/portal-client": { + "optional": true + } } }, "node_modules/@code-pushup/models": { - "version": "0.50.0", + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@code-pushup/models/-/models-0.54.0.tgz", + "integrity": "sha512-+k6gWAAMkZ78+6pdb7zsNNgUU+7xSQ9H7l04Shv2lXcvMWcfcSYJNtMfBr9PIRDlCCNOA0ml0LED9gYQ8rhLnQ==", "dev": true, - "license": "MIT", "dependencies": { "vscode-material-icons": "^0.1.0", "zod": "^3.22.1" @@ -1862,6 +1871,8 @@ "node_modules/@code-pushup/portal-client": { "version": "0.9.0", "dev": true, + "optional": true, + "peer": true, "dependencies": { "graphql": "^16.6.0", "graphql-request": "^6.1.0", @@ -1870,11 +1881,12 @@ } }, "node_modules/@code-pushup/utils": { - "version": "0.50.0", + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@code-pushup/utils/-/utils-0.54.0.tgz", + "integrity": "sha512-QISMKWRpi2Vza3nrjV0uNzK2+nlGNvXVUa3FUOrvWspTdpYUdFrX+LBVHyFJITqhxiluCg7gZOkysNGUqs8eOg==", "dev": true, - "license": "MIT", "dependencies": { - "@code-pushup/models": "0.50.0", + "@code-pushup/models": "0.54.0", "@isaacs/cliui": "^8.0.2", "@poppinss/cliui": "^6.4.0", "ansis": "^3.3.0", @@ -2205,6 +2217,8 @@ "version": "3.2.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } @@ -7037,6 +7051,8 @@ "version": "3.1.8", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "node-fetch": "^2.6.12" } @@ -8777,6 +8793,8 @@ "version": "16.9.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -8785,6 +8803,8 @@ "version": "6.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@graphql-typed-document-node/core": "^3.2.0", "cross-fetch": "^3.1.5" @@ -8797,6 +8817,8 @@ "version": "2.12.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "tslib": "^2.1.0" }, @@ -11104,6 +11126,8 @@ "version": "2.7.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -11122,17 +11146,23 @@ "node_modules/node-fetch/node_modules/tr46": { "version": "0.0.3", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/node-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "dev": true, - "license": "BSD-2-Clause" + "license": "BSD-2-Clause", + "optional": true, + "peer": true }, "node_modules/node-fetch/node_modules/whatwg-url": { "version": "5.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" diff --git a/package.json b/package.json index 33ac037..1339f70 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,10 @@ "yargs": "^17.7.2" }, "devDependencies": { - "@code-pushup/cli": "^0.50.0", - "@code-pushup/core": "^0.50.0", - "@code-pushup/models": "^0.50.0", - "@code-pushup/utils": "^0.50.0", + "@code-pushup/cli": "^0.54.0", + "@code-pushup/core": "^0.54.0", + "@code-pushup/models": "^0.54.0", + "@code-pushup/utils": "^0.54.0", "@nx/devkit": "19.8.0", "@nx/esbuild": "19.8.0", "@nx/eslint": "19.8.0",