فهرست منبع

fix(ci): preserve pnpm links in packed probes

Tianyi Cui 3 ماه پیش
والد
کامیت
d4b126862e
1فایلهای تغییر یافته به همراه39 افزوده شده و 47 حذف شده
  1. 39 47
      scripts/verify-built-package-invariants.mjs

+ 39 - 47
scripts/verify-built-package-invariants.mjs

@@ -3,15 +3,12 @@
 import { spawnSync } from 'node:child_process'
 import {
   copyFileSync,
-  existsSync,
   globSync,
   mkdirSync,
   mkdtempSync,
   readFileSync,
   rmSync,
-  symlinkSync,
 } from 'node:fs'
-import { tmpdir } from 'node:os'
 import { dirname, resolve } from 'node:path'
 import { pathToFileURL } from 'node:url'
 
@@ -19,7 +16,6 @@ const root = resolve(import.meta.dirname, '..')
 const loaderUrl = pathToFileURL(resolve(root, 'vendor/loader/lib/index.js')).href
 const failures = []
 const manifests = globSync('packages/*/*/package.json', { cwd: root }).sort()
-const stagingRoot = mkdtempSync(resolve(tmpdir(), 'dsh-built-package-invariants-'))
 const packArgs = ['pack', '--dry-run', '--json', '--ignore-scripts']
 // Windows cannot spawn npm's .cmd shim directly; setup-node installs this JS
 // entrypoint beside node.exe, so the probe stays shell-free on every runner.
@@ -27,38 +23,41 @@ const npmInvocation = process.platform === 'win32'
   ? [process.execPath, [resolve(dirname(process.execPath), 'node_modules/npm/bin/npm-cli.js'), ...packArgs]]
   : ['npm', packArgs]
 
-try {
-  for (const [index, manifestPath] of manifests.entries()) {
-    const packageDir = dirname(resolve(root, manifestPath))
-    const manifest = JSON.parse(readFileSync(resolve(root, manifestPath), 'utf8'))
-    const packageName = manifest.name
-    if (typeof packageName !== 'string' || packageName.length === 0) {
-      failures.push(`${manifestPath}: missing package name`)
-      continue
-    }
+for (const manifestPath of manifests) {
+  const packageDir = dirname(resolve(root, manifestPath))
+  const manifest = JSON.parse(readFileSync(resolve(root, manifestPath), 'utf8'))
+  const packageName = manifest.name
+  if (typeof packageName !== 'string' || packageName.length === 0) {
+    failures.push(`${manifestPath}: missing package name`)
+    continue
+  }
 
-    const pack = spawnSync(npmInvocation[0], npmInvocation[1], {
-      cwd: packageDir,
-      encoding: 'utf8',
-    })
-    if (pack.status !== 0) {
-      const detail = pack.error?.message
-        ?? (pack.stderr.trim() || pack.stdout.trim() || `npm pack exited ${pack.status}`)
-      failures.push(`${packageName}: ${detail}`)
-      continue
-    }
+  const pack = spawnSync(npmInvocation[0], npmInvocation[1], {
+    cwd: packageDir,
+    encoding: 'utf8',
+  })
+  if (pack.status !== 0) {
+    const detail = pack.error?.message
+      ?? (pack.stderr.trim() || pack.stdout.trim() || `npm pack exited ${pack.status}`)
+    failures.push(`${packageName}: ${detail}`)
+    continue
+  }
 
-    let files
-    try {
-      const result = JSON.parse(pack.stdout)
-      files = result[0]?.files
-      if (!Array.isArray(files)) throw new Error('npm pack returned no file inventory')
-    } catch (error) {
-      failures.push(`${packageName}: cannot parse npm pack inventory: ${String(error)}`)
-      continue
-    }
+  let files
+  try {
+    const result = JSON.parse(pack.stdout)
+    files = result[0]?.files
+    if (!Array.isArray(files)) throw new Error('npm pack returned no file inventory')
+  } catch (error) {
+    failures.push(`${packageName}: cannot parse npm pack inventory: ${String(error)}`)
+    continue
+  }
 
-    const stagedPackageDir = resolve(stagingRoot, String(index))
+  // Keep the packed view below its owning package so Node reaches the real
+  // pnpm dependency links. Junctioning node_modules elsewhere breaks pnpm's
+  // relative workspace links on Windows.
+  const stagedPackageDir = mkdtempSync(resolve(packageDir, '.dsh-packed-invariant-'))
+  try {
     for (const file of files) {
       if (typeof file.path !== 'string'
         || (file.path !== 'package.json' && !file.path.startsWith('lib/'))) continue
@@ -66,14 +65,6 @@ try {
       mkdirSync(dirname(target), { recursive: true })
       copyFileSync(resolve(packageDir, file.path), target)
     }
-    const packageNodeModules = resolve(packageDir, 'node_modules')
-    if (existsSync(packageNodeModules)) {
-      symlinkSync(
-        packageNodeModules,
-        resolve(stagedPackageDir, 'node_modules'),
-        process.platform === 'win32' ? 'junction' : 'dir',
-      )
-    }
 
     const probe = `
       const companion = await import(${JSON.stringify(`${packageName}/invariant`)});
@@ -92,13 +83,14 @@ try {
       cwd: stagedPackageDir,
       encoding: 'utf8',
     })
-    if (result.status === 0) continue
-    const detail = result.error?.message
-      ?? (result.stderr.trim() || result.stdout.trim() || `node exited ${result.status}`)
-    failures.push(`${packageName}: ${detail}`)
+    if (result.status !== 0) {
+      const detail = result.error?.message
+        ?? (result.stderr.trim() || result.stdout.trim() || `node exited ${result.status}`)
+      failures.push(`${packageName}: ${detail}`)
+    }
+  } finally {
+    rmSync(stagedPackageDir, { recursive: true, force: true })
   }
-} finally {
-  rmSync(stagingRoot, { recursive: true, force: true })
 }
 
 if (failures.length > 0) {