k8s-deploy/src/utilities/dockerUtils.ts
David Gamero 01cfe404ef
Migrate to esbuild/Vitest and upgrade @actions/* to ESM-only versions (#492)
* Migrate build toolchain from ncc/Jest to esbuild/Vitest

Replace the legacy ncc/Jest/Babel build stack with a modern ESM toolchain:

Build:
- Replace @vercel/ncc with esbuild (--platform=node --target=node20 --format=esm)
- Add createRequire banner for CJS interop in ESM bundle
- Add "type": "module" to package.json
- Add tsc --noEmit typecheck script (esbuild strips types without checking)
- Add typecheck to husky pre-commit hook

Dependencies:
- Bump @actions/core@3, exec@3, io@3, tool-cache@4 (ESM-only)
- Replace jest/ts-jest/@babel/* with vitest@4

Tests:
- Convert 29 test files: jest.fn()→vi.fn(), jest.mock()→vi.mock(), jest.spyOn()→vi.spyOn()
- Fix vitest 4 compat: mockImplementation requires args, mock call tracking, await .rejects

CI:
- Update build step from ncc build → npm run build
- Update composite action to use npm run build

* Switch tsconfig to NodeNext module resolution

Change module/moduleResolution from ES2022/bundler to NodeNext/NodeNext
and target from ES2022 to ES2020.

- Add .js extensions to all relative imports across 59 source/test files
  (required by NodeNext module resolution)
- Add vitest/globals to tsconfig types array for global test API declarations
2026-02-24 11:57:56 -08:00

80 lines
2.5 KiB
TypeScript

import * as io from '@actions/io'
import {DeploymentConfig} from '../types/deploymentConfig.js'
import * as core from '@actions/core'
import {DockerExec} from '../types/docker.js'
import {getNormalizedPath} from './githubUtils.js'
export async function getDeploymentConfig(): Promise<DeploymentConfig> {
let helmChartPaths: string[] =
process.env?.HELM_CHART_PATHS?.split(';').filter((path) => path != '') ||
[]
helmChartPaths = helmChartPaths.map((helmchart) =>
getNormalizedPath(helmchart.trim())
)
let inputManifestFiles: string[] =
core
.getInput('manifests')
.split(/[\n,;]+/)
.filter((manifest) => manifest.trim().length > 0) || []
if (helmChartPaths?.length == 0) {
inputManifestFiles = inputManifestFiles.map((manifestFile) =>
getNormalizedPath(manifestFile)
)
}
const imageNames =
core
.getInput('images')
.split('\n')
.filter((image) => image.length > 0) || []
const imageDockerfilePathMap: {[id: string]: string} = {}
const pullImages = !(core.getInput('pull-images').toLowerCase() === 'false')
if (pullImages) {
//Fetching from image label if available
for (const image of imageNames) {
try {
imageDockerfilePathMap[image] = await getDockerfilePath(image)
} catch (ex) {
core.warning(
`Failed to get dockerfile path for image ${image.toString()}: ${ex} `
)
}
}
}
return Promise.resolve(<DeploymentConfig>{
manifestFilePaths: inputManifestFiles,
helmChartFilePaths: helmChartPaths,
dockerfilePaths: imageDockerfilePathMap
})
}
async function getDockerfilePath(image: any): Promise<string> {
await checkDockerPath()
const dockerExec: DockerExec = new DockerExec('docker')
await dockerExec.pull(image, [], false)
const imageInspectResult: string = await dockerExec.inspect(image, [], false)
const imageConfig = JSON.parse(imageInspectResult)[0]
const DOCKERFILE_PATH_LABEL_KEY = 'dockerfile-path'
let pathValue: string = ''
if (
imageConfig?.Config?.Labels &&
imageConfig?.Config?.Labels[DOCKERFILE_PATH_LABEL_KEY]
) {
const pathLabel = imageConfig.Config.Labels[DOCKERFILE_PATH_LABEL_KEY]
pathValue = getNormalizedPath(pathLabel)
}
return Promise.resolve(pathValue)
}
export async function checkDockerPath() {
const dockerPath = await io.which('docker', false)
if (!dockerPath) {
throw new Error('Docker is not installed.')
}
}