Added arch detection to kubectl download (#117)

This commit is contained in:
Gennady Trubach 2021-03-15 10:16:34 +03:00 коммит произвёл GitHub
Родитель ce7c8f066f
Коммит 282a81e1fc
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 65 добавлений и 15 удалений

Просмотреть файл

@ -6,6 +6,7 @@ import * as deployment from '../src/utilities/strategy-helpers/deployment-helper
import * as fs from 'fs';
import * as io from '@actions/io';
import * as toolCache from '@actions/tool-cache';
import * as util from 'util';
import * as fileHelper from '../src/utilities/files-helper';
import { getWorkflowAnnotationKeyLabel, getWorkflowAnnotationsJson } from '../src/constants';
import * as inputParam from '../src/input-parameters';
@ -23,6 +24,7 @@ const os = require("os");
const coreMock = mocked(core, true);
const ioMock = mocked(io, true);
const inputParamMock = mocked(inputParam, true);
const osMock = mocked(os, true);
const toolCacheMock = mocked(toolCache, true);
const fileUtility = mocked(fs, true);
@ -91,10 +93,15 @@ beforeEach(() => {
process.env['GITHUB_TOKEN'] = 'testToken';
})
test("setKubectlPath() - install a particular version", async () => {
test.each([
['arm', 'arm'],
['arm64', 'arm64'],
['x64', 'amd64']
])("setKubectlPath() - install a particular version on %s", async (osArch, kubectlArch) => {
const kubectlVersion = 'v1.18.0'
//Mocks
coreMock.getInput = jest.fn().mockReturnValue(kubectlVersion);
osMock.arch = jest.fn().mockReturnValue(osArch);
toolCacheMock.find = jest.fn().mockReturnValue(undefined);
toolCacheMock.downloadTool = jest.fn().mockReturnValue('downloadpath');
toolCacheMock.cacheFile = jest.fn().mockReturnValue('cachepath');
@ -103,7 +110,7 @@ test("setKubectlPath() - install a particular version", async () => {
//Invoke and assert
await expect(action.run()).resolves.not.toThrow();
expect(toolCacheMock.find).toBeCalledWith('kubectl', kubectlVersion);
expect(toolCacheMock.downloadTool).toBeCalledWith(getkubectlDownloadURL(kubectlVersion));
expect(toolCacheMock.downloadTool).toBeCalledWith(getkubectlDownloadURL(kubectlVersion, kubectlArch));
});
test("setKubectlPath() - install a latest version", async () => {
@ -394,4 +401,19 @@ test("utility - getWorkflowFilePath() - Get workflow file path under API failure
//Invoke and assert
await expect(utility.getWorkflowFilePath(process.env.GITHUB_TOKEN)).resolves.not.toThrowError;
await expect(utility.getWorkflowFilePath(process.env.GITHUB_TOKEN)).resolves.toBe(process.env.GITHUB_WORKFLOW);
});
});
test("action - run() - Throw kubectl error on 404 response", async () => {
const kubectlVersion = 'v1.18.0'
const arch = 'arm128';
// Mock
coreMock.getInput = jest.fn().mockReturnValue(kubectlVersion);
osMock.arch = jest.fn().mockReturnValue(arch);
toolCacheMock.find = jest.fn().mockReturnValue(undefined);
toolCacheMock.downloadTool = jest.fn().mockImplementation(_ => {
throw new toolCache.HTTPError(httpClient.StatusCodes.NOT_FOUND);
});
//Invoke and assert
await expect(action.run()).rejects.toThrow(util.format("Kubectl '%s' for '%s' arch not found.", kubectlVersion, arch));
});

Просмотреть файл

@ -16,6 +16,7 @@ const os = require("os");
const path = require("path");
const toolCache = require("@actions/tool-cache");
const util = require("util");
const httpClient_1 = require("./httpClient");
const kubectlToolName = 'kubectl';
const stableKubectlVersion = 'v1.15.0';
const stableVersionUrl = 'https://storage.googleapis.com/kubernetes-release/release/stable.txt';
@ -26,15 +27,22 @@ function getExecutableExtension() {
}
return '';
}
function getkubectlDownloadURL(version) {
function getKubectlArch() {
let arch = os.arch();
if (arch === 'x64') {
return 'amd64';
}
return arch;
}
function getkubectlDownloadURL(version, arch) {
switch (os.type()) {
case 'Linux':
return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/linux/amd64/kubectl', version);
return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/linux/%s/kubectl', version, arch);
case 'Darwin':
return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/darwin/amd64/kubectl', version);
return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/darwin/%s/kubectl', version, arch);
case 'Windows_NT':
default:
return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/windows/amd64/kubectl.exe', version);
return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/windows/%s/kubectl.exe', version, arch);
}
}
exports.getkubectlDownloadURL = getkubectlDownloadURL;
@ -58,12 +66,18 @@ function downloadKubectl(version) {
return __awaiter(this, void 0, void 0, function* () {
let cachedToolpath = toolCache.find(kubectlToolName, version);
let kubectlDownloadPath = '';
let arch = getKubectlArch();
if (!cachedToolpath) {
try {
kubectlDownloadPath = yield toolCache.downloadTool(getkubectlDownloadURL(version));
kubectlDownloadPath = yield toolCache.downloadTool(getkubectlDownloadURL(version, arch));
}
catch (exception) {
throw new Error('DownloadKubectlFailed');
if (exception instanceof toolCache.HTTPError && exception.httpStatusCode === httpClient_1.StatusCodes.NOT_FOUND) {
throw new Error(util.format("Kubectl '%s' for '%s' arch not found.", version, arch));
}
else {
throw new Error('DownloadKubectlFailed');
}
}
cachedToolpath = yield toolCache.cacheFile(kubectlDownloadPath, kubectlToolName + getExecutableExtension(), kubectlToolName, version);
}

Просмотреть файл

@ -6,6 +6,7 @@ import * as toolCache from '@actions/tool-cache';
import * as util from 'util';
import { Kubectl } from '../kubectl-object-model';
import { StatusCodes } from "./httpClient"
const kubectlToolName = 'kubectl';
const stableKubectlVersion = 'v1.15.0';
@ -19,17 +20,25 @@ function getExecutableExtension(): string {
return '';
}
export function getkubectlDownloadURL(version: string): string {
function getKubectlArch(): string {
let arch = os.arch();
if (arch === 'x64') {
return 'amd64';
}
return arch;
}
export function getkubectlDownloadURL(version: string, arch: string): string {
switch (os.type()) {
case 'Linux':
return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/linux/amd64/kubectl', version);
return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/linux/%s/kubectl', version, arch);
case 'Darwin':
return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/darwin/amd64/kubectl', version);
return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/darwin/%s/kubectl', version, arch);
case 'Windows_NT':
default:
return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/windows/amd64/kubectl.exe', version);
return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/windows/%s/kubectl.exe', version, arch);
}
}
@ -51,11 +60,16 @@ export async function getStableKubectlVersion(): Promise<string> {
export async function downloadKubectl(version: string): Promise<string> {
let cachedToolpath = toolCache.find(kubectlToolName, version);
let kubectlDownloadPath = '';
let arch = getKubectlArch();
if (!cachedToolpath) {
try {
kubectlDownloadPath = await toolCache.downloadTool(getkubectlDownloadURL(version));
kubectlDownloadPath = await toolCache.downloadTool(getkubectlDownloadURL(version, arch));
} catch (exception) {
throw new Error('DownloadKubectlFailed');
if (exception instanceof toolCache.HTTPError && exception.httpStatusCode === StatusCodes.NOT_FOUND) {
throw new Error(util.format("Kubectl '%s' for '%s' arch not found.", version, arch));
} else {
throw new Error('DownloadKubectlFailed');
}
}
cachedToolpath = await toolCache.cacheFile(kubectlDownloadPath, kubectlToolName + getExecutableExtension(), kubectlToolName, version);