Merge branch 'worktree/ci-native-windows-coverage-20260808' into worktree/ci-native-windows-multicore-20260809

# Conflicts:
#	.agents/notes/implemented/process/2026-08-08-native-windows-pull-request-ci.i18n.yaml
This commit is contained in:
Tianyi Cui
2026-08-09 20:50:38 +08:00
7 changed files with 50 additions and 12 deletions

View File

@@ -1,4 +1,5 @@
import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs'
import { mkdirSync, mkdtempSync, readFileSync, rmSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs'
import { realpath } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { pathToFileURL } from 'node:url'
@@ -40,7 +41,7 @@ describe('HMR exact config paths', () => {
// This acceptance owns alias-to-cache identity. Other cases below exercise
// native events; polling keeps Windows fs.watch queue pressure out of it.
const ctx = await bootHmr(alias, ['.'], true)
const filename = join(realpathSync(target), 'module.ts')
const filename = join(await realpath(target), 'module.ts')
const expected = pathToFileURL(filename).href
const cacheHas = vi.spyOn(ctx.loader.internal!.loadCache, 'has').mockReturnValue(false)
const observed: string[] = []
@@ -73,7 +74,7 @@ describe('HMR exact config paths', () => {
const ctx = await bootHmr(alias)
try {
await ctx.hmr.registerConfig('plugins.yml', () => {})
await expect(ctx.hmr.registerConfig(join(realpathSync(target), 'plugins.yml'), () => {}))
await expect(ctx.hmr.registerConfig(join(await realpath(target), 'plugins.yml'), () => {}))
.rejects.toThrow('config path already registered')
} finally {
await ctx.fiber.dispose()

View File

@@ -2,7 +2,7 @@ import { execFile } from 'node:child_process'
import { createHash } from 'node:crypto'
import { mkdtemp, mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { delimiter, join } from 'node:path'
import { pathToFileURL } from 'node:url'
import { promisify } from 'node:util'
import { afterEach, describe, expect, it, vi } from 'vitest'
@@ -122,6 +122,10 @@ describe('RepositoryCache', () => {
await mkdir(join(repository, '.dsh-plugin', 'build-helper'), { recursive: true })
await mkdir(join(repository, '.dsh-plugin', 'prepare-helper'), { recursive: true })
await mkdir(join(repository, 'skills', 'fixture'), { recursive: true })
const shadowPnpm = join(root, 'shadow-pnpm')
await mkdir(shadowPnpm)
await writeFile(join(shadowPnpm, 'pnpm'), '#!/bin/sh\nexit 99\n', { mode: 0o700 })
await writeFile(join(shadowPnpm, 'pnpm.bat'), '@exit /b 99\r\n')
await writeFile(join(repository, 'package.json'), `${JSON.stringify({
name: 'repository-fixture',
private: true,
@@ -160,6 +164,7 @@ describe('RepositoryCache', () => {
"cpSync('../skills', 'dsh-plugin-assets/skills/0', { recursive: true })",
"writeFileSync('dsh-plugin.mjs', 'export function apply() {}\\n')",
"writeFileSync('prepared.txt', `${process.env.REPOSITORY_TEST_VISIBLE ?? 'absent'}|${process.env.REPOSITORY_TEST_TOKEN ?? 'absent'}|${process.env.PNPM_CONFIG_IGNORE_WORKSPACE ?? 'absent'}\\n`)",
"writeFileSync('environment.json', `${JSON.stringify({ path: process.env.PATH, pathExt: process.env.PATHEXT })}\\n`)",
'',
].join('\n'), { mode: 0o700 })
await writeFile(join(repository, 'skills', 'fixture', 'SKILL.md'), 'repository skill source\n')
@@ -191,10 +196,19 @@ describe('RepositoryCache', () => {
const specifier = `git+${pathToFileURL(repository).href}#${stdout.trim()}&path:/.dsh-plugin`
vi.stubEnv('REPOSITORY_TEST_VISIBLE', 'visible')
vi.stubEnv('REPOSITORY_TEST_TOKEN', 'hidden')
vi.stubEnv('PNPM_HOME', shadowPnpm)
vi.stubEnv('PATH', [shadowPnpm, ...(process.env.PATH === undefined ? [] : [process.env.PATH])].join(delimiter))
vi.stubEnv('PATHEXT', '.BAT;.CMD;.EXE')
const installed = await new RepositoryCache(join(root, 'cache')).resolve(specifier)
await expect(readFile(join(installed, 'dependency-built.txt'), 'utf8')).resolves.toBe('dependency available\n')
await expect(readFile(join(installed, 'prepared.txt'), 'utf8')).resolves.toBe('visible|absent|true\n')
const environment = JSON.parse(await readFile(join(installed, 'environment.json'), 'utf8')) as {
path: string
pathExt: string
}
expect(environment.path.split(delimiter)).not.toContain(shadowPnpm)
expect(environment.pathExt.split(';')[0]?.toUpperCase()).toBe('.CMD')
await expect(readFile(join(installed, 'dsh-plugin.mjs'), 'utf8')).resolves.toContain('export function apply')
expect(lf(await readFile(join(installed, 'dsh-plugin-assets/skills/0/fixture/SKILL.md'), 'utf8')))
.toBe('repository skill source\n')