fix(managed-tools): stage downloaded archives with a .zip extension
Windows CI / verify (push) Failing after 2m11s

The installer staged downloaded tool archives as archiveName.uuid, so
the temporary file no longer ended in .zip. The Expand-Archive cmdlet
shipped with stock Windows PowerShell (Microsoft.PowerShell.Archive
1.0.1.0) rejects any archive whose extension is not .zip, which made
every managed streamlink and ffmpeg installation fail with
extract-failed on systems without an updated Archive module - including
plain end-user machines and the self-hosted CI runner. The unique
download path now uses the UUID as a prefix and keeps the manifest
archive name with its .zip extension intact.
This commit is contained in:
Sucukdeluxe
2026-08-14 15:09:26 +02:00
parent 9f2a54a8f6
commit 70124a9570
2 changed files with 13 additions and 1 deletions
+12
View File
@@ -107,6 +107,18 @@ afterEach(() => {
}); });
describe('managed tool installer', () => { describe('managed tool installer', () => {
it('stages the downloaded archive under a unique path that keeps the .zip extension', async () => {
const { installer, download } = createInstaller();
const result = await installer.repair(manifest());
expect(result.success).toBe(true);
expect(download).toHaveBeenCalledTimes(1);
const archivePath = download.mock.calls[0][1];
expect(path.extname(archivePath)).toBe('.zip');
expect(path.basename(archivePath)).not.toBe(manifest().archiveName);
});
it('retains the working installation when the downloaded archive hash is corrupted', async () => { it('retains the working installation when the downloaded archive hash is corrupted', async () => {
const { installer, installPath, download } = createInstaller({ archiveContents: 'corrupted archive' }); const { installer, installPath, download } = createInstaller({ archiveContents: 'corrupted archive' });
writeExistingInstallation(installPath); writeExistingInstallation(installPath);
+1 -1
View File
@@ -217,7 +217,7 @@ export class ManagedToolInstaller {
private async installOnce(manifest: ExternalToolManifest): Promise<ManagedToolInstallResult> { private async installOnce(manifest: ExternalToolManifest): Promise<ManagedToolInstallResult> {
const uniqueSuffix = crypto.randomUUID(); const uniqueSuffix = crypto.randomUUID();
const archivePath = path.join(this.options.temporaryDirectory, `${manifest.archiveName}.${uniqueSuffix}`); const archivePath = path.join(this.options.temporaryDirectory, `${uniqueSuffix}-${manifest.archiveName}`);
const stagingDirectory = `${this.options.installationDirectory}.stage-${uniqueSuffix}`; const stagingDirectory = `${this.options.installationDirectory}.stage-${uniqueSuffix}`;
const diagnostics: string[] = []; const diagnostics: string[] = [];