diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f51ba81f9..a897c48567 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,35 +27,31 @@ jobs: - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - - name: Install pnpm - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4 + - name: Setup utoo + uses: utooland/setup-utoo@3a51006d0b66afcc32d1b9177a4b200b74f4a8cb # main - name: Set up Node.js uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6 with: node-version: '24' - cache: 'pnpm' - name: Install dependencies - run: pnpm install --frozen-lockfile + run: ut install --from pnpm - name: Run lint - run: pnpm run lint - - - name: Check dedupe - run: pnpm dedupe --check + run: ut run lint - name: Run typecheck - run: pnpm run typecheck + run: ut run typecheck - name: Run format check - run: pnpm run fmtcheck + run: ut run fmtcheck - name: Run build - run: pnpm run build + run: ut run build - name: Run site build - run: pnpm run site:build + run: ut run site:build test: strategy: @@ -157,25 +153,24 @@ jobs: # & mysqladmin -u root password root & mysql -uroot -e "CREATE DATABASE IF NOT EXISTS test;" - - name: Install pnpm - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4 + - name: Setup utoo + uses: utooland/setup-utoo@3a51006d0b66afcc32d1b9177a4b200b74f4a8cb # main - name: Set up Node.js uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6 with: node-version: ${{ matrix.node }} - cache: 'pnpm' - name: Install dependencies - run: pnpm install --frozen-lockfile + run: ut install --from pnpm - name: Run tests - run: pnpm run ci --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} + run: ut run ci -- --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} - name: Run example tests if: ${{ matrix.node != '20' && matrix.os != 'windows-latest' }} run: | - pnpm run example:test:all + ut run example:test:all - name: Code Coverage # skip on windows, it will hangup on codecov @@ -205,22 +200,21 @@ jobs: - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - - name: Install pnpm - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4 + - name: Setup utoo + uses: utooland/setup-utoo@3a51006d0b66afcc32d1b9177a4b200b74f4a8cb # main - name: Set up Node.js uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6 with: node-version: ${{ matrix.node }} - cache: 'pnpm' - name: Install dependencies - run: pnpm install --frozen-lockfile + run: ut install --from pnpm - name: Run tests run: | - pnpm build --workspace ./tools/egg-bin - pnpm run --filter ./tools/egg-bin ci + ut run build -- --workspace tools/egg-bin + ut run ci --workspace tools/egg-bin env: # https://github.com/jamiebuilds/ci-parallel-vars CI_NODE_INDEX: ${{ matrix.shardIndex }} @@ -251,22 +245,21 @@ jobs: - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - - name: Install pnpm - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4 + - name: Setup utoo + uses: utooland/setup-utoo@3a51006d0b66afcc32d1b9177a4b200b74f4a8cb # main - name: Set up Node.js uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6 with: node-version: ${{ matrix.node }} - cache: 'pnpm' - name: Install dependencies - run: pnpm install --frozen-lockfile + run: ut install --from pnpm - name: Run tests run: | - pnpm build - pnpm run --filter=./tools/scripts ci + ut run build + ut run ci --workspace tools/scripts - name: Code Coverage if: ${{ matrix.os != 'windows-latest' }} diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 969c3b9526..1dc1459799 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -138,24 +138,23 @@ jobs: with: ecosystem-ci-project: ${{ matrix.project.name }} - - name: Install pnpm - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4 + - name: Setup utoo + uses: utooland/setup-utoo@3a51006d0b66afcc32d1b9177a4b200b74f4a8cb # main - name: Set up Node.js uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6 with: node-version: ${{ matrix.project.node-version }} - cache: 'pnpm' - name: Install dependencies - run: pnpm install --frozen-lockfile + run: ut install --from pnpm - name: Build all packages - run: pnpm build + run: ut run build - name: Pack packages into tgz run: | - pnpm -r pack + node ecosystem-ci/pack-all.mjs - name: Override dependencies from tgz in ${{ matrix.project.name }} working-directory: ecosystem-ci/${{ matrix.project.name }} diff --git a/ecosystem-ci/pack-all.mjs b/ecosystem-ci/pack-all.mjs new file mode 100644 index 0000000000..62236ab0c7 --- /dev/null +++ b/ecosystem-ci/pack-all.mjs @@ -0,0 +1,64 @@ +import { execSync } from 'node:child_process'; +import { readFileSync, writeFileSync } from 'node:fs'; +import { glob } from 'node:fs/promises'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import yaml from 'js-yaml'; + +const rootDir = join(fileURLToPath(import.meta.url), '../..'); +const wsConfig = yaml.load(readFileSync(join(rootDir, 'pnpm-workspace.yaml'), 'utf8')); +const catalog = wsConfig.catalog ?? {}; + +// Build a map of workspace package versions for resolving workspace: protocol +const workspaceVersions = {}; +for (const pattern of wsConfig.packages ?? []) { + for await (const entry of glob(`${pattern}/package.json`, { cwd: rootDir })) { + const pkg = JSON.parse(readFileSync(join(rootDir, entry), 'utf8')); + if (pkg.name && pkg.version) workspaceVersions[pkg.name] = pkg.version; + } +} + +function resolveVersion(name, version) { + if (typeof version !== 'string') return version; + if (version === 'catalog:' || version.startsWith('catalog:')) { + return catalog[name] ?? version; + } + if (version.startsWith('workspace:')) { + return workspaceVersions[name] ? `^${workspaceVersions[name]}` : version; + } + return version; +} + +function resolveDeps(deps) { + if (!deps) return deps; + return Object.fromEntries(Object.entries(deps).map(([k, v]) => [k, resolveVersion(k, v)])); +} + +for (const pattern of wsConfig.packages ?? []) { + for await (const entry of glob(`${pattern}/package.json`, { cwd: rootDir })) { + const pkgPath = join(rootDir, entry); + const original = readFileSync(pkgPath, 'utf8'); + const pkg = JSON.parse(original); + if (pkg.private || !pkg.name || !pkg.version) continue; + + // Apply publishConfig overrides (npm pack does not do this automatically) + const publishConfig = pkg.publishConfig ?? {}; + const publishOverrides = Object.fromEntries( + Object.entries(publishConfig).filter(([k]) => !['access', 'registry', 'tag'].includes(k)), + ); + const patched = { + ...pkg, + ...publishOverrides, + dependencies: resolveDeps(pkg.dependencies), + peerDependencies: resolveDeps(pkg.peerDependencies), + optionalDependencies: resolveDeps(pkg.optionalDependencies), + }; + writeFileSync(pkgPath, JSON.stringify(patched, null, 2) + '\n'); + try { + execSync(`npm pack --pack-destination "${rootDir}"`, { cwd: join(rootDir, dirname(entry)), stdio: 'inherit' }); + } finally { + writeFileSync(pkgPath, original); + } + } +} diff --git a/package.json b/package.json index e8f828791c..b2abf85e69 100644 --- a/package.json +++ b/package.json @@ -8,31 +8,40 @@ "type": "git", "url": "git+https://github.com/eggjs/egg.git" }, + "workspaces": [ + "packages/*", + "plugins/*", + "examples/*", + "tools/*", + "site", + "tegg/core/*", + "tegg/plugin/*", + "tegg/standalone/*" + ], "files": [ "README.md" ], "type": "module", "scripts": { - "clean-dist": "pnpm -r --parallel exec rimraf dist", - "clean": "pnpm -r --parallel run clean && pnpm clean-dist", + "clean-dist": "ut run clean --workspaces", "build": "tsdown", - "prelint": "pnpm clean-dist", + "prelint": "ut run clean-dist", "lint": "oxlint --type-aware --type-check --quiet", "fmt": "oxfmt", - "typecheck": "pnpm clean && pnpm -r run typecheck", + "typecheck": "ut run clean-dist && ut run typecheck --workspaces", "fmtcheck": "oxfmt --check .", - "pretest": "pnpm run clean && pnpm -r run pretest", + "pretest": "ut run clean-dist && ut run pretest --workspaces --if-present", "test": "vitest run --bail 1 --retry 2 --testTimeout 20000 --hookTimeout 20000", - "test:cov": "pnpm run test --coverage", - "preci": "pnpm -r --parallel run pretest", - "ci": "pnpm run test --coverage", - "site:dev": "pnpm --filter=site run dev", - "site:build": "pnpm --filter=site run build", + "test:cov": "ut run test -- --coverage", + "preci": "ut run pretest --workspaces --if-present", + "ci": "ut run test -- --coverage", + "site:dev": "ut run dev --workspace site", + "site:build": "ut run build --workspace site", "puml": "puml . --dest ./site", - "example:dev:commonjs": "pnpm --filter=helloworld-commonjs run dev", - "example:dev:typescript": "pnpm --filter=helloworld-typescript run dev", - "example:dev:tegg": "pnpm --filter=helloworld-tegg run dev", - "example:test:all": "pnpm --filter=helloworld-* run test", + "example:dev:commonjs": "ut run dev --workspace helloworld-commonjs", + "example:dev:typescript": "ut run dev --workspace helloworld-typescript", + "example:dev:tegg": "ut run dev --workspace helloworld-tegg", + "example:test:all": "ut run test --workspace helloworld-typescript && ut run test --workspace helloworld-tegg", "prepare": "husky", "version:patch": "node scripts/version.js patch", "version:minor": "node scripts/version.js minor", @@ -67,9 +76,13 @@ "tsdown": "catalog:", "tsx": "catalog:", "typescript": "catalog:", + "unplugin-unused": "catalog:", "urllib": "catalog:", "vitest": "catalog:" }, + "overrides": { + "vite": "npm:rolldown-vite@^7.1.13" + }, "lint-staged": { "*": [ "oxfmt --no-error-on-unmatched-pattern", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7755709050..508ad0a2eb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -570,6 +570,9 @@ catalogs: typescript: specifier: ^5.9.3 version: 5.9.3 + unplugin-unused: + specifier: ^0.5.4 + version: 0.5.4 urijs: specifier: ^1.19.11 version: 1.19.11 @@ -675,6 +678,9 @@ importers: typescript: specifier: 'catalog:' version: 5.9.3 + unplugin-unused: + specifier: 'catalog:' + version: 0.5.4 urllib: specifier: 'catalog:' version: 4.8.2 @@ -10173,7 +10179,6 @@ snapshots: dependencies: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - optional: true '@jridgewell/resolve-uri@3.1.2': {} @@ -12136,8 +12141,7 @@ snapshots: concat-map@0.0.1: {} - confbox@0.2.2: - optional: true + confbox@0.2.2: {} config-chain@1.1.13: dependencies: @@ -12741,8 +12745,7 @@ snapshots: transitivePeerDependencies: - supports-color - exsolve@1.0.7: - optional: true + exsolve@1.0.7: {} extend-shallow@2.0.1: dependencies: @@ -14885,7 +14888,6 @@ snapshots: confbox: 0.2.2 exsolve: 1.0.7 pathe: 2.0.3 - optional: true platform@1.3.6: {} @@ -15945,7 +15947,6 @@ snapshots: js-tokens: 9.0.1 pkg-types: 2.3.0 unplugin: 2.3.10 - optional: true unplugin@2.3.10: dependencies: @@ -15953,7 +15954,6 @@ snapshots: acorn: 8.15.0 picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 - optional: true unrun@0.2.20: dependencies: @@ -16169,8 +16169,7 @@ snapshots: web-streams-polyfill@4.0.0-beta.3: {} - webpack-virtual-modules@0.6.2: - optional: true + webpack-virtual-modules@0.6.2: {} whatwg-encoding@3.1.1: dependencies: diff --git a/tools/scripts/package.json b/tools/scripts/package.json index 895e386d60..3663293d22 100644 --- a/tools/scripts/package.json +++ b/tools/scripts/package.json @@ -50,8 +50,8 @@ "scripts": { "typecheck": "tsgo --noEmit", "test": "vitest run --bail 1 --no-file-parallelism", - "cov": "pnpm test --coverage", - "ci": "pnpm run cov" + "cov": "ut run test -- --coverage", + "ci": "ut run cov" }, "dependencies": { "@eggjs/utils": "workspace:*", diff --git a/tsdown.config.ts b/tsdown.config.ts index 389c514ae1..12ff5fa10c 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -22,6 +22,7 @@ export default defineConfig({ publint: { level: 'suggestion', strict: true, + pack: 'npm', }, // Default entry pattern - glob to include all source files