1import { isDirectlyRun, getImportMetaUrlPath } from '../../serverF/isDirectlyRunF.mts'2import type { ViteAppCfg } from './viteAppCfgAI.mts'3import { pathJoin } from '../../serverF/pathF.mts'4import { ptDir } from '../../serverF/ptDirF.mts'5import { appCfgCtx } from '../k8sF/ctxF/appCfgCtxF.mts'6import { availActionsCtx } from '../ctxF/availActionsCtxF.mts'7import { getAction } from '../ctxF/actionCtxF.mts'8import { wrapKubeCoalesce } from '../k8sF/kubeCoalesceF.mts'9import { klusterCtx, type KlusterCfg } from '../k8sF/ctxF/klusterCtxF.mts'10import { nextContCtx } from '../libF/nextContCtxF.mts'11import { dockerBuildAndRet } from '../dockerF/dockerImageF.mts'12import { applyAndWaitRollout } from '../../nextF/deployF/mkNextDeploymentF.mts'14import { watchFlogs } from '../k8sF/logsF/watchFlogsF.mts'15import { getDeployGitSha } from '../libF/gitF/getDeployGitShaAI.mts'16import { printDeployedUrl } from '../../serverF/briefForLlmF.mts'17import { cliHelp } from '../cliF/cliHelpF.mts'18import { resourcesActionsH } from '../k8sF/isActionSupportedF.mts'19import { cliValidatedCtx } from '../ctxF/cliValidatedCtxF.mts'20import { ptDeployActionsCtx, getDeployActions } from '../ptDeployActions/doPtDeployActionF.mts'21import { tryDispatchAction } from '../ptDeployActions/do1PtDeployActionF.mts'22import { devserver, runtests, testdeploy, setDoViteAppApplyRef } from './viteAppActionsAI.mts'23import { genViteBuilderDockerfile, genViteRunnerDockerfile } from './viteDockerfileAI.mts'24import { dockerActions } from '../ptDeployActions/dockerActionsAI.mts'25import { absPathToPtPath } from '../../serverF/pathF/absPathToPtPathF.mts'26import { generic3DeploymentTmpl } from '../k8sF/genericDeploymentF.mts'27import { decAppCfgResGitSha } from '../decAppCfgResGitShaF.mts'29export const eptViteAppK8sRes = {kind: 'Deployment', apiVersion: 'apps/v1'}30export const eptViteApp = async (inputCfg: ViteAppCfg) => {31 const {importMetaUrl, srcDir, monorepoRoot, distDir = 'dist', buildCmd, installCmd, devCmd, svcPortNo = 3000, ...props} = inputCfg32 const fullConfig = {importMetaUrl, srcDir, monorepoRoot, distDir, buildCmd, installCmd, devCmd, svcPortNo, ...props}33 if (importMetaUrl && !isDirectlyRun(importMetaUrl)) return fullConfig37 const resolvedMonorepoRoot = monorepoRoot ? (monorepoRoot.startsWith('/') ? monorepoRoot : pathJoin(ptDir, monorepoRoot)) : null39 const {name, cluster_name} = props40 const resourceTmpl = generic3DeploymentTmpl({name: name!})41 const appSourcePath = absPathToPtPath((resolvedMonorepoRoot || resolvedSrcDir) as Parameters<typeof absPathToPtPath>[0])42 const deployEpPath = absPathToPtPath(getImportMetaUrlPath(importMetaUrl as any) as Parameters<typeof absPathToPtPath>[0])43 const git_sha = await getDeployGitSha({importMetaUrl: importMetaUrl as any, appSourcePaths: [appSourcePath]})44 let appCfg: ViteAppCfg = {...props, importMetaUrl, srcDir: resolvedSrcDir, monorepoRoot: resolvedMonorepoRoot, distDir, buildCmd, installCmd, devCmd, svcPortNo, usesExplicitEpPtPaths: true, epPtPathsA: [deployEpPath], resourceTmpl, cluster_name, action, git_sha}45 appCfg = await decAppCfgResGitSha({appConfig: appCfg}) as ViteAppCfg46 appCfgCtx.enterWith(appCfg)47 availActionsCtx.enterWith({...availActionsCtx.getStore(), ...getDeployActions(), devserver, runtests, testdeploy})48 ptDeployActionsCtx.enterWith(dockerActions)49 setDoViteAppApplyRef(doViteAppApply)51 if (await tryDispatchAction()) return53 await doViteAppApply({...props, importMetaUrl, srcDir: resolvedSrcDir, monorepoRoot: resolvedMonorepoRoot, distDir, buildCmd, installCmd, devCmd, svcPortNo, action})54}56export const doViteAppApply = async (props: ViteAppCfg) => wrapKubeCoalesce(async () => {57 const {srcDir, monorepoRoot, distDir, buildCmd, installCmd, viteBuildEnvH, svcPortNo, name, action, wcHostname} = props58 const kube_extHostname = props.kube_extHostname || wcHostname60 if (!cliValidatedCtx.getStore()?.validated) {61 cliHelp({action, actionsH: resourcesActionsH()})62 }64 props = {...props, kube_extHostname}65 klusterCtx.enterWith(props as KlusterCfg)67 // git_sha computed in eptViteApp, get from appCfg or recompute for direct doViteAppApply calls68 const appCfg = appCfgCtx.getStore() || {}69 let {git_sha} = appCfg70 if (!git_sha) {71 const {importMetaUrl} = props72 const appSourcePath = absPathToPtPath((monorepoRoot || srcDir) as Parameters<typeof absPathToPtPath>[0])73 git_sha = await getDeployGitSha({importMetaUrl: importMetaUrl as any, appSourcePaths: [appSourcePath]})74 }76 const {builderDf, ptSrcDir} = await genViteBuilderDockerfile({srcDir, monorepoRoot, buildCmd, installCmd, viteBuildEnvH})78 const builtBuilder = await dockerBuildAndRet({79 dfToBuild: builderDf,80 name,81 git_sha,82 dfLabel: 'vite-builder',83 reqDockPush: true,84 ...props,85 })87 const {repo_name_tag: builderRepoNameTag} = await builtBuilder.getRnt()89 const runnerDf = genViteRunnerDockerfile({builderRepoNameTag, ptSrcDir, distDir: distDir!, svcPortNo: svcPortNo!})91 await dockerBuildAndRet({92 dfToBuild: runnerDf,93 name,94 action,95 git_sha,96 dfLabel: 'vite-runner',97 ...props,98 })100 const dockerFilesA = [runnerDf]101 appCfgCtx.enterWith({...appCfgCtx.getStore(), dockerFilesA})103 nextContCtx.enterWith({104 command: ['serve', '-s', '/app', '-l', String(svcPortNo)],105 ports: [{containerPort: svcPortNo}],106 })108 const propsWithDf = {...props, git_sha, dockerFilesA}109 appCfgCtx.enterWith({...appCfgCtx.getStore(), ...propsWithDf})111 await applyAndWaitRollout(propsWithDf)113 if (kube_extHostname) {114 await syncOtherNextAppResources()115 printDeployedUrl({action, kubeExtUrl: `https://${kube_extHostname}`})116 }118 await watchFlogs()119}, props)