From 5876560d6cc083816a823bf32f9df6d5f6318e68 Mon Sep 17 00:00:00 2001 From: Oliver King Date: Fri, 4 Feb 2022 09:45:03 -0500 Subject: [PATCH] Add arm64 support (#64) * add arm64 support --- __tests__/run.test.ts | 174 ---------------------------- src/run.test.ts | 264 ++++++++++++++++++++++++++++++++++++++++++ src/run.ts | 241 ++++++++++++++++++++++---------------- 3 files changed, 407 insertions(+), 272 deletions(-) delete mode 100644 __tests__/run.test.ts create mode 100644 src/run.test.ts diff --git a/__tests__/run.test.ts b/__tests__/run.test.ts deleted file mode 100644 index bdc8573f..00000000 --- a/__tests__/run.test.ts +++ /dev/null @@ -1,174 +0,0 @@ -import * as run from '../src/run' -import * as os from 'os'; -import * as toolCache from '@actions/tool-cache'; -import * as fs from 'fs'; -import * as path from 'path'; -import * as core from '@actions/core'; - -describe('run.ts', () => { - test('getExecutableExtension() - return .exe when os is Windows', () => { - jest.spyOn(os, 'type').mockReturnValue('Windows_NT'); - - expect(run.getExecutableExtension()).toBe('.exe'); - expect(os.type).toBeCalled(); - }); - - test('getExecutableExtension() - return empty string for non-windows OS', () => { - jest.spyOn(os, 'type').mockReturnValue('Darwin'); - - expect(run.getExecutableExtension()).toBe(''); - expect(os.type).toBeCalled(); - }); - - test('getHelmDownloadURL() - return the URL to download helm for Linux', () => { - jest.spyOn(os, 'type').mockReturnValue('Linux'); - const kubectlLinuxUrl = 'https://get.helm.sh/helm-v3.8.0-linux-amd64.zip' - - expect(run.getHelmDownloadURL('v3.8.0')).toBe(kubectlLinuxUrl); - expect(os.type).toBeCalled(); - }); - - test('getHelmDownloadURL() - return the URL to download helm for Darwin', () => { - jest.spyOn(os, 'type').mockReturnValue('Darwin'); - const kubectlDarwinUrl = 'https://get.helm.sh/helm-v3.8.0-darwin-amd64.zip' - - expect(run.getHelmDownloadURL('v3.8.0')).toBe(kubectlDarwinUrl); - expect(os.type).toBeCalled(); - }); - - test('getHelmDownloadURL() - return the URL to download helm for Windows', () => { - jest.spyOn(os, 'type').mockReturnValue('Windows_NT'); - - const kubectlWindowsUrl = 'https://get.helm.sh/helm-v3.8.0-windows-amd64.zip' - expect(run.getHelmDownloadURL('v3.8.0')).toBe(kubectlWindowsUrl); - expect(os.type).toBeCalled(); - }); - - test('getLatestHelmVersion() - return the latest version of HELM', async () => { - try{ - expect(await run.getLatestHelmVersion()).toBe("v3.8.0"); - } catch (e){ - return e; - } - }); - - test('walkSync() - return path to the all files matching fileToFind in dir', () => { - jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => { - if (file == 'mainFolder') return ['file1' as unknown as fs.Dirent, 'file2' as unknown as fs.Dirent, 'folder1' as unknown as fs.Dirent, 'folder2' as unknown as fs.Dirent]; - if (file == path.join('mainFolder', 'folder1')) return ['file11' as unknown as fs.Dirent, 'file12' as unknown as fs.Dirent]; - if (file == path.join('mainFolder', 'folder2')) return ['file21' as unknown as fs.Dirent, 'file22' as unknown as fs.Dirent]; - }); - jest.spyOn(core, 'debug').mockImplementation(); - jest.spyOn(fs, 'statSync').mockImplementation((file) => { - const isDirectory = (file as string).toLowerCase().indexOf('file') == -1 ? true: false - return { isDirectory: () => isDirectory } as fs.Stats; - }); - - expect(run.walkSync('mainFolder', null, 'file21')).toEqual([path.join('mainFolder', 'folder2', 'file21')]); - expect(fs.readdirSync).toBeCalledTimes(3); - expect(fs.statSync).toBeCalledTimes(8); - }); - - test('walkSync() - return empty array if no file with name fileToFind exists', () => { - jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => { - if (file == 'mainFolder') return ['file1' as unknown as fs.Dirent, 'file2' as unknown as fs.Dirent, 'folder1' as unknown as fs.Dirent, 'folder2' as unknown as fs.Dirent]; - if (file == path.join('mainFolder', 'folder1')) return ['file11' as unknown as fs.Dirent, 'file12' as unknown as fs.Dirent]; - if (file == path.join('mainFolder', 'folder2')) return ['file21' as unknown as fs.Dirent, 'file22' as unknown as fs.Dirent]; - }); - jest.spyOn(core, 'debug').mockImplementation(); - jest.spyOn(fs, 'statSync').mockImplementation((file) => { - const isDirectory = (file as string).toLowerCase().indexOf('file') == -1 ? true: false - return { isDirectory: () => isDirectory } as fs.Stats; - }); - - expect(run.walkSync('mainFolder', null, 'helm.exe')).toEqual([]); - expect(fs.readdirSync).toBeCalledTimes(3); - expect(fs.statSync).toBeCalledTimes(8); - }); - - test('findHelm() - change access permissions and find the helm in given directory', () => { - jest.spyOn(fs, 'chmodSync').mockImplementation(() => {}); - jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => { - if (file == 'mainFolder') return ['helm.exe' as unknown as fs.Dirent]; - }); - jest.spyOn(fs, 'statSync').mockImplementation((file) => { - const isDirectory = (file as string).indexOf('folder') == -1 ? false: true - return { isDirectory: () => isDirectory } as fs.Stats; - }); - jest.spyOn(os, 'type').mockReturnValue('Windows_NT'); - - expect(run.findHelm('mainFolder')).toBe(path.join('mainFolder', 'helm.exe')); - }); - - test('findHelm() - throw error if executable not found', () => { - jest.spyOn(fs, 'chmodSync').mockImplementation(() => {}); - jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => { - if (file == 'mainFolder') return []; - }); - jest.spyOn(fs, 'statSync').mockImplementation((file) => { return { isDirectory: () => true } as fs.Stats}); - jest.spyOn(os, 'type').mockReturnValue('Windows_NT'); - expect(() => run.findHelm('mainFolder')).toThrow('Helm executable not found in path mainFolder'); - }); - - test('downloadHelm() - download helm and return path to it', async () => { - jest.spyOn(toolCache, 'find').mockReturnValue(''); - jest.spyOn(toolCache, 'downloadTool').mockResolvedValue('pathToTool'); - const response = JSON.stringify([{'tag_name': 'v4.0.0'}]); - jest.spyOn(fs, 'readFileSync').mockReturnValue(response); - jest.spyOn(os, 'type').mockReturnValue('Windows_NT'); - jest.spyOn(fs, 'chmodSync').mockImplementation(() => {}); - jest.spyOn(toolCache, 'extractZip').mockResolvedValue('pathToUnzippedHelm'); - jest.spyOn(toolCache, 'cacheDir').mockResolvedValue('pathToCachedDir'); - jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => ['helm.exe' as unknown as fs.Dirent]); - 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("v4.0.0")).toBe(path.join('pathToCachedDir', 'helm.exe')); - expect(toolCache.find).toBeCalledWith('helm', 'v4.0.0'); - expect(toolCache.downloadTool).toBeCalledWith('https://get.helm.sh/helm-v4.0.0-windows-amd64.zip'); - expect(fs.chmodSync).toBeCalledWith('pathToTool', '777'); - expect(toolCache.extractZip).toBeCalledWith('pathToTool'); - expect(fs.chmodSync).toBeCalledWith(path.join('pathToCachedDir', 'helm.exe'), '777'); - }); - - test('downloadHelm() - throw error if unable to download', async () => { - jest.spyOn(toolCache, 'find').mockReturnValue(''); - jest.spyOn(toolCache, 'downloadTool').mockImplementation(async () => { throw 'Unable to download'}); - jest.spyOn(os, 'type').mockReturnValue('Windows_NT'); - - await expect(run.downloadHelm('v3.2.1')).rejects.toThrow('Failed to download Helm from location https://get.helm.sh/helm-v3.2.1-windows-amd64.zip'); - expect(toolCache.find).toBeCalledWith('helm', 'v3.2.1'); - expect(toolCache.downloadTool).toBeCalledWith('https://get.helm.sh/helm-v3.2.1-windows-amd64.zip'); - }); - - test('downloadHelm() - return path to helm tool with same version from toolCache', async () => { - jest.spyOn(toolCache, 'find').mockReturnValue('pathToCachedDir'); - jest.spyOn(fs, 'chmodSync').mockImplementation(() => {}); - - expect(await run.downloadHelm('v3.2.1')).toBe(path.join('pathToCachedDir', 'helm.exe')); - expect(toolCache.find).toBeCalledWith('helm', 'v3.2.1'); - expect(fs.chmodSync).toBeCalledWith(path.join('pathToCachedDir', 'helm.exe'), '777'); - }); - - test('downloadHelm() - throw error is helm is not found in path', async () => { - jest.spyOn(toolCache, 'find').mockReturnValue(''); - jest.spyOn(toolCache, 'downloadTool').mockResolvedValue('pathToTool'); - jest.spyOn(os, 'type').mockReturnValue('Windows_NT'); - jest.spyOn(fs, 'chmodSync').mockImplementation(); - jest.spyOn(toolCache, 'extractZip').mockResolvedValue('pathToUnzippedHelm'); - jest.spyOn(toolCache, 'cacheDir').mockResolvedValue('pathToCachedDir'); - jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => []); - jest.spyOn(fs, 'statSync').mockImplementation((file) => { - const isDirectory = (file as string).indexOf('folder') == -1 ? false: true - return { isDirectory: () => isDirectory } as fs.Stats; - }); - - await expect(run.downloadHelm('v3.2.1')).rejects.toThrow('Helm executable not found in path pathToCachedDir'); - expect(toolCache.find).toBeCalledWith('helm', 'v3.2.1'); - expect(toolCache.downloadTool).toBeCalledWith('https://get.helm.sh/helm-v3.2.1-windows-amd64.zip'); - expect(fs.chmodSync).toBeCalledWith('pathToTool', '777'); - expect(toolCache.extractZip).toBeCalledWith('pathToTool'); - }); -}); \ No newline at end of file diff --git a/src/run.test.ts b/src/run.test.ts new file mode 100644 index 00000000..d50930d7 --- /dev/null +++ b/src/run.test.ts @@ -0,0 +1,264 @@ +import * as run from "./run"; +import * as os from "os"; +import * as toolCache from "@actions/tool-cache"; +import * as fs from "fs"; +import * as path from "path"; +import * as core from "@actions/core"; + +describe("run.ts", () => { + test("getExecutableExtension() - return .exe when os is Windows", () => { + jest.spyOn(os, "type").mockReturnValue("Windows_NT"); + + expect(run.getExecutableExtension()).toBe(".exe"); + expect(os.type).toBeCalled(); + }); + + test("getExecutableExtension() - return empty string for non-windows OS", () => { + jest.spyOn(os, "type").mockReturnValue("Darwin"); + + expect(run.getExecutableExtension()).toBe(""); + expect(os.type).toBeCalled(); + }); + + test("getHelmDownloadURL() - return the URL to download helm for Linux", () => { + jest.spyOn(os, "type").mockReturnValue("Linux"); + jest.spyOn(os, "arch").mockReturnValueOnce("unknown"); + const kubectlLinuxUrl = "https://get.helm.sh/helm-v3.8.0-linux-amd64.zip"; + + expect(run.getHelmDownloadURL("v3.8.0")).toBe(kubectlLinuxUrl); + expect(os.type).toBeCalled(); + expect(os.arch).toBeCalled(); + + // arm64 + jest.spyOn(os, "type").mockReturnValue("Linux"); + jest.spyOn(os, "arch").mockReturnValueOnce("arm64"); + const kubectlLinuxArm64Url = + "https://get.helm.sh/helm-v3.8.0-linux-arm64.zip"; + + expect(run.getHelmDownloadURL("v3.8.0")).toBe(kubectlLinuxArm64Url); + expect(os.type).toBeCalled(); + expect(os.arch).toBeCalled(); + }); + + test("getHelmDownloadURL() - return the URL to download helm for Darwin", () => { + jest.spyOn(os, "type").mockReturnValue("Darwin"); + jest.spyOn(os, "arch").mockReturnValueOnce("unknown"); + const kubectlDarwinUrl = "https://get.helm.sh/helm-v3.8.0-darwin-amd64.zip"; + + expect(run.getHelmDownloadURL("v3.8.0")).toBe(kubectlDarwinUrl); + expect(os.type).toBeCalled(); + expect(os.arch).toBeCalled(); + + // arm64 + jest.spyOn(os, "type").mockReturnValue("Darwin"); + jest.spyOn(os, "arch").mockReturnValueOnce("arm64"); + const kubectlDarwinArm64Url = + "https://get.helm.sh/helm-v3.8.0-darwin-arm64.zip"; + + expect(run.getHelmDownloadURL("v3.8.0")).toBe(kubectlDarwinArm64Url); + expect(os.type).toBeCalled(); + expect(os.arch).toBeCalled(); + }); + + test("getHelmDownloadURL() - return the URL to download helm for Windows", () => { + jest.spyOn(os, "type").mockReturnValue("Windows_NT"); + + const kubectlWindowsUrl = + "https://get.helm.sh/helm-v3.8.0-windows-amd64.zip"; + expect(run.getHelmDownloadURL("v3.8.0")).toBe(kubectlWindowsUrl); + expect(os.type).toBeCalled(); + }); + + test("getLatestHelmVersion() - return the latest version of HELM", async () => { + try { + expect(await run.getLatestHelmVersion()).toBe("v3.8.0"); + } catch (e) { + return e; + } + }); + + test("walkSync() - return path to the all files matching fileToFind in dir", () => { + jest.spyOn(fs, "readdirSync").mockImplementation((file, _) => { + if (file == "mainFolder") + return [ + "file1" as unknown as fs.Dirent, + "file2" as unknown as fs.Dirent, + "folder1" as unknown as fs.Dirent, + "folder2" as unknown as fs.Dirent, + ]; + if (file == path.join("mainFolder", "folder1")) + return [ + "file11" as unknown as fs.Dirent, + "file12" as unknown as fs.Dirent, + ]; + if (file == path.join("mainFolder", "folder2")) + return [ + "file21" as unknown as fs.Dirent, + "file22" as unknown as fs.Dirent, + ]; + }); + jest.spyOn(core, "debug").mockImplementation(); + jest.spyOn(fs, "statSync").mockImplementation((file) => { + const isDirectory = + (file as string).toLowerCase().indexOf("file") == -1 ? true : false; + return { isDirectory: () => isDirectory } as fs.Stats; + }); + + expect(run.walkSync("mainFolder", null, "file21")).toEqual([ + path.join("mainFolder", "folder2", "file21"), + ]); + expect(fs.readdirSync).toBeCalledTimes(3); + expect(fs.statSync).toBeCalledTimes(8); + }); + + test("walkSync() - return empty array if no file with name fileToFind exists", () => { + jest.spyOn(fs, "readdirSync").mockImplementation((file, _) => { + if (file == "mainFolder") + return [ + "file1" as unknown as fs.Dirent, + "file2" as unknown as fs.Dirent, + "folder1" as unknown as fs.Dirent, + "folder2" as unknown as fs.Dirent, + ]; + if (file == path.join("mainFolder", "folder1")) + return [ + "file11" as unknown as fs.Dirent, + "file12" as unknown as fs.Dirent, + ]; + if (file == path.join("mainFolder", "folder2")) + return [ + "file21" as unknown as fs.Dirent, + "file22" as unknown as fs.Dirent, + ]; + }); + jest.spyOn(core, "debug").mockImplementation(); + jest.spyOn(fs, "statSync").mockImplementation((file) => { + const isDirectory = + (file as string).toLowerCase().indexOf("file") == -1 ? true : false; + return { isDirectory: () => isDirectory } as fs.Stats; + }); + + expect(run.walkSync("mainFolder", null, "helm.exe")).toEqual([]); + expect(fs.readdirSync).toBeCalledTimes(3); + expect(fs.statSync).toBeCalledTimes(8); + }); + + test("findHelm() - change access permissions and find the helm in given directory", () => { + jest.spyOn(fs, "chmodSync").mockImplementation(() => {}); + jest.spyOn(fs, "readdirSync").mockImplementation((file, _) => { + if (file == "mainFolder") return ["helm.exe" as unknown as fs.Dirent]; + }); + jest.spyOn(fs, "statSync").mockImplementation((file) => { + const isDirectory = + (file as string).indexOf("folder") == -1 ? false : true; + return { isDirectory: () => isDirectory } as fs.Stats; + }); + jest.spyOn(os, "type").mockReturnValue("Windows_NT"); + + expect(run.findHelm("mainFolder")).toBe( + path.join("mainFolder", "helm.exe") + ); + }); + + test("findHelm() - throw error if executable not found", () => { + jest.spyOn(fs, "chmodSync").mockImplementation(() => {}); + jest.spyOn(fs, "readdirSync").mockImplementation((file, _) => { + if (file == "mainFolder") return []; + }); + jest.spyOn(fs, "statSync").mockImplementation((file) => { + return { isDirectory: () => true } as fs.Stats; + }); + jest.spyOn(os, "type").mockReturnValue("Windows_NT"); + expect(() => run.findHelm("mainFolder")).toThrow( + "Helm executable not found in path mainFolder" + ); + }); + + test("downloadHelm() - download helm and return path to it", async () => { + jest.spyOn(toolCache, "find").mockReturnValue(""); + jest.spyOn(toolCache, "downloadTool").mockResolvedValue("pathToTool"); + const response = JSON.stringify([{ tag_name: "v4.0.0" }]); + jest.spyOn(fs, "readFileSync").mockReturnValue(response); + jest.spyOn(os, "type").mockReturnValue("Windows_NT"); + jest.spyOn(fs, "chmodSync").mockImplementation(() => {}); + jest.spyOn(toolCache, "extractZip").mockResolvedValue("pathToUnzippedHelm"); + jest.spyOn(toolCache, "cacheDir").mockResolvedValue("pathToCachedDir"); + jest + .spyOn(fs, "readdirSync") + .mockImplementation((file, _) => ["helm.exe" as unknown as fs.Dirent]); + 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("v4.0.0")).toBe( + path.join("pathToCachedDir", "helm.exe") + ); + expect(toolCache.find).toBeCalledWith("helm", "v4.0.0"); + expect(toolCache.downloadTool).toBeCalledWith( + "https://get.helm.sh/helm-v4.0.0-windows-amd64.zip" + ); + expect(fs.chmodSync).toBeCalledWith("pathToTool", "777"); + expect(toolCache.extractZip).toBeCalledWith("pathToTool"); + expect(fs.chmodSync).toBeCalledWith( + path.join("pathToCachedDir", "helm.exe"), + "777" + ); + }); + + test("downloadHelm() - throw error if unable to download", async () => { + jest.spyOn(toolCache, "find").mockReturnValue(""); + jest.spyOn(toolCache, "downloadTool").mockImplementation(async () => { + throw "Unable to download"; + }); + jest.spyOn(os, "type").mockReturnValue("Windows_NT"); + + await expect(run.downloadHelm("v3.2.1")).rejects.toThrow( + "Failed to download Helm from location https://get.helm.sh/helm-v3.2.1-windows-amd64.zip" + ); + expect(toolCache.find).toBeCalledWith("helm", "v3.2.1"); + expect(toolCache.downloadTool).toBeCalledWith( + "https://get.helm.sh/helm-v3.2.1-windows-amd64.zip" + ); + }); + + test("downloadHelm() - return path to helm tool with same version from toolCache", async () => { + jest.spyOn(toolCache, "find").mockReturnValue("pathToCachedDir"); + jest.spyOn(fs, "chmodSync").mockImplementation(() => {}); + + expect(await run.downloadHelm("v3.2.1")).toBe( + path.join("pathToCachedDir", "helm.exe") + ); + expect(toolCache.find).toBeCalledWith("helm", "v3.2.1"); + expect(fs.chmodSync).toBeCalledWith( + path.join("pathToCachedDir", "helm.exe"), + "777" + ); + }); + + test("downloadHelm() - throw error is helm is not found in path", async () => { + jest.spyOn(toolCache, "find").mockReturnValue(""); + jest.spyOn(toolCache, "downloadTool").mockResolvedValue("pathToTool"); + jest.spyOn(os, "type").mockReturnValue("Windows_NT"); + jest.spyOn(fs, "chmodSync").mockImplementation(); + jest.spyOn(toolCache, "extractZip").mockResolvedValue("pathToUnzippedHelm"); + jest.spyOn(toolCache, "cacheDir").mockResolvedValue("pathToCachedDir"); + jest.spyOn(fs, "readdirSync").mockImplementation((file, _) => []); + jest.spyOn(fs, "statSync").mockImplementation((file) => { + const isDirectory = + (file as string).indexOf("folder") == -1 ? false : true; + return { isDirectory: () => isDirectory } as fs.Stats; + }); + + await expect(run.downloadHelm("v3.2.1")).rejects.toThrow( + "Helm executable not found in path pathToCachedDir" + ); + expect(toolCache.find).toBeCalledWith("helm", "v3.2.1"); + expect(toolCache.downloadTool).toBeCalledWith( + "https://get.helm.sh/helm-v3.2.1-windows-amd64.zip" + ); + expect(fs.chmodSync).toBeCalledWith("pathToTool", "777"); + expect(toolCache.extractZip).toBeCalledWith("pathToTool"); + }); +}); diff --git a/src/run.ts b/src/run.ts index c9a79276..1e58f01c 100644 --- a/src/run.ts +++ b/src/run.ts @@ -2,140 +2,185 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as os from 'os'; -import * as path from 'path'; -import * as util from 'util'; -import * as fs from 'fs'; +import * as os from "os"; +import * as path from "path"; +import * as util from "util"; +import * as fs from "fs"; -import * as toolCache from '@actions/tool-cache'; -import * as core from '@actions/core'; +import * as toolCache from "@actions/tool-cache"; +import * as core from "@actions/core"; -const helmToolName = 'helm'; -const stableHelmVersion = 'v3.8.0'; -const helmAllReleasesUrl = 'https://api.github.com/repos/helm/helm/releases'; +const helmToolName = "helm"; +const stableHelmVersion = "v3.8.0"; +const helmAllReleasesUrl = "https://api.github.com/repos/helm/helm/releases"; export async function run() { - let version = core.getInput('version', { 'required': true }); + let version = core.getInput("version", { required: true }); - if (version.toLocaleLowerCase() === 'latest') { - version = await getLatestHelmVersion(); - } - - core.debug(util.format("Downloading %s", version)); - let cachedPath = await downloadHelm(version); + if (version.toLocaleLowerCase() === "latest") { + version = await getLatestHelmVersion(); + } - try { + core.debug(util.format("Downloading %s", version)); + let cachedPath = await downloadHelm(version); - if (!process.env['PATH'].startsWith(path.dirname(cachedPath))) { - core.addPath(path.dirname(cachedPath)); - } + try { + if (!process.env["PATH"].startsWith(path.dirname(cachedPath))) { + core.addPath(path.dirname(cachedPath)); } - catch { - //do nothing, set as output variable - } - - console.log(`Helm tool version: '${version}' has been cached at ${cachedPath}`); - core.setOutput('helm-path', cachedPath); + } catch { + //do nothing, set as output variable + } + + console.log( + `Helm tool version: '${version}' has been cached at ${cachedPath}` + ); + core.setOutput("helm-path", cachedPath); } -// Downloads the helm releases JSON and parses all the recent versions of helm from it. +// Downloads the helm releases JSON and parses all the recent versions of helm from it. // Defaults to sending stable helm version if none are valid or if it fails export async function getLatestHelmVersion(): Promise { - const helmJSONPath: string = await toolCache.downloadTool(helmAllReleasesUrl); - - try { - const helmJSON = JSON.parse(fs.readFileSync(helmJSONPath, 'utf-8')) - for(let i in helmJSON) { - if(isValidVersion(helmJSON[i].tag_name)) { - return helmJSON[i].tag_name; - } - } - } catch(err) { - core.warning(util.format("Error while fetching the latest Helm release. Error: %s. Using default Helm version %s", err.toString(), stableHelmVersion)); - return stableHelmVersion; + const helmJSONPath: string = await toolCache.downloadTool(helmAllReleasesUrl); + + try { + const helmJSON = JSON.parse(fs.readFileSync(helmJSONPath, "utf-8")); + for (let i in helmJSON) { + if (isValidVersion(helmJSON[i].tag_name)) { + return helmJSON[i].tag_name; + } } - + } catch (err) { + core.warning( + util.format( + "Error while fetching the latest Helm release. Error: %s. Using default Helm version %s", + err.toString(), + stableHelmVersion + ) + ); return stableHelmVersion; + } + + return stableHelmVersion; } // isValidVersion checks if verison is a stable release function isValidVersion(version: string): boolean { - return version.indexOf('rc') == -1; + return version.indexOf("rc") == -1; } export function getExecutableExtension(): string { - if (os.type().match(/^Win/)) { - return '.exe'; - } - return ''; + if (os.type().match(/^Win/)) { + return ".exe"; + } + return ""; } +const LINUX = "Linux"; +const MAC_OS = "Darwin"; +const WINDOWS = "Windows_NT"; +const ARM64 = "arm64"; export function getHelmDownloadURL(version: string): string { - switch (os.type()) { - case 'Linux': - return util.format('https://get.helm.sh/helm-%s-linux-amd64.zip', version); - - case 'Darwin': - return util.format('https://get.helm.sh/helm-%s-darwin-amd64.zip', version); - - case 'Windows_NT': - default: - return util.format('https://get.helm.sh/helm-%s-windows-amd64.zip', version); - } + const arch = os.arch(); + const operatingSystem = os.type(); + + switch (true) { + case operatingSystem == LINUX && arch == ARM64: + return util.format( + "https://get.helm.sh/helm-%s-linux-arm64.zip", + version + ); + case operatingSystem == LINUX: + return util.format( + "https://get.helm.sh/helm-%s-linux-amd64.zip", + version + ); + + case operatingSystem == MAC_OS && arch == ARM64: + return util.format( + "https://get.helm.sh/helm-%s-darwin-arm64.zip", + version + ); + case operatingSystem == MAC_OS: + return util.format( + "https://get.helm.sh/helm-%s-darwin-amd64.zip", + version + ); + + case operatingSystem == WINDOWS: + default: + return util.format( + "https://get.helm.sh/helm-%s-windows-amd64.zip", + version + ); + } } export async function downloadHelm(version: string): Promise { - let cachedToolpath = toolCache.find(helmToolName, version); - if (!cachedToolpath) { - let helmDownloadPath; - try { - helmDownloadPath = await toolCache.downloadTool(getHelmDownloadURL(version)); - } catch (exception) { - throw new Error(util.format("Failed to download Helm from location", getHelmDownloadURL(version))); - } - - fs.chmodSync(helmDownloadPath, '777'); - const unzipedHelmPath = await toolCache.extractZip(helmDownloadPath); - cachedToolpath = await toolCache.cacheDir(unzipedHelmPath, helmToolName, version); - } - - const helmpath = findHelm(cachedToolpath); - if (!helmpath) { - throw new Error(util.format("Helm executable not found in path", cachedToolpath)); + let cachedToolpath = toolCache.find(helmToolName, version); + if (!cachedToolpath) { + let helmDownloadPath; + try { + helmDownloadPath = await toolCache.downloadTool( + getHelmDownloadURL(version) + ); + } catch (exception) { + throw new Error( + util.format( + "Failed to download Helm from location", + getHelmDownloadURL(version) + ) + ); } - fs.chmodSync(helmpath, '777'); - return helmpath; + fs.chmodSync(helmDownloadPath, "777"); + const unzipedHelmPath = await toolCache.extractZip(helmDownloadPath); + cachedToolpath = await toolCache.cacheDir( + unzipedHelmPath, + helmToolName, + version + ); + } + + const helmpath = findHelm(cachedToolpath); + if (!helmpath) { + throw new Error( + util.format("Helm executable not found in path", cachedToolpath) + ); + } + + fs.chmodSync(helmpath, "777"); + return helmpath; } export function findHelm(rootFolder: string): string { - fs.chmodSync(rootFolder, '777'); - var filelist: string[] = []; - walkSync(rootFolder, filelist, helmToolName + getExecutableExtension()); - if (!filelist || filelist.length == 0) { - throw new Error(util.format("Helm executable not found in path", rootFolder)); - } - else { - return filelist[0]; - } + fs.chmodSync(rootFolder, "777"); + var filelist: string[] = []; + walkSync(rootFolder, filelist, helmToolName + getExecutableExtension()); + if (!filelist || filelist.length == 0) { + throw new Error( + util.format("Helm executable not found in path", rootFolder) + ); + } else { + return filelist[0]; + } } export var walkSync = function (dir, filelist, fileToFind) { - var files = fs.readdirSync(dir); - filelist = filelist || []; - files.forEach(function (file) { - if (fs.statSync(path.join(dir, file)).isDirectory()) { - filelist = walkSync(path.join(dir, file), filelist, fileToFind); - } - else { - core.debug(file); - if (file == fileToFind) { - filelist.push(path.join(dir, file)); - } - } - }); - return filelist; + var files = fs.readdirSync(dir); + filelist = filelist || []; + files.forEach(function (file) { + if (fs.statSync(path.join(dir, file)).isDirectory()) { + filelist = walkSync(path.join(dir, file), filelist, fileToFind); + } else { + core.debug(file); + if (file == fileToFind) { + filelist.push(path.join(dir, file)); + } + } + }); + return filelist; }; run().catch(core.setFailed);