mirror of
https://github.com/Azure/setup-helm.git
synced 2025-11-07 13:06:56 +00:00
Merge 2da3d27d8f into 0400c1212d
This commit is contained in:
commit
4a94aef191
6 changed files with 139 additions and 18 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "setuphelm",
|
||||
"version": "4.3.1",
|
||||
"version": "4.4.0",
|
||||
"private": true,
|
||||
"description": "Setup helm",
|
||||
"author": "Anumita Shenoy",
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
33
src/run.ts
33
src/run.ts
|
|
@ -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,6 +105,26 @@ export async function downloadHelm(
|
|||
getHelmDownloadURL(baseURL, version)
|
||||
)
|
||||
} catch (exception) {
|
||||
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,
|
||||
|
|
@ -104,6 +132,7 @@ export async function downloadHelm(
|
|||
)}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fs.chmodSync(helmDownloadPath, '777')
|
||||
const extractedPath =
|
||||
|
|
|
|||
Loading…
Reference in a new issue