This commit is contained in:
@@ -4,25 +4,23 @@ on: push
|
|||||||
jobs:
|
jobs:
|
||||||
diag:
|
diag:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
timeout-minutes: 10
|
timeout-minutes: 20
|
||||||
|
env:
|
||||||
|
CI: 'true'
|
||||||
steps:
|
steps:
|
||||||
- name: Probe tool sources
|
- uses: actions/checkout@v4
|
||||||
run: |
|
timeout-minutes: 10
|
||||||
whoami
|
- uses: actions/setup-node@v4
|
||||||
"TEMP=$env:TEMP"
|
timeout-minutes: 10
|
||||||
"HTTP_PROXY=$env:HTTP_PROXY HTTPS_PROXY=$env:HTTPS_PROXY NO_PROXY=$env:NO_PROXY"
|
with:
|
||||||
try { [System.Net.Dns]::GetHostAddresses('www.gyan.dev') | ForEach-Object { "DNS gyan: $($_.IPAddressToString)" } } catch { "DNS gyan ERR: $($_.Exception.Message)" }
|
node-version: '24.11.1'
|
||||||
try { [System.Net.Dns]::GetHostAddresses('github.com') | ForEach-Object { "DNS github: $($_.IPAddressToString)" } } catch { "DNS github ERR: $($_.Exception.Message)" }
|
cache: npm
|
||||||
$ProgressPreference = 'SilentlyContinue'
|
- name: Clean install
|
||||||
try { $r = Invoke-WebRequest -Uri 'https://api.github.com/' -UseBasicParsing -TimeoutSec 20; "api.github: $($r.StatusCode)" } catch { "api.github ERR: $($_.Exception.Message)" }
|
run: npm ci
|
||||||
try { $r = Invoke-WebRequest -Uri 'https://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-8.1.2-essentials_build.zip' -Method Head -UseBasicParsing -TimeoutSec 30; "gyan HEAD: $($r.StatusCode) len=$($r.Headers['Content-Length'])" } catch { "gyan ERR: $($_.Exception.Message)" }
|
timeout-minutes: 10
|
||||||
try { $r = Invoke-WebRequest -Uri 'https://github.com/streamlink/windows-builds/releases/download/8.4.0-1/streamlink-8.4.0-1-py314-x86_64.zip' -Method Head -UseBasicParsing -TimeoutSec 30; "github release HEAD: $($r.StatusCode) len=$($r.Headers['Content-Length'])" } catch { "github release ERR: $($_.Exception.Message)" }
|
- name: Build
|
||||||
$node = Get-Command node -ErrorAction SilentlyContinue
|
run: npm run build
|
||||||
if ($node) {
|
timeout-minutes: 10
|
||||||
"node: $($node.Source) $(node --version)"
|
- name: Repair repro with full diagnostics
|
||||||
node -e "const https=require('https');https.get('https://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-8.1.2-essentials_build.zip',{timeout:20000},r=>{console.log('node gyan status',r.statusCode);r.destroy();}).on('error',e=>console.log('node gyan ERR',e.code||'',e.message)).on('timeout',function(){this.destroy();console.log('node gyan TIMEOUT')})"
|
run: node tvm-diag-repair.js
|
||||||
Start-Sleep -Seconds 3
|
timeout-minutes: 10
|
||||||
} else {
|
|
||||||
'node not on PATH'
|
|
||||||
}
|
|
||||||
exit 0
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
const fs = require('node:fs');
|
||||||
|
const os = require('node:os');
|
||||||
|
const path = require('node:path');
|
||||||
|
const { spawn } = require('node:child_process');
|
||||||
|
const axios = require(path.join(process.cwd(), 'node_modules', 'axios'));
|
||||||
|
const { createManagedToolInstaller } = require(path.join(process.cwd(), 'dist', 'main', 'domain', 'managed-tools.js'));
|
||||||
|
const { APPLICATION_TOOL_MANIFEST } = require(path.join(process.cwd(), 'dist', 'main', 'domain', 'tool-manifest.js'));
|
||||||
|
|
||||||
|
async function downloadFile(url, destinationPath) {
|
||||||
|
const response = await axios.get(url, { responseType: 'stream', timeout: 120000 });
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
const writer = fs.createWriteStream(destinationPath);
|
||||||
|
response.data.on('error', (err) => { writer.destroy(); reject(err); });
|
||||||
|
response.data.pipe(writer);
|
||||||
|
writer.on('finish', () => resolve());
|
||||||
|
writer.on('error', (err) => reject(err));
|
||||||
|
});
|
||||||
|
const size = fs.statSync(destinationPath).size;
|
||||||
|
console.log('downloaded', url, '->', destinationPath, size, 'bytes');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function extractZip(zipPath, destinationDir) {
|
||||||
|
fs.mkdirSync(destinationDir, { recursive: true });
|
||||||
|
const command = `Expand-Archive -Path '${zipPath.replace(/'/g, "''")}' -DestinationPath '${destinationDir.replace(/'/g, "''")}' -Force`;
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
const proc = spawn('powershell', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', command], { windowsHide: true });
|
||||||
|
let stderr = '';
|
||||||
|
proc.stderr?.on('data', (data) => { stderr += data.toString(); });
|
||||||
|
proc.on('close', (code) => {
|
||||||
|
console.log('extract close code', code, 'stderr:', stderr.trim().slice(0, 500));
|
||||||
|
if (code === 0) resolve(); else reject(new Error(`Expand-Archive exit code ${code}: ${stderr.trim()}`));
|
||||||
|
});
|
||||||
|
proc.on('error', (err) => { console.log('extract spawn error', err.message); reject(err); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
console.log('user temp:', os.tmpdir());
|
||||||
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'tvm-diag-repair-'));
|
||||||
|
console.log('sandbox:', root);
|
||||||
|
for (const toolId of ['streamlink', 'ffmpeg']) {
|
||||||
|
const manifest = APPLICATION_TOOL_MANIFEST[toolId];
|
||||||
|
const installationDirectory = path.join(root, 'tools', toolId);
|
||||||
|
const temporaryDirectory = path.join(root, 'managed-tools-temp');
|
||||||
|
fs.mkdirSync(installationDirectory, { recursive: true });
|
||||||
|
fs.mkdirSync(temporaryDirectory, { recursive: true });
|
||||||
|
const installer = createManagedToolInstaller({
|
||||||
|
installationDirectory,
|
||||||
|
temporaryDirectory,
|
||||||
|
download: downloadFile,
|
||||||
|
extract: extractZip,
|
||||||
|
diagnostic: (message, details) => console.log('DIAG', toolId, message, JSON.stringify(details))
|
||||||
|
});
|
||||||
|
const started = Date.now();
|
||||||
|
try {
|
||||||
|
const result = await installer.repair(manifest);
|
||||||
|
console.log(toolId, 'repair after', Date.now() - started, 'ms:', JSON.stringify({
|
||||||
|
success: result.success,
|
||||||
|
error: result.error,
|
||||||
|
detail: result.detail,
|
||||||
|
status: result.status,
|
||||||
|
diagnostics: result.diagnostics
|
||||||
|
}, null, 2));
|
||||||
|
} catch (error) {
|
||||||
|
console.log(toolId, 'repair THREW after', Date.now() - started, 'ms:', String(error && error.stack || error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fs.rmSync(root, { recursive: true, force: true });
|
||||||
|
})().catch((error) => {
|
||||||
|
console.error('FATAL', error);
|
||||||
|
process.exitCode = 1;
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user