4
0
Fork 0
mirror of https://github.com/Azure/setup-helm.git synced 2025-11-07 04:56:56 +00:00
This commit is contained in:
Marcus Vinicius Tavares 2025-10-29 16:37:25 -03:00 committed by GitHub
commit 4a94aef191
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 139 additions and 18 deletions

View file

@ -1,5 +1,11 @@
# Change Log
## [4.4.0] - 2025-10-29
### Added
- Add fallback URL support via optional `downloadBaseURLFallback` input for improved download reliability
## [4.3.1] - 2025-08-12
### Changed

View file

@ -7,7 +7,7 @@ Install a specific version of helm binary on the runner.
Acceptable values are latest or any semantic version string like v3.5.0 Use this action in workflow to define which version of helm will be used. v2+ of this action only support Helm3.
```yaml
- uses: azure/setup-helm@v4.3.0
- uses: azure/setup-helm@v4.4.0
with:
version: '<version>' # default is latest (stable)
id: install

View file

@ -14,6 +14,10 @@ inputs:
description: 'Set the download base URL'
required: false
default: 'https://get.helm.sh'
downloadBaseURLFallback:
description: 'Fallback base URL if primary download fails'
required: false
default: ''
outputs:
helm-path:
description: 'Path to the cached helm binary'

View file

@ -1,6 +1,6 @@
{
"name": "setuphelm",
"version": "4.3.1",
"version": "4.4.0",
"private": true,
"description": "Setup helm",
"author": "Anumita Shenoy",

View file

@ -228,7 +228,7 @@ describe('run.ts', () => {
return {isDirectory: () => isDirectory} as fs.Stats
})
expect(await run.downloadHelm(downloadBaseURL, 'v4.0.0')).toBe(
expect(await run.downloadHelm(downloadBaseURL, 'v4.0.0', '')).toBe(
path.join('pathToCachedDir', 'helm.exe')
)
expect(toolCache.find).toHaveBeenCalledWith('helm', 'v4.0.0')
@ -252,9 +252,9 @@ describe('run.ts', () => {
jest.spyOn(os, 'arch').mockReturnValue('x64')
const downloadUrl = 'https://test.tld/helm-v3.2.1-windows-amd64.zip'
await expect(run.downloadHelm(downloadBaseURL, 'v3.2.1')).rejects.toThrow(
`Failed to download Helm from location ${downloadUrl}`
)
await expect(
run.downloadHelm(downloadBaseURL, 'v3.2.1', '')
).rejects.toThrow(`Failed to download Helm from location ${downloadUrl}`)
expect(toolCache.find).toHaveBeenCalledWith('helm', 'v3.2.1')
expect(toolCache.downloadTool).toHaveBeenCalledWith(`${downloadUrl}`)
})
@ -278,7 +278,7 @@ describe('run.ts', () => {
return {isDirectory: () => isDirectory} as fs.Stats
})
expect(await run.downloadHelm(downloadBaseURL, 'v3.2.1')).toBe(
expect(await run.downloadHelm(downloadBaseURL, 'v3.2.1', '')).toBe(
path.join('pathToCachedDir', 'helm.exe')
)
expect(toolCache.find).toHaveBeenCalledWith('helm', 'v3.2.1')
@ -304,9 +304,9 @@ describe('run.ts', () => {
return {isDirectory: () => isDirectory} as fs.Stats
})
await expect(run.downloadHelm(downloadBaseURL, 'v3.2.1')).rejects.toThrow(
'Helm executable not found in path pathToCachedDir'
)
await expect(
run.downloadHelm(downloadBaseURL, 'v3.2.1', '')
).rejects.toThrow('Helm executable not found in path pathToCachedDir')
expect(toolCache.find).toHaveBeenCalledWith('helm', 'v3.2.1')
expect(toolCache.downloadTool).toHaveBeenCalledWith(
'https://test.tld/helm-v3.2.1-windows-amd64.zip'
@ -314,4 +314,86 @@ describe('run.ts', () => {
expect(fs.chmodSync).toHaveBeenCalledWith('pathToTool', '777')
expect(toolCache.extractZip).toHaveBeenCalledWith('pathToTool')
})
test('downloadHelm() - use fallback URL when primary download fails', async () => {
const fallbackBaseURL = 'https://fallback.tld'
jest.spyOn(toolCache, 'find').mockReturnValue('')
jest
.spyOn(toolCache, 'downloadTool')
.mockRejectedValueOnce(new Error('Primary download failed'))
.mockResolvedValueOnce('pathToTool')
jest.spyOn(toolCache, 'extractZip').mockResolvedValue('extractedPath')
jest.spyOn(toolCache, 'cacheDir').mockResolvedValue('pathToCachedDir')
jest.spyOn(os, 'platform').mockReturnValue('win32')
jest.spyOn(os, 'arch').mockReturnValue('x64')
jest.spyOn(fs, 'chmodSync').mockImplementation()
jest.spyOn(core, 'warning').mockImplementation()
jest
.spyOn(fs, 'readdirSync')
.mockImplementation((file, _) => [
'helm.exe' as unknown as fs.Dirent<Buffer<ArrayBufferLike>>
])
jest.spyOn(fs, 'statSync').mockImplementation((file) => {
const isDirectory =
(file as string).indexOf('folder') == -1 ? false : true
return {isDirectory: () => isDirectory} as fs.Stats
})
expect(
await run.downloadHelm(downloadBaseURL, 'v3.2.1', fallbackBaseURL)
).toBe(path.join('pathToCachedDir', 'helm.exe'))
expect(toolCache.downloadTool).toHaveBeenCalledTimes(2)
expect(toolCache.downloadTool).toHaveBeenNthCalledWith(
1,
'https://test.tld/helm-v3.2.1-windows-amd64.zip'
)
expect(toolCache.downloadTool).toHaveBeenNthCalledWith(
2,
'https://fallback.tld/helm-v3.2.1-windows-amd64.zip'
)
expect(core.warning).toHaveBeenCalled()
})
test('downloadHelm() - throw error if both primary and fallback downloads fail', async () => {
const fallbackBaseURL = 'https://fallback.tld'
jest.spyOn(toolCache, 'find').mockReturnValue('')
jest
.spyOn(toolCache, 'downloadTool')
.mockRejectedValueOnce(new Error('Primary download failed'))
.mockRejectedValueOnce(new Error('Fallback download failed'))
jest.spyOn(os, 'platform').mockReturnValue('win32')
jest.spyOn(os, 'arch').mockReturnValue('x64')
await expect(
run.downloadHelm(downloadBaseURL, 'v3.2.1', fallbackBaseURL)
).rejects.toThrow(
'Failed to download Helm from location https://test.tld/helm-v3.2.1-windows-amd64.zip or https://fallback.tld/helm-v3.2.1-windows-amd64.zip'
)
expect(toolCache.downloadTool).toHaveBeenCalledTimes(2)
})
test('downloadHelm() - work without fallback URL (backwards compatibility)', async () => {
jest.spyOn(toolCache, 'find').mockReturnValue('')
jest.spyOn(toolCache, 'downloadTool').mockResolvedValue('pathToTool')
jest.spyOn(toolCache, 'extractZip').mockResolvedValue('extractedPath')
jest.spyOn(toolCache, 'cacheDir').mockResolvedValue('pathToCachedDir')
jest.spyOn(os, 'platform').mockReturnValue('win32')
jest.spyOn(os, 'arch').mockReturnValue('x64')
jest.spyOn(fs, 'chmodSync').mockImplementation()
jest
.spyOn(fs, 'readdirSync')
.mockImplementation((file, _) => [
'helm.exe' as unknown as fs.Dirent<Buffer<ArrayBufferLike>>
])
jest.spyOn(fs, 'statSync').mockImplementation((file) => {
const isDirectory =
(file as string).indexOf('folder') == -1 ? false : true
return {isDirectory: () => isDirectory} as fs.Stats
})
expect(await run.downloadHelm(downloadBaseURL, 'v3.2.1')).toBe(
path.join('pathToCachedDir', 'helm.exe')
)
expect(toolCache.downloadTool).toHaveBeenCalledTimes(1)
})
})

View file

@ -24,9 +24,16 @@ export async function run() {
}
const downloadBaseURL = core.getInput('downloadBaseURL', {required: false})
const downloadBaseURLFallback = core.getInput('downloadBaseURLFallback', {
required: false
})
core.startGroup(`Installing ${version}`)
const cachedPath = await downloadHelm(downloadBaseURL, version)
const cachedPath = await downloadHelm(
downloadBaseURL,
version,
downloadBaseURLFallback
)
core.endGroup()
try {
@ -84,7 +91,8 @@ export function getHelmDownloadURL(baseURL: string, version: string): string {
export async function downloadHelm(
baseURL: string,
version: string
version: string,
fallbackBaseURL?: string
): Promise<string> {
let cachedToolpath = toolCache.find(helmToolName, version)
if (cachedToolpath) {
@ -97,12 +105,33 @@ export async function downloadHelm(
getHelmDownloadURL(baseURL, version)
)
} catch (exception) {
throw new Error(
`Failed to download Helm from location ${getHelmDownloadURL(
baseURL,
version
)}`
)
if (fallbackBaseURL) {
core.warning(
`Failed to download Helm from location ${getHelmDownloadURL(
baseURL,
version
)}. Attempting to download from fallback URL: ${fallbackBaseURL}`
)
try {
helmDownloadPath = await toolCache.downloadTool(
getHelmDownloadURL(fallbackBaseURL, version)
)
} catch (fallbackException) {
throw new Error(
`Failed to download Helm from location ${getHelmDownloadURL(
baseURL,
version
)} or ${getHelmDownloadURL(fallbackBaseURL, version)}`
)
}
} else {
throw new Error(
`Failed to download Helm from location ${getHelmDownloadURL(
baseURL,
version
)}`
)
}
}
fs.chmodSync(helmDownloadPath, '777')