Compare commits

...

1 commit
v5.0.0 ... main

Author SHA1 Message Date
David Gamero
1e2e44e1bc
Migrate to ESM with esbuild/vitest and upgrade to node24 (#260)
Some checks failed
Run prettify / Prettier Check (push) Has been cancelled
Run unit tests. / build (macos-latest) (push) Has been cancelled
Run unit tests. / build (ubuntu-24.04-arm) (push) Has been cancelled
Run unit tests. / build (ubuntu-latest) (push) Has been cancelled
Run unit tests. / build (windows-11-arm) (push) Has been cancelled
Run unit tests. / build (windows-latest) (push) Has been cancelled
- Add "type": "module" to package.json for ESM support
- Replace ncc with esbuild for bundling (with createRequire banner for CJS compat)
- Replace jest/ts-jest with vitest for testing
- Upgrade @actions/core to ^3.0.0, @actions/exec to ^3.0.0, @actions/io to ^3.0.2, @actions/tool-cache to 4.0.0 (ESM-only versions)
- Update tsconfig.json to use NodeNext module resolution
- Convert all tests to use vi.mock() factory pattern for ESM-only module compatibility
- Update action.yml runtime from node20 to node24
- Bump version from 4.3.1 to 5.0.0 (major version bump for breaking node runtime change)
2026-03-24 10:46:19 -07:00
8 changed files with 1682 additions and 4424 deletions

View file

@ -1,18 +0,0 @@
module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.ts$': 'ts-jest'
},
verbose: true,
coverageThreshold: {
global: {
branches: 0,
functions: 14,
lines: 27,
statements: 27
}
}
}

5779
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -5,31 +5,31 @@
"description": "Setup helm", "description": "Setup helm",
"author": "Anumita Shenoy", "author": "Anumita Shenoy",
"license": "MIT", "license": "MIT",
"type": "module",
"dependencies": { "dependencies": {
"@actions/core": "^2.0.2", "@actions/core": "^3.0.0",
"@actions/exec": "^2.0.0", "@actions/exec": "^3.0.0",
"@actions/io": "^2.0.0", "@actions/io": "^3.0.2",
"@actions/tool-cache": "3.0.0", "@actions/tool-cache": "4.0.0",
"@octokit/action": "^8.0.4", "@octokit/action": "^8.0.4",
"semver": "^7.7.3" "semver": "^7.7.3"
}, },
"main": "lib/index.js", "main": "lib/index.js",
"scripts": { "scripts": {
"build": "ncc build src/index.ts -o lib", "build": "tsc --noEmit && esbuild src/index.ts --bundle --platform=node --target=node20 --format=esm --outfile=lib/index.js --banner:js=\"import { createRequire } from 'module';const require = createRequire(import.meta.url);\"",
"test": "jest", "typecheck": "tsc --noEmit",
"test-coverage": "jest --coverage", "test": "vitest run",
"test-coverage": "vitest run --coverage",
"format": "prettier --write .", "format": "prettier --write .",
"format-check": "prettier --check .", "format-check": "prettier --check .",
"prepare": "husky" "prepare": "husky"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^30.0.0",
"@types/node": "^25.0.9", "@types/node": "^25.0.9",
"@vercel/ncc": "^0.38.4", "esbuild": "^0.27",
"husky": "^9.1.7", "husky": "^9.1.7",
"jest": "^30.2.0",
"prettier": "^3.8.0", "prettier": "^3.8.0",
"ts-jest": "^29.4.6", "typescript": "^5.9.3",
"typescript": "^5.9.3" "vitest": "^4"
} }
} }

View file

@ -1,4 +1,4 @@
import {run} from './run' import {run} from './run.js'
import * as core from '@actions/core' import * as core from '@actions/core'
run().catch(core.setFailed) run().catch(core.setFailed)

View file

@ -1,8 +1,62 @@
import * as run from './run' import {vi, describe, test, expect, afterEach} from 'vitest'
import * as path from 'path'
// Mock os module
vi.mock('os', async (importOriginal) => {
const actual = await importOriginal<typeof import('os')>()
return {
...actual,
platform: vi.fn(),
arch: vi.fn()
}
})
// Mock fs module
vi.mock('fs', async (importOriginal) => {
const actual = await importOriginal<typeof import('fs')>()
return {
...actual,
readdirSync: vi.fn(),
statSync: vi.fn(),
chmodSync: vi.fn(),
readFileSync: vi.fn()
}
})
// Mock @actions/core
vi.mock('@actions/core', async (importOriginal) => {
const actual = await importOriginal<typeof import('@actions/core')>()
return {
...actual,
getInput: vi.fn(),
info: vi.fn(),
debug: vi.fn(),
warning: vi.fn(),
startGroup: vi.fn(),
endGroup: vi.fn(),
addPath: vi.fn(),
setOutput: vi.fn(),
setFailed: vi.fn()
}
})
// Mock @actions/tool-cache
vi.mock('@actions/tool-cache', async (importOriginal) => {
const actual = await importOriginal<typeof import('@actions/tool-cache')>()
return {
...actual,
find: vi.fn(),
downloadTool: vi.fn(),
extractZip: vi.fn(),
extractTar: vi.fn(),
cacheDir: vi.fn()
}
})
import * as run from './run.js'
import * as os from 'os' import * as os from 'os'
import * as toolCache from '@actions/tool-cache' import * as toolCache from '@actions/tool-cache'
import * as fs from 'fs' import * as fs from 'fs'
import * as path from 'path'
import * as core from '@actions/core' import * as core from '@actions/core'
describe('run.ts', () => { describe('run.ts', () => {
@ -10,26 +64,26 @@ describe('run.ts', () => {
// Cleanup mocks after each test to ensure that subsequent tests are not affected by the mocks. // Cleanup mocks after each test to ensure that subsequent tests are not affected by the mocks.
afterEach(() => { afterEach(() => {
jest.restoreAllMocks() vi.restoreAllMocks()
}) })
test('getExecutableExtension() - return .exe when os is Windows', () => { test('getExecutableExtension() - return .exe when os is Windows', () => {
jest.spyOn(os, 'platform').mockReturnValue('win32') vi.mocked(os.platform).mockReturnValue('win32')
expect(run.getExecutableExtension()).toBe('.exe') expect(run.getExecutableExtension()).toBe('.exe')
expect(os.platform).toHaveBeenCalled() expect(os.platform).toHaveBeenCalled()
}) })
test('getExecutableExtension() - return empty string for non-windows OS', () => { test('getExecutableExtension() - return empty string for non-windows OS', () => {
jest.spyOn(os, 'platform').mockReturnValue('darwin') vi.mocked(os.platform).mockReturnValue('darwin')
expect(run.getExecutableExtension()).toBe('') expect(run.getExecutableExtension()).toBe('')
expect(os.platform).toHaveBeenCalled() expect(os.platform).toHaveBeenCalled()
}) })
test('getHelmDownloadURL() - return the URL to download helm for Linux amd64', () => { test('getHelmDownloadURL() - return the URL to download helm for Linux amd64', () => {
jest.spyOn(os, 'platform').mockReturnValue('linux') vi.mocked(os.platform).mockReturnValue('linux')
jest.spyOn(os, 'arch').mockReturnValue('x64') vi.mocked(os.arch).mockReturnValue('x64')
const expected = 'https://test.tld/helm-v3.8.0-linux-amd64.tar.gz' const expected = 'https://test.tld/helm-v3.8.0-linux-amd64.tar.gz'
expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected) expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected)
@ -38,8 +92,8 @@ describe('run.ts', () => {
}) })
test('getHelmDownloadURL() - return the URL to download helm for Linux arm64', () => { test('getHelmDownloadURL() - return the URL to download helm for Linux arm64', () => {
jest.spyOn(os, 'platform').mockReturnValue('linux') vi.mocked(os.platform).mockReturnValue('linux')
jest.spyOn(os, 'arch').mockReturnValue('arm64') vi.mocked(os.arch).mockReturnValue('arm64')
const expected = 'https://test.tld/helm-v3.8.0-linux-arm64.tar.gz' const expected = 'https://test.tld/helm-v3.8.0-linux-arm64.tar.gz'
expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected) expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected)
@ -48,8 +102,8 @@ describe('run.ts', () => {
}) })
test('getHelmDownloadURL() - return the URL to download helm for Darwin x64', () => { test('getHelmDownloadURL() - return the URL to download helm for Darwin x64', () => {
jest.spyOn(os, 'platform').mockReturnValue('darwin') vi.mocked(os.platform).mockReturnValue('darwin')
jest.spyOn(os, 'arch').mockReturnValue('x64') vi.mocked(os.arch).mockReturnValue('x64')
const expected = 'https://test.tld/helm-v3.8.0-darwin-amd64.tar.gz' const expected = 'https://test.tld/helm-v3.8.0-darwin-amd64.tar.gz'
expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected) expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected)
@ -58,8 +112,8 @@ describe('run.ts', () => {
}) })
test('getHelmDownloadURL() - return the URL to download helm for Darwin arm64', () => { test('getHelmDownloadURL() - return the URL to download helm for Darwin arm64', () => {
jest.spyOn(os, 'platform').mockReturnValue('darwin') vi.mocked(os.platform).mockReturnValue('darwin')
jest.spyOn(os, 'arch').mockReturnValue('arm64') vi.mocked(os.arch).mockReturnValue('arm64')
const expected = 'https://test.tld/helm-v3.8.0-darwin-arm64.tar.gz' const expected = 'https://test.tld/helm-v3.8.0-darwin-arm64.tar.gz'
expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected) expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected)
@ -68,8 +122,8 @@ describe('run.ts', () => {
}) })
test('getHelmDownloadURL() - return the URL to download helm for Windows x64', () => { test('getHelmDownloadURL() - return the URL to download helm for Windows x64', () => {
jest.spyOn(os, 'platform').mockReturnValue('win32') vi.mocked(os.platform).mockReturnValue('win32')
jest.spyOn(os, 'arch').mockReturnValue('x64') vi.mocked(os.arch).mockReturnValue('x64')
const expected = 'https://test.tld/helm-v3.8.0-windows-amd64.zip' const expected = 'https://test.tld/helm-v3.8.0-windows-amd64.zip'
expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected) expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected)
@ -77,8 +131,8 @@ describe('run.ts', () => {
}) })
test('getHelmDownloadURL() - return the URL to download helm for Windows arm64', () => { test('getHelmDownloadURL() - return the URL to download helm for Windows arm64', () => {
jest.spyOn(os, 'platform').mockReturnValue('win32') vi.mocked(os.platform).mockReturnValue('win32')
jest.spyOn(os, 'arch').mockReturnValue('arm64') vi.mocked(os.arch).mockReturnValue('arm64')
const expected = 'https://test.tld/helm-v3.8.0-windows-arm64.zip' const expected = 'https://test.tld/helm-v3.8.0-windows-arm64.zip'
expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected) expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected)
@ -90,13 +144,16 @@ describe('run.ts', () => {
status: 200, status: 200,
text: async () => 'v9.99.999' text: async () => 'v9.99.999'
} as Response } as Response
global.fetch = jest.fn().mockReturnValue(res) vi.stubGlobal('fetch', vi.fn().mockReturnValue(res))
expect(await run.getLatestHelmVersion()).toBe('v9.99.999') expect(await run.getLatestHelmVersion()).toBe('v9.99.999')
}) })
test('getLatestHelmVersion() - return the stable version of HELM when simulating a network error', async () => { test('getLatestHelmVersion() - return the stable version of HELM when simulating a network error', async () => {
const errorMessage: string = 'Network Error' const errorMessage: string = 'Network Error'
global.fetch = jest.fn().mockRejectedValueOnce(new Error(errorMessage)) vi.stubGlobal(
'fetch',
vi.fn().mockRejectedValueOnce(new Error(errorMessage))
)
expect(await run.getLatestHelmVersion()).toBe(run.stableHelmVersion) expect(await run.getLatestHelmVersion()).toBe(run.stableHelmVersion)
}) })
@ -105,7 +162,7 @@ describe('run.ts', () => {
}) })
test('walkSync() - return path to the all files matching fileToFind in dir', () => { test('walkSync() - return path to the all files matching fileToFind in dir', () => {
jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => { vi.mocked(fs.readdirSync).mockImplementation((file, _?) => {
if (file == 'mainFolder') if (file == 'mainFolder')
return [ return [
'file1' as unknown as fs.Dirent<NonSharedBuffer>, 'file1' as unknown as fs.Dirent<NonSharedBuffer>,
@ -125,8 +182,7 @@ describe('run.ts', () => {
] ]
return [] return []
}) })
jest.spyOn(core, 'debug').mockImplementation() vi.mocked(fs.statSync).mockImplementation((file) => {
jest.spyOn(fs, 'statSync').mockImplementation((file) => {
const isDirectory = const isDirectory =
(file as string).toLowerCase().indexOf('file') == -1 ? true : false (file as string).toLowerCase().indexOf('file') == -1 ? true : false
return {isDirectory: () => isDirectory} as fs.Stats return {isDirectory: () => isDirectory} as fs.Stats
@ -140,7 +196,7 @@ describe('run.ts', () => {
}) })
test('walkSync() - return empty array if no file with name fileToFind exists', () => { test('walkSync() - return empty array if no file with name fileToFind exists', () => {
jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => { vi.mocked(fs.readdirSync).mockImplementation((file, _?) => {
if (file == 'mainFolder') if (file == 'mainFolder')
return [ return [
'file1' as unknown as fs.Dirent<NonSharedBuffer>, 'file1' as unknown as fs.Dirent<NonSharedBuffer>,
@ -160,8 +216,7 @@ describe('run.ts', () => {
] ]
return [] return []
}) })
jest.spyOn(core, 'debug').mockImplementation() vi.mocked(fs.statSync).mockImplementation((file) => {
jest.spyOn(fs, 'statSync').mockImplementation((file) => {
const isDirectory = const isDirectory =
(file as string).toLowerCase().indexOf('file') == -1 ? true : false (file as string).toLowerCase().indexOf('file') == -1 ? true : false
return {isDirectory: () => isDirectory} as fs.Stats return {isDirectory: () => isDirectory} as fs.Stats
@ -173,18 +228,18 @@ describe('run.ts', () => {
}) })
test('findHelm() - change access permissions and find the helm in given directory', () => { test('findHelm() - change access permissions and find the helm in given directory', () => {
jest.spyOn(fs, 'chmodSync').mockImplementation(() => {}) vi.mocked(fs.chmodSync).mockImplementation(() => {})
jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => { vi.mocked(fs.readdirSync).mockImplementation((file, _?) => {
if (file == 'mainFolder') if (file == 'mainFolder')
return ['helm.exe' as unknown as fs.Dirent<NonSharedBuffer>] return ['helm.exe' as unknown as fs.Dirent<NonSharedBuffer>]
return [] return []
}) })
jest.spyOn(fs, 'statSync').mockImplementation((file) => { vi.mocked(fs.statSync).mockImplementation((file) => {
const isDirectory = const isDirectory =
(file as string).indexOf('folder') == -1 ? false : true (file as string).indexOf('folder') == -1 ? false : true
return {isDirectory: () => isDirectory} as fs.Stats return {isDirectory: () => isDirectory} as fs.Stats
}) })
jest.spyOn(os, 'platform').mockReturnValue('win32') vi.mocked(os.platform).mockReturnValue('win32')
expect(run.findHelm('mainFolder')).toBe( expect(run.findHelm('mainFolder')).toBe(
path.join('mainFolder', 'helm.exe') path.join('mainFolder', 'helm.exe')
@ -192,15 +247,15 @@ describe('run.ts', () => {
}) })
test('findHelm() - throw error if executable not found', () => { test('findHelm() - throw error if executable not found', () => {
jest.spyOn(fs, 'chmodSync').mockImplementation(() => {}) vi.mocked(fs.chmodSync).mockImplementation(() => {})
jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => { vi.mocked(fs.readdirSync).mockImplementation((file, _?) => {
if (file == 'mainFolder') return [] if (file == 'mainFolder') return []
return [] return []
}) })
jest.spyOn(fs, 'statSync').mockImplementation((file) => { vi.mocked(fs.statSync).mockImplementation((file) => {
return {isDirectory: () => true} as fs.Stats return {isDirectory: () => true} as fs.Stats
}) })
jest.spyOn(os, 'platform').mockReturnValue('win32') vi.mocked(os.platform).mockReturnValue('win32')
expect(() => run.findHelm('mainFolder')).toThrow( expect(() => run.findHelm('mainFolder')).toThrow(
'Helm executable not found in path mainFolder' 'Helm executable not found in path mainFolder'
@ -208,21 +263,19 @@ describe('run.ts', () => {
}) })
test('downloadHelm() - download helm and return path to it', async () => { test('downloadHelm() - download helm and return path to it', async () => {
jest.spyOn(toolCache, 'find').mockReturnValue('') vi.mocked(toolCache.find).mockReturnValue('')
jest.spyOn(toolCache, 'downloadTool').mockResolvedValue('pathToTool') vi.mocked(toolCache.downloadTool).mockResolvedValue('pathToTool')
const response = JSON.stringify([{tag_name: 'v4.0.0'}]) const response = JSON.stringify([{tag_name: 'v4.0.0'}])
jest.spyOn(fs, 'readFileSync').mockReturnValue(response) vi.mocked(fs.readFileSync).mockReturnValue(response)
jest.spyOn(os, 'platform').mockReturnValue('win32') vi.mocked(os.platform).mockReturnValue('win32')
jest.spyOn(os, 'arch').mockReturnValue('x64') vi.mocked(os.arch).mockReturnValue('x64')
jest.spyOn(fs, 'chmodSync').mockImplementation(() => {}) vi.mocked(fs.chmodSync).mockImplementation(() => {})
jest.spyOn(toolCache, 'extractZip').mockResolvedValue('extractedPath') vi.mocked(toolCache.extractZip).mockResolvedValue('extractedPath')
jest.spyOn(toolCache, 'cacheDir').mockResolvedValue('pathToCachedDir') vi.mocked(toolCache.cacheDir).mockResolvedValue('pathToCachedDir')
jest vi.mocked(fs.readdirSync).mockImplementation((file, _?) => [
.spyOn(fs, 'readdirSync') 'helm.exe' as unknown as fs.Dirent<NonSharedBuffer>
.mockImplementation((file, _) => [ ])
'helm.exe' as unknown as fs.Dirent<NonSharedBuffer> vi.mocked(fs.statSync).mockImplementation((file) => {
])
jest.spyOn(fs, 'statSync').mockImplementation((file) => {
const isDirectory = const isDirectory =
(file as string).indexOf('folder') == -1 ? false : true (file as string).indexOf('folder') == -1 ? false : true
return {isDirectory: () => isDirectory} as fs.Stats return {isDirectory: () => isDirectory} as fs.Stats
@ -244,12 +297,12 @@ describe('run.ts', () => {
}) })
test('downloadHelm() - throw error if unable to download', async () => { test('downloadHelm() - throw error if unable to download', async () => {
jest.spyOn(toolCache, 'find').mockReturnValue('') vi.mocked(toolCache.find).mockReturnValue('')
jest.spyOn(toolCache, 'downloadTool').mockImplementation(async () => { vi.mocked(toolCache.downloadTool).mockImplementation(async () => {
throw 'Unable to download' throw 'Unable to download'
}) })
jest.spyOn(os, 'platform').mockReturnValue('win32') vi.mocked(os.platform).mockReturnValue('win32')
jest.spyOn(os, 'arch').mockReturnValue('x64') vi.mocked(os.arch).mockReturnValue('x64')
const downloadUrl = 'https://test.tld/helm-v3.2.1-windows-amd64.zip' const downloadUrl = 'https://test.tld/helm-v3.2.1-windows-amd64.zip'
await expect(run.downloadHelm(downloadBaseURL, 'v3.2.1')).rejects.toThrow( await expect(run.downloadHelm(downloadBaseURL, 'v3.2.1')).rejects.toThrow(
@ -260,17 +313,17 @@ describe('run.ts', () => {
}) })
test('downloadHelm() - return path to helm tool with same version from toolCache', async () => { test('downloadHelm() - return path to helm tool with same version from toolCache', async () => {
jest.spyOn(toolCache, 'find').mockReturnValue('pathToCachedDir') vi.mocked(toolCache.find).mockReturnValue('pathToCachedDir')
jest.spyOn(toolCache, 'cacheDir').mockResolvedValue('pathToCachedDir') vi.mocked(toolCache.cacheDir).mockResolvedValue('pathToCachedDir')
jest.spyOn(toolCache, 'downloadTool').mockResolvedValue('pathToTool') vi.mocked(toolCache.downloadTool).mockResolvedValue('pathToTool')
jest.spyOn(toolCache, 'extractZip').mockResolvedValue('extractedPath') vi.mocked(toolCache.extractZip).mockResolvedValue('extractedPath')
jest.spyOn(os, 'platform').mockReturnValue('win32') vi.mocked(os.platform).mockReturnValue('win32')
jest.spyOn(os, 'arch').mockReturnValue('x64') vi.mocked(os.arch).mockReturnValue('x64')
jest.spyOn(fs, 'chmodSync').mockImplementation(() => {}) vi.mocked(fs.chmodSync).mockImplementation(() => {})
jest vi.mocked(fs.readdirSync).mockReturnValue([
.spyOn(fs, 'readdirSync') 'helm.exe' as unknown as fs.Dirent<NonSharedBuffer>
.mockReturnValue(['helm.exe' as unknown as fs.Dirent<NonSharedBuffer>]) ])
jest.spyOn(fs, 'statSync').mockImplementation((file) => { vi.mocked(fs.statSync).mockImplementation((file) => {
const isDirectory = const isDirectory =
(file as string).indexOf('folder') == -1 ? false : true (file as string).indexOf('folder') == -1 ? false : true
return {isDirectory: () => isDirectory} as fs.Stats return {isDirectory: () => isDirectory} as fs.Stats
@ -287,16 +340,16 @@ describe('run.ts', () => {
}) })
test('downloadHelm() - throw error is helm is not found in path', async () => { test('downloadHelm() - throw error is helm is not found in path', async () => {
jest.spyOn(toolCache, 'find').mockReturnValue('') vi.mocked(toolCache.find).mockReturnValue('')
jest.spyOn(toolCache, 'downloadTool').mockResolvedValue('pathToTool') vi.mocked(toolCache.downloadTool).mockResolvedValue('pathToTool')
jest.spyOn(toolCache, 'cacheDir').mockResolvedValue('pathToCachedDir') vi.mocked(toolCache.cacheDir).mockResolvedValue('pathToCachedDir')
jest.spyOn(toolCache, 'downloadTool').mockResolvedValue('pathToTool') vi.mocked(toolCache.downloadTool).mockResolvedValue('pathToTool')
jest.spyOn(toolCache, 'extractZip').mockResolvedValue('extractedPath') vi.mocked(toolCache.extractZip).mockResolvedValue('extractedPath')
jest.spyOn(os, 'platform').mockReturnValue('win32') vi.mocked(os.platform).mockReturnValue('win32')
jest.spyOn(os, 'arch').mockReturnValue('x64') vi.mocked(os.arch).mockReturnValue('x64')
jest.spyOn(fs, 'chmodSync').mockImplementation() vi.mocked(fs.chmodSync).mockImplementation(() => {})
jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => []) vi.mocked(fs.readdirSync).mockImplementation((file, _?) => [])
jest.spyOn(fs, 'statSync').mockImplementation((file) => { vi.mocked(fs.statSync).mockImplementation((file) => {
const isDirectory = const isDirectory =
(file as string).indexOf('folder') == -1 ? false : true (file as string).indexOf('folder') == -1 ? false : true
return {isDirectory: () => isDirectory} as fs.Stats return {isDirectory: () => isDirectory} as fs.Stats

View file

@ -131,7 +131,7 @@ export async function downloadHelm(
export function findHelm(rootFolder: string): string { export function findHelm(rootFolder: string): string {
fs.chmodSync(rootFolder, '777') fs.chmodSync(rootFolder, '777')
var filelist: string[] = [] let filelist: string[] = []
walkSync(rootFolder, filelist, helmToolName + getExecutableExtension()) walkSync(rootFolder, filelist, helmToolName + getExecutableExtension())
if (!filelist || filelist.length == 0) { if (!filelist || filelist.length == 0) {
throw new Error( throw new Error(
@ -142,8 +142,8 @@ export function findHelm(rootFolder: string): string {
} }
} }
export var walkSync = function (dir, filelist, fileToFind) { export function walkSync(dir, filelist, fileToFind) {
var files = fs.readdirSync(dir) const files = fs.readdirSync(dir)
filelist = filelist || [] filelist = filelist || []
files.forEach(function (file) { files.forEach(function (file) {
if (fs.statSync(path.join(dir, file)).isDirectory()) { if (fs.statSync(path.join(dir, file)).isDirectory()) {

View file

@ -1,64 +1,14 @@
{ {
"compilerOptions": { "compilerOptions": {
/* Basic Options */ "target": "ES2020",
// "incremental": true, /* Enable incremental compilation */ "module": "NodeNext",
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */, "moduleResolution": "NodeNext",
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, "rootDir": "./src",
// "allowJs": true, /* Allow javascript files to be compiled. */ "outDir": "./lib",
// "checkJs": true, /* Report errors in .js files. */ "noImplicitAny": false,
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ "skipLibCheck": true,
// "declaration": true, /* Generates corresponding '.d.ts' file. */ "noEmit": true,
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ "types": ["node", "vitest/globals"]
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./lib" /* Redirect output structure to the directory. */,
"rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
//"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": false /* Raise error on expressions and declarations with an implied 'any' type. */,
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
// "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
"skipLibCheck": true
}, },
"exclude": ["node_modules", "**/*.test.ts"] "exclude": ["node_modules", "**/*.test.ts", "vitest.config.ts"]
} }

10
vitest.config.ts Normal file
View file

@ -0,0 +1,10 @@
import {defineConfig} from 'vitest/config'
export default defineConfig({
test: {
globals: true,
environment: 'node',
include: ['**/*.test.ts'],
clearMocks: true
}
})