From eb399fcd4f2008dc98b83dcc51e730ce9e12da9e Mon Sep 17 00:00:00 2001 From: Ogheneobukome Ejaife <97336369+ejaifeobuks@users.noreply.github.com> Date: Wed, 15 Jul 2026 12:45:05 -0700 Subject: [PATCH] fix: preserve subpath base URLs in getHelmDownloadURL (#292) Ensure downloadBaseURL ends with '/' before URL resolution so a subpath mirror (e.g. https://example/kubernetes/helm) is preserved instead of having its last path segment replaced. Fixes downloads for all subpath mirrors. --- src/run.test.ts | 28 ++++++++++++++++++++++++++++ src/run.ts | 6 +++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/run.test.ts b/src/run.test.ts index 30b313d..a7fea77 100644 --- a/src/run.test.ts +++ b/src/run.test.ts @@ -140,6 +140,34 @@ describe('run.ts', () => { expect(os.platform).toHaveBeenCalled() }) + test('getHelmDownloadURL() - preserve a subpath base URL without a trailing slash', () => { + vi.mocked(os.platform).mockReturnValue('linux') + vi.mocked(os.arch).mockReturnValue('x64') + + const expected = + 'https://mirror.example/kubernetes/helm/helm-v3.8.0-linux-amd64.tar.gz' + expect( + run.getHelmDownloadURL( + 'https://mirror.example/kubernetes/helm', + 'v3.8.0' + ) + ).toBe(expected) + }) + + test('getHelmDownloadURL() - preserve a subpath base URL with a trailing slash', () => { + vi.mocked(os.platform).mockReturnValue('linux') + vi.mocked(os.arch).mockReturnValue('x64') + + const expected = + 'https://mirror.example/kubernetes/helm/helm-v3.8.0-linux-amd64.tar.gz' + expect( + run.getHelmDownloadURL( + 'https://mirror.example/kubernetes/helm/', + 'v3.8.0' + ) + ).toBe(expected) + }) + test('getLatestHelmVersion() - return the latest version of HELM', async () => { const res = { status: 200, diff --git a/src/run.ts b/src/run.ts index ff7c285..833ef87 100644 --- a/src/run.ts +++ b/src/run.ts @@ -139,7 +139,11 @@ export function getExecutableExtension(): string { export function getHelmDownloadURL(baseURL: string, version: string): string { const urlPath = `helm-${version}-${getPlatform()}-${getArch()}.${getArchiveExtension()}` - const url = new URL(urlPath, baseURL) + // Ensure the base ends with '/' so a subpath mirror (e.g. + // 'https://example/kubernetes/helm') is preserved; otherwise URL resolution + // replaces the last path segment and points at the wrong location. + const base = baseURL.endsWith('/') ? baseURL : `${baseURL}/` + const url = new URL(urlPath, base) return url.toString() }