diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..21217c77 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,20 @@ +name: "build-test" +on: # rebuild any PRs and main branch changes + pull_request: + branches: + - master + - 'releases/*' + push: + branches: + - master + - 'releases/*' + +jobs: + build: # make sure build/ci works properly + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - run: | + npm install + npm build + npm test \ No newline at end of file diff --git a/.gitignore b/.gitignore index ddea9084..d109d827 100644 --- a/.gitignore +++ b/.gitignore @@ -327,3 +327,4 @@ ASALocalRun/ # MFractors (Xamarin productivity tool) working folder .mfractor/ +node_modules diff --git a/__tests__/manifests/deployment.yml b/__tests__/manifests/deployment.yml new file mode 100644 index 00000000..791154a2 --- /dev/null +++ b/__tests__/manifests/deployment.yml @@ -0,0 +1,16 @@ +apiVersion : apps/v1beta1 +kind: Deployment +metadata: + name: testapp +spec: + replicas: 1 + template: + metadata: + labels: + app: testapp + spec: + containers: + - name: testapp + image: testcr.azurecr.io/testapp + ports: + - containerPort: 80 \ No newline at end of file diff --git a/__tests__/run.test.ts b/__tests__/run.test.ts new file mode 100644 index 00000000..fcd2633b --- /dev/null +++ b/__tests__/run.test.ts @@ -0,0 +1,196 @@ +import * as KubernetesManifestUtility from '../src/utilities/manifest-stability-utility'; +import * as KubernetesObjectUtility from '../src/utilities/resource-object-utility'; +import * as action from '../src/run'; +import * as core from '@actions/core'; +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 { Kubectl, Resource } from '../src/kubectl-object-model'; + +import { getkubectlDownloadURL } from "../src/utilities/kubectl-util"; +import { mocked } from 'ts-jest/utils'; + +var path = require('path'); + +const coreMock = mocked(core, true); +const ioMock = mocked(io, true); + +const toolCacheMock = mocked(toolCache, true); +const fileUtility = mocked(fs, true); + +const stableVersionUrl = 'https://storage.googleapis.com/kubernetes-release/release/stable.txt'; + +var deploymentYaml = ""; + +beforeAll(() => { + deploymentYaml = fs.readFileSync(path.join(__dirname, 'manifests', 'deployment.yml'), 'utf8'); + process.env["KUBECONFIG"] = 'kubeConfig'; +}) + +test("setKubectlPath() - install a particular version", async () => { + const kubectlVersion = 'v1.18.0' + //Mocks + coreMock.getInput = jest.fn().mockReturnValue(kubectlVersion); + toolCacheMock.find = jest.fn().mockReturnValue(undefined); + toolCacheMock.downloadTool = jest.fn().mockReturnValue('downloadpath'); + toolCacheMock.cacheFile = jest.fn().mockReturnValue('cachepath'); + fileUtility.chmodSync = jest.fn(); + + //Invoke and assert + await expect(action.run()).resolves.not.toThrow(); + expect(toolCacheMock.find).toBeCalledWith('kubectl', kubectlVersion); + expect(toolCacheMock.downloadTool).toBeCalledWith(getkubectlDownloadURL(kubectlVersion)); +}); + +test("setKubectlPath() - install a latest version", async () => { + const kubectlVersion = 'latest' + //Mocks + coreMock.getInput = jest.fn().mockReturnValue(kubectlVersion); + jest.spyOn(fs, 'readFileSync').mockImplementation(() => ""); + toolCacheMock.find = jest.fn().mockReturnValue(undefined); + toolCacheMock.downloadTool = jest.fn().mockResolvedValue(''); + toolCacheMock.cacheFile = jest.fn().mockReturnValue('cachepath'); + fileUtility.chmodSync = jest.fn(); + + //Invoke and assert + await expect(action.run()).resolves.not.toThrow(); + expect(toolCacheMock.find).toBeCalledWith('kubectl', kubectlVersion); + expect(toolCacheMock.downloadTool).toBeCalledWith(stableVersionUrl); + +}); + +test("setKubectlPath() - kubectl version already avilable", async () => { + const kubectlVersion = 'v1.18.0' + //Mock + coreMock.getInput = jest.fn().mockReturnValue(kubectlVersion); + toolCacheMock.find = jest.fn().mockReturnValue('validPath'); + toolCacheMock.downloadTool = jest.fn().mockReturnValue('downloadpath'); + toolCacheMock.cacheFile = jest.fn().mockReturnValue('cachepath'); + fileUtility.chmodSync = jest.fn(); + + //Invoke and assert + await expect(action.run()).resolves.not.toThrow(); + expect(toolCacheMock.find).toBeCalledWith('kubectl', kubectlVersion); + expect(toolCacheMock.downloadTool).toBeCalledTimes(0); +}); + +test("setKubectlPath() - kubectl version not provided and kubectl avilable on machine", async () => { + //Mock + coreMock.getInput = jest.fn().mockReturnValue(undefined); + ioMock.which = jest.fn().mockReturnValue('validPath'); + + //Invoke and assert + await expect(action.run()).resolves.not.toThrow(); + expect(ioMock.which).toBeCalledWith('kubectl', false); + expect(toolCacheMock.downloadTool).toBeCalledTimes(0); +}); + +test("setKubectlPath() - kubectl version not provided and kubectl not avilable on machine", async () => { + //Mock + coreMock.getInput = jest.fn().mockReturnValue(undefined); + ioMock.which = jest.fn().mockReturnValue(undefined); + toolCacheMock.findAllVersions = jest.fn().mockReturnValue(undefined); + + //Invoke and assert + await expect(action.run()).rejects.toThrowError(); + expect(ioMock.which).toBeCalledWith('kubectl', false); +}); + +test("run() - action not provided", async () => { + const kubectlVersion = 'v1.18.0' + coreMock.getInput = jest.fn().mockImplementation((name) => { + if (name == 'action') { + return undefined; + } + return kubectlVersion; + }); + coreMock.setFailed = jest.fn(); + //Mocks + toolCacheMock.find = jest.fn().mockReturnValue(undefined); + toolCacheMock.downloadTool = jest.fn().mockReturnValue('downloadpath'); + toolCacheMock.cacheFile = jest.fn().mockReturnValue('cachepath'); + fileUtility.chmodSync = jest.fn(); + + //Invoke and assert + await expect(action.run()).resolves.not.toThrow(); + expect(coreMock.setFailed).toBeCalledWith('Not a valid action. The allowed actions are deploy, promote, reject'); +}); + +test("run() - deploy - Manifiest not provided", async () => { + //Mocks + const kubectlVersion = 'v1.18.0' + coreMock.getInput = jest.fn().mockImplementation((name) => { + if (name == 'manifests') { + return undefined; + } + if (name == 'action') { + return 'deploy'; + } + return kubectlVersion; + }); + coreMock.setFailed = jest.fn(); + toolCacheMock.find = jest.fn().mockReturnValue(undefined); + toolCacheMock.downloadTool = jest.fn().mockReturnValue('downloadpath'); + toolCacheMock.cacheFile = jest.fn().mockReturnValue('cachepath'); + fileUtility.chmodSync = jest.fn(); + + //Invoke and assert + await expect(action.run()).rejects.toThrowError(); + expect(coreMock.setFailed).toBeCalledWith('No manifests supplied to deploy'); +}); + +test("deployment - deploy() - Invokes with no manifestfiles", async () => { + const kubeCtl: jest.Mocked = new Kubectl("") as any; + + //Invoke and assert + await expect(deployment.deploy(kubeCtl, [], undefined)).rejects.toThrowError('ManifestFileNotFound'); +}); + +test("run() - deploy", async () => { + const kubectlVersion = 'v1.18.0' + //Mocks + coreMock.getInput = jest.fn().mockImplementation((name) => { + if (name == 'manifests') { + return 'manifests/deployment.yaml'; + } + if (name == 'action') { + return 'deploy'; + } + if (name == 'strategy') { + return undefined; + } + return kubectlVersion; + }); + + coreMock.setFailed = jest.fn(); + toolCacheMock.find = jest.fn().mockReturnValue('validPath'); + toolCacheMock.downloadTool = jest.fn().mockReturnValue('downloadpath'); + toolCacheMock.cacheFile = jest.fn().mockReturnValue('cachepath'); + fileUtility.chmodSync = jest.fn(); + const deploySpy = jest.spyOn(deployment, 'deploy').mockImplementation(); + + //Invoke and assert + await expect(action.run()).resolves.not.toThrow(); + expect(deploySpy).toBeCalledWith({ "ignoreSSLErrors": false, "kubectlPath": 'validPath', "namespace": "v1.18.0" }, ['manifests/deployment.yaml'], undefined); + deploySpy.mockRestore(); +}); + +test("deployment - deploy() - Invokes with manifestfiles", async () => { + const KubernetesManifestUtilityMock = mocked(KubernetesManifestUtility, true); + const KubernetesObjectUtilityMock = mocked(KubernetesObjectUtility, true); + const kubeCtl: jest.Mocked = new Kubectl("") as any; + kubeCtl.apply = jest.fn().mockReturnValue(""); + const resources: Resource[] = [{ type: "Deployment", name: "AppName" }]; + KubernetesObjectUtilityMock.getResources = jest.fn().mockReturnValue(resources); + kubeCtl.getResource = jest.fn().mockReturnValue(""); + KubernetesManifestUtilityMock.checkManifestStability = jest.fn().mockReturnValue(""); + + const readFileSpy = jest.spyOn(fs, 'readFileSync').mockImplementation(() => deploymentYaml); + + //Invoke and assert + await expect(deployment.deploy(kubeCtl, ['manifests/deployment.yaml'], undefined)).resolves.not.toThrowError(); + expect(readFileSpy).toBeCalledWith("manifests/deployment.yaml"); + expect(kubeCtl.getResource).toBeCalledWith("ingress", "AppName"); +}); \ No newline at end of file diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..45ff45ec --- /dev/null +++ b/jest.config.js @@ -0,0 +1,10 @@ +module.exports = { + clearMocks: true, + moduleFileExtensions: ['js', 'ts'], + testEnvironment: 'node', + testMatch: ['**/*.test.ts'], + transform: { + '^.+\\.ts$': 'ts-jest' + }, + verbose: true + } \ No newline at end of file diff --git a/lib/actions/promote.js b/lib/actions/promote.js index 2bdf58c9..50e3fd05 100644 --- a/lib/actions/promote.js +++ b/lib/actions/promote.js @@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.promote = void 0; const core = require("@actions/core"); const deploymentHelper = require("../utilities/strategy-helpers/deployment-helper"); const canaryDeploymentHelper = require("../utilities/strategy-helpers/canary-deployment-helper"); diff --git a/lib/actions/reject.js b/lib/actions/reject.js index d3177ef6..cb0d73ee 100644 --- a/lib/actions/reject.js +++ b/lib/actions/reject.js @@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.reject = void 0; const core = require("@actions/core"); const canaryDeploymentHelper = require("../utilities/strategy-helpers/canary-deployment-helper"); const SMICanaryDeploymentHelper = require("../utilities/strategy-helpers/smi-canary-deployment-helper"); diff --git a/lib/constants.js b/lib/constants.js index 50919389..31ea7d3d 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -1,26 +1,36 @@ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); -class KubernetesWorkload { -} +exports.workloadTypesWithRolloutStatus = exports.workloadTypes = exports.deploymentTypes = exports.ServiceTypes = exports.DiscoveryAndLoadBalancerResource = exports.KubernetesWorkload = void 0; +let KubernetesWorkload = /** @class */ (() => { + class KubernetesWorkload { + } + KubernetesWorkload.pod = 'Pod'; + KubernetesWorkload.replicaset = 'Replicaset'; + KubernetesWorkload.deployment = 'Deployment'; + KubernetesWorkload.statefulSet = 'StatefulSet'; + KubernetesWorkload.daemonSet = 'DaemonSet'; + KubernetesWorkload.job = 'job'; + KubernetesWorkload.cronjob = 'cronjob'; + return KubernetesWorkload; +})(); exports.KubernetesWorkload = KubernetesWorkload; -KubernetesWorkload.pod = 'Pod'; -KubernetesWorkload.replicaset = 'Replicaset'; -KubernetesWorkload.deployment = 'Deployment'; -KubernetesWorkload.statefulSet = 'StatefulSet'; -KubernetesWorkload.daemonSet = 'DaemonSet'; -KubernetesWorkload.job = 'job'; -KubernetesWorkload.cronjob = 'cronjob'; -class DiscoveryAndLoadBalancerResource { -} +let DiscoveryAndLoadBalancerResource = /** @class */ (() => { + class DiscoveryAndLoadBalancerResource { + } + DiscoveryAndLoadBalancerResource.service = 'service'; + DiscoveryAndLoadBalancerResource.ingress = 'ingress'; + return DiscoveryAndLoadBalancerResource; +})(); exports.DiscoveryAndLoadBalancerResource = DiscoveryAndLoadBalancerResource; -DiscoveryAndLoadBalancerResource.service = 'service'; -DiscoveryAndLoadBalancerResource.ingress = 'ingress'; -class ServiceTypes { -} +let ServiceTypes = /** @class */ (() => { + class ServiceTypes { + } + ServiceTypes.loadBalancer = 'LoadBalancer'; + ServiceTypes.nodePort = 'NodePort'; + ServiceTypes.clusterIP = 'ClusterIP'; + return ServiceTypes; +})(); exports.ServiceTypes = ServiceTypes; -ServiceTypes.loadBalancer = 'LoadBalancer'; -ServiceTypes.nodePort = 'NodePort'; -ServiceTypes.clusterIP = 'ClusterIP'; exports.deploymentTypes = ['deployment', 'replicaset', 'daemonset', 'pod', 'statefulset']; exports.workloadTypes = ['deployment', 'replicaset', 'daemonset', 'pod', 'statefulset', 'job', 'cronjob']; exports.workloadTypesWithRolloutStatus = ['deployment', 'daemonset', 'statefulset']; diff --git a/lib/input-parameters.js b/lib/input-parameters.js index 63869312..c4903363 100644 --- a/lib/input-parameters.js +++ b/lib/input-parameters.js @@ -1,5 +1,6 @@ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); +exports.args = exports.baselineAndCanaryReplicas = exports.trafficSplitMethod = exports.deploymentStrategy = exports.canaryPercentage = exports.manifests = exports.imagePullSecrets = exports.containers = exports.namespace = void 0; const core = require("@actions/core"); exports.namespace = core.getInput('namespace'); exports.containers = core.getInput('images').split('\n'); diff --git a/lib/kubectl-object-model.js b/lib/kubectl-object-model.js index 9effab10..e8687466 100644 --- a/lib/kubectl-object-model.js +++ b/lib/kubectl-object-model.js @@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.Kubectl = void 0; const tool_runner_1 = require("./utilities/tool-runner"); class Kubectl { constructor(kubectlPath, namespace, ignoreSSLErrors) { diff --git a/lib/run.js b/lib/run.js index af12fe7a..ebcb91e7 100644 --- a/lib/run.js +++ b/lib/run.js @@ -9,16 +9,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); -const toolCache = require("@actions/tool-cache"); +exports.run = void 0; const core = require("@actions/core"); const io = require("@actions/io"); const path = require("path"); -const utility_1 = require("./utilities/utility"); +const toolCache = require("@actions/tool-cache"); const kubectl_util_1 = require("./utilities/kubectl-util"); +const utility_1 = require("./utilities/utility"); +const kubectl_object_model_1 = require("./kubectl-object-model"); const deployment_helper_1 = require("./utilities/strategy-helpers/deployment-helper"); const promote_1 = require("./actions/promote"); const reject_1 = require("./actions/reject"); -const kubectl_object_model_1 = require("./kubectl-object-model"); let kubectlPath = ""; function setKubectlPath() { return __awaiter(this, void 0, void 0, function* () { @@ -68,7 +69,7 @@ function run() { namespace = 'default'; } let action = core.getInput('action'); - let manifests = manifestsInput.split('\n'); + let manifests = manifestsInput ? manifestsInput.split('\n') : undefined; if (action === 'deploy') { let strategy = core.getInput('strategy'); console.log("strategy: ", strategy); @@ -85,4 +86,5 @@ function run() { } }); } +exports.run = run; run().catch(core.setFailed); diff --git a/lib/utilities/files-helper.js b/lib/utilities/files-helper.js index b7cd2754..4b9ecc81 100644 --- a/lib/utilities/files-helper.js +++ b/lib/utilities/files-helper.js @@ -1,5 +1,6 @@ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); +exports.writeManifestToFile = exports.writeObjectsToFile = exports.assertFileExists = exports.ensureDirExists = exports.getNewUserDirPath = exports.getTempDirectory = void 0; const fs = require("fs"); const path = require("path"); const core = require("@actions/core"); diff --git a/lib/utilities/kubectl-util.js b/lib/utilities/kubectl-util.js index 720f3589..a5bbcb63 100644 --- a/lib/utilities/kubectl-util.js +++ b/lib/utilities/kubectl-util.js @@ -9,12 +9,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.getTrafficSplitAPIVersion = exports.downloadKubectl = exports.getStableKubectlVersion = exports.getkubectlDownloadURL = void 0; +const core = require("@actions/core"); +const fs = require("fs"); const os = require("os"); const path = require("path"); -const util = require("util"); -const fs = require("fs"); const toolCache = require("@actions/tool-cache"); -const core = require("@actions/core"); +const util = require("util"); const kubectlToolName = 'kubectl'; const stableKubectlVersion = 'v1.15.0'; const stableVersionUrl = 'https://storage.googleapis.com/kubernetes-release/release/stable.txt'; @@ -36,6 +37,7 @@ function getkubectlDownloadURL(version) { return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/windows/amd64/kubectl.exe', version); } } +exports.getkubectlDownloadURL = getkubectlDownloadURL; function getStableKubectlVersion() { return __awaiter(this, void 0, void 0, function* () { return toolCache.downloadTool(stableVersionUrl).then((downloadPath) => { diff --git a/lib/utilities/manifest-stability-utility.js b/lib/utilities/manifest-stability-utility.js index c5cd5013..778219a7 100644 --- a/lib/utilities/manifest-stability-utility.js +++ b/lib/utilities/manifest-stability-utility.js @@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.checkPodStatus = exports.checkManifestStability = void 0; const core = require("@actions/core"); const utils = require("./utility"); const KubernetesConstants = require("../constants"); diff --git a/lib/utilities/manifest-utilities.js b/lib/utilities/manifest-utilities.js index 04f29ff8..0237cdc4 100644 --- a/lib/utilities/manifest-utilities.js +++ b/lib/utilities/manifest-utilities.js @@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.isWorkloadEntity = exports.updateImagePullSecrets = exports.updateContainerImagesInManifestFiles = exports.substituteImageNameInSpecFile = exports.getDeleteCmdArgs = exports.createKubectlArgs = exports.getKubectl = exports.getManifestFiles = void 0; const core = require("@actions/core"); const kubectlutility = require("./kubectl-util"); const io = require("@actions/io"); diff --git a/lib/utilities/resource-object-utility.js b/lib/utilities/resource-object-utility.js index 14c7f740..ebb7e564 100644 --- a/lib/utilities/resource-object-utility.js +++ b/lib/utilities/resource-object-utility.js @@ -1,5 +1,6 @@ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); +exports.getResources = exports.updateSelectorLabels = exports.updateSpecLabels = exports.updateImageDetails = exports.updateImagePullSecrets = exports.updateObjectLabels = exports.getReplicaCount = exports.isServiceEntity = exports.isWorkloadEntity = exports.isDeploymentEntity = void 0; const fs = require("fs"); const core = require("@actions/core"); const yaml = require("js-yaml"); diff --git a/lib/utilities/strategy-helpers/canary-deployment-helper.js b/lib/utilities/strategy-helpers/canary-deployment-helper.js index d8c5cb91..7df15ce1 100644 --- a/lib/utilities/strategy-helpers/canary-deployment-helper.js +++ b/lib/utilities/strategy-helpers/canary-deployment-helper.js @@ -1,5 +1,6 @@ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); +exports.getStableResourceName = exports.getBaselineResourceName = exports.getCanaryResourceName = exports.isSMICanaryStrategy = exports.isCanaryDeploymentStrategy = exports.fetchResource = exports.fetchCanaryResource = exports.getNewCanaryResource = exports.getNewBaselineResource = exports.getStableResource = exports.isResourceMarkedAsStable = exports.markResourceAsStable = exports.deleteCanaryDeployment = exports.STABLE_LABEL_VALUE = exports.STABLE_SUFFIX = exports.CANARY_LABEL_VALUE = exports.BASELINE_LABEL_VALUE = exports.CANARY_VERSION_LABEL = exports.TRAFFIC_SPLIT_STRATEGY = exports.CANARY_DEPLOYMENT_STRATEGY = void 0; const fs = require("fs"); const yaml = require("js-yaml"); const core = require("@actions/core"); diff --git a/lib/utilities/strategy-helpers/deployment-helper.js b/lib/utilities/strategy-helpers/deployment-helper.js index a880bd9c..a2e242cd 100644 --- a/lib/utilities/strategy-helpers/deployment-helper.js +++ b/lib/utilities/strategy-helpers/deployment-helper.js @@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.deploy = void 0; const fs = require("fs"); const core = require("@actions/core"); const yaml = require("js-yaml"); diff --git a/lib/utilities/strategy-helpers/pod-canary-deployment-helper.js b/lib/utilities/strategy-helpers/pod-canary-deployment-helper.js index 3a66581a..4e0ae883 100644 --- a/lib/utilities/strategy-helpers/pod-canary-deployment-helper.js +++ b/lib/utilities/strategy-helpers/pod-canary-deployment-helper.js @@ -1,5 +1,6 @@ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); +exports.deployPodCanary = void 0; const core = require("@actions/core"); const fs = require("fs"); const yaml = require("js-yaml"); diff --git a/lib/utilities/strategy-helpers/smi-canary-deployment-helper.js b/lib/utilities/strategy-helpers/smi-canary-deployment-helper.js index 4a871824..fd90abcb 100644 --- a/lib/utilities/strategy-helpers/smi-canary-deployment-helper.js +++ b/lib/utilities/strategy-helpers/smi-canary-deployment-helper.js @@ -1,5 +1,6 @@ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); +exports.redirectTrafficToStableDeployment = exports.redirectTrafficToCanaryDeployment = exports.deploySMICanary = void 0; const core = require("@actions/core"); const fs = require("fs"); const yaml = require("js-yaml"); diff --git a/lib/utilities/string-comparison.js b/lib/utilities/string-comparison.js index 5edaa9aa..9dd1b0a1 100644 --- a/lib/utilities/string-comparison.js +++ b/lib/utilities/string-comparison.js @@ -1,5 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +exports.isEqual = exports.StringComparer = void 0; var StringComparer; (function (StringComparer) { StringComparer[StringComparer["Ordinal"] = 0] = "Ordinal"; diff --git a/lib/utilities/tool-runner.js b/lib/utilities/tool-runner.js index cd46a5f5..e1ea302e 100644 --- a/lib/utilities/tool-runner.js +++ b/lib/utilities/tool-runner.js @@ -1,5 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +exports.ToolRunner = void 0; const os = require("os"); const events = require("events"); const child = require("child_process"); diff --git a/lib/utilities/utility.js b/lib/utilities/utility.js index 35b79737..db0543a5 100644 --- a/lib/utilities/utility.js +++ b/lib/utilities/utility.js @@ -1,5 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +exports.getCurrentTime = exports.getRandomInt = exports.sleep = exports.checkForErrors = exports.isEqual = exports.getExecutableExtension = void 0; const os = require("os"); const core = require("@actions/core"); function getExecutableExtension() { diff --git a/package.json b/package.json index 66d2abfa..66c46c66 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "author": "Deepak Sattiraju", "license": "MIT", "scripts": { - "build": "tsc --outDir ./lib --rootDir ./src" + "build": "tsc --outDir ./lib --rootDir ./src", + "test": "jest" }, "dependencies": { "@actions/tool-cache": "^1.0.0", @@ -14,6 +15,10 @@ "js-yaml": "3.13.1" }, "devDependencies": { - "@types/node": "^12.0.10" + "@types/node": "^12.0.10", + "jest": "^25.0.0", + "@types/jest": "^25.2.2", + "ts-jest": "^25.5.1", + "typescript": "^3.9.2" } } diff --git a/src/run.ts b/src/run.ts index fbf5fe67..c36e5ba0 100644 --- a/src/run.ts +++ b/src/run.ts @@ -1,14 +1,15 @@ -import * as toolCache from '@actions/tool-cache'; import * as core from '@actions/core'; import * as io from '@actions/io'; import * as path from 'path'; +import * as toolCache from '@actions/tool-cache'; -import { getExecutableExtension, isEqual } from "./utilities/utility"; import { downloadKubectl, getStableKubectlVersion } from "./utilities/kubectl-util"; +import { getExecutableExtension, isEqual } from "./utilities/utility"; + +import { Kubectl } from './kubectl-object-model'; import { deploy } from './utilities/strategy-helpers/deployment-helper'; import { promote } from './actions/promote'; import { reject } from './actions/reject'; -import { Kubectl } from './kubectl-object-model'; let kubectlPath = ""; @@ -45,7 +46,7 @@ function checkClusterContext() { } } -async function run() { +export async function run() { checkClusterContext(); await setKubectlPath(); let manifestsInput = core.getInput('manifests'); @@ -57,7 +58,7 @@ async function run() { namespace = 'default'; } let action = core.getInput('action'); - let manifests = manifestsInput.split('\n'); + let manifests = manifestsInput ? manifestsInput.split('\n') : undefined; if (action === 'deploy') { let strategy = core.getInput('strategy'); diff --git a/src/utilities/kubectl-util.ts b/src/utilities/kubectl-util.ts index 64a8ee71..11b202ec 100644 --- a/src/utilities/kubectl-util.ts +++ b/src/utilities/kubectl-util.ts @@ -1,10 +1,10 @@ +import * as core from '@actions/core'; +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 util from 'util'; + import { Kubectl } from '../kubectl-object-model'; const kubectlToolName = 'kubectl'; @@ -19,7 +19,7 @@ function getExecutableExtension(): string { return ''; } -function getkubectlDownloadURL(version: string): string { +export function getkubectlDownloadURL(version: string): string { switch (os.type()) { case 'Linux': return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/linux/amd64/kubectl', version); diff --git a/tsconfig.json b/tsconfig.json index 7a5d8bef..3555b597 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,6 +4,7 @@ "module": "commonjs" }, "exclude": [ - "node_modules" + "node_modules", + "__tests__" ] } \ No newline at end of file