fix(release): kill broader locks before npm ci (rolldown EPERM)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,18 +3,60 @@ import { promisify } from 'node:util';
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
/** Stop vite/electron dev servers that lock dnd_player node_modules during npm ci. */
|
||||
/**
|
||||
* Stop Vite/Electron/dev.mjs/TTRPGPlayer that lock native .node files under
|
||||
* dnd_player/node_modules (EPERM unlink on @rolldown during npm ci).
|
||||
* @param {string} projectRoot
|
||||
*/
|
||||
export async function killBlockingDevProcesses(projectRoot) {
|
||||
if (process.platform !== 'win32') return;
|
||||
|
||||
const rootEsc = projectRoot.replace(/'/g, "''");
|
||||
const script = `
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
$root = '${rootEsc}'
|
||||
$killed = [System.Collections.Generic.HashSet[int]]::new()
|
||||
foreach ($name in @('TTRPGPlayer','electron')) {
|
||||
Get-Process -Name $name | ForEach-Object {
|
||||
Stop-Process -Id $_.Id -Force
|
||||
[void]$killed.Add([int]$_.Id)
|
||||
}
|
||||
}
|
||||
Get-CimInstance Win32_Process -Filter "Name='node.exe'" | ForEach-Object {
|
||||
$cmd = [string]$_.CommandLine
|
||||
if (-not $cmd) { return }
|
||||
$touches = ($cmd -like ('*' + $root + '*')) -or ($cmd -match 'dnd_player')
|
||||
if (-not $touches) { return }
|
||||
if ($cmd -match 'dev\\.mjs|vite|electron|esbuild|rolldown|tsx|scripts[/\\\\]dev') {
|
||||
Stop-Process -Id $_.ProcessId -Force
|
||||
[void]$killed.Add([int]$_.ProcessId)
|
||||
}
|
||||
}
|
||||
foreach ($port in @(5173, 5174)) {
|
||||
try {
|
||||
Get-NetTCPConnection -LocalPort $port -ErrorAction Stop | ForEach-Object {
|
||||
$ownerPid = [int]$_.OwningProcess
|
||||
if ($ownerPid -gt 0) {
|
||||
Stop-Process -Id $ownerPid -Force
|
||||
[void]$killed.Add($ownerPid)
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
Start-Sleep -Seconds 2
|
||||
$rolldown = Join-Path $root 'node_modules\\@rolldown\\binding-win32-x64-msvc'
|
||||
if (Test-Path -LiteralPath $rolldown) {
|
||||
Remove-Item -LiteralPath $rolldown -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
Start-Sleep -Seconds 1
|
||||
Write-Output ('killed=' + $killed.Count)
|
||||
`;
|
||||
|
||||
try {
|
||||
const { stdout } = await execFileAsync(
|
||||
'powershell',
|
||||
[
|
||||
'-NoProfile',
|
||||
'-Command',
|
||||
`Get-CimInstance Win32_Process -Filter "name='node.exe'" | Where-Object { $_.CommandLine -match 'dnd_player' -and ($_.CommandLine -match 'vite dev|electron') } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }`,
|
||||
],
|
||||
{ windowsHide: true },
|
||||
['-NoProfile', '-Command', script],
|
||||
{ windowsHide: true, timeout: 30000 },
|
||||
);
|
||||
void stdout;
|
||||
} catch {
|
||||
@@ -24,6 +66,7 @@ export async function killBlockingDevProcesses(projectRoot) {
|
||||
|
||||
/**
|
||||
* @param {string} cwd
|
||||
* @param {string} scriptName
|
||||
* @param {string[]} args
|
||||
* @param {(line: string) => void} onLine
|
||||
*/
|
||||
@@ -62,7 +105,7 @@ export function runPowerShellScript(cwd, scriptName, args, onLine) {
|
||||
});
|
||||
}
|
||||
|
||||
/** @param {string} projectRoot */
|
||||
/** @param {string} projectRoot @param {(line: string) => void} onLine */
|
||||
export async function gitPull(projectRoot, onLine) {
|
||||
onLine('git pull…');
|
||||
await new Promise((resolve, reject) => {
|
||||
@@ -88,6 +131,7 @@ export async function gitPull(projectRoot, onLine) {
|
||||
/** @param {string} line @returns {number | null} */
|
||||
export function progressFromLogLine(line) {
|
||||
if (/Mac artifacts check/i.test(line)) return 12;
|
||||
if (/Stopping processes that may lock/i.test(line)) return 20;
|
||||
if (/Build Windows/i.test(line)) return 22;
|
||||
if (/npm ci/i.test(line)) return 28;
|
||||
if (/pack:win/i.test(line)) return 38;
|
||||
|
||||
Reference in New Issue
Block a user