99 lines
4.2 KiB
JavaScript
99 lines
4.2 KiB
JavaScript
import { execSync } from 'child_process';
|
|
import { resolve } from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import { dirname } from 'path';
|
|
import process from 'process';
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const ROOT = resolve(__dirname, '..');
|
|
|
|
// colors
|
|
const G = (s) => `\x1b[0;32m${s}\x1b[0m`;
|
|
const Y = (s) => `\x1b[1;33m${s}\x1b[0m`;
|
|
const R = (s) => `\x1b[0;31m${s}\x1b[0m`;
|
|
|
|
const log = (msg) => console.log(`${G('[OK]')} ${msg}`);
|
|
const warn = (msg) => console.warn(`${Y('[WARN]')} ${msg}`);
|
|
const err = (msg) => { console.error(`${R('[ERR]')} ${msg}`); process.exit(1); };
|
|
|
|
// ── defaults ──
|
|
const NAMESPACE = process.env.NAMESPACE || 'app';
|
|
const RELEASE = process.env.RELEASE || 'deploy';
|
|
const CHART_DIR = process.env.CHART_DIR || resolve(ROOT, 'deploy');
|
|
const REGISTRY = process.env.REGISTRY || 'harbor.gitdata.me/gtateam';
|
|
const TAG = process.env.TAG || execSync('git rev-parse --short HEAD', { encoding: 'utf8', cwd: ROOT }).trim();
|
|
const CONFIG_MAP = process.env.CONFIG_MAP || 'app-env';
|
|
const PVC_NAME = process.env.PVC_NAME || 'shared-data';
|
|
|
|
// ── prereqs ──
|
|
try { execSync('helm version --short', { stdio: 'pipe' }); } catch { err('helm not found'); }
|
|
try { execSync('kubectl version --client', { stdio: 'pipe' }); } catch { err('kubectl not found'); }
|
|
|
|
log(execSync('helm version --short', { encoding: 'utf8' }).trim());
|
|
log(execSync('kubectl version --client --short 2>/dev/null || kubectl version -o json 2>/dev/null | grep gitVersion', { encoding: 'utf8', shell: true }).trim());
|
|
|
|
// ── 1. Ensure namespace ──
|
|
log(`Ensuring namespace ${NAMESPACE} exists...`);
|
|
execSync(`kubectl create namespace "${NAMESPACE}" --dry-run=client -o yaml | kubectl apply -f -`, { stdio: 'inherit' });
|
|
|
|
// ── 2. Verify prerequisites ──
|
|
try { execSync(`kubectl get namespace "${NAMESPACE}"`, { stdio: 'pipe' }); }
|
|
catch { err(`Namespace '${NAMESPACE}' not found`); }
|
|
|
|
try { execSync(`kubectl get configmap "${CONFIG_MAP}" -n "${NAMESPACE}"`, { stdio: 'pipe' }); }
|
|
catch { err(`ConfigMap '${CONFIG_MAP}' not found in namespace '${NAMESPACE}'`); }
|
|
|
|
try { execSync(`kubectl get pvc "${PVC_NAME}" -n "${NAMESPACE}"`, { stdio: 'pipe' }); }
|
|
catch { err(`PVC '${PVC_NAME}' not found in namespace '${NAMESPACE}'`); }
|
|
|
|
// Protect from Helm deletion
|
|
execSync(`kubectl annotate configmap "${CONFIG_MAP}" -n "${NAMESPACE}" helm.sh/resource-policy=keep --overwrite`, { stdio: 'inherit' });
|
|
execSync(`kubectl annotate pvc "${PVC_NAME}" -n "${NAMESPACE}" helm.sh/resource-policy=keep --overwrite`, { stdio: 'inherit' });
|
|
|
|
// cert-manager ClusterIssuer
|
|
try { execSync('kubectl get clusterissuer cloudflare-acme-cluster-issuer', { stdio: 'pipe' }); }
|
|
catch { warn("ClusterIssuer 'cloudflare-acme-cluster-issuer' not found — TLS will fail"); }
|
|
|
|
log('Prerequisites verified');
|
|
|
|
// ── 3. Lint ──
|
|
log('Linting Helm chart...');
|
|
try { execSync(`helm lint "${CHART_DIR}"`, { stdio: 'inherit' }); }
|
|
catch { err('Helm lint failed'); }
|
|
|
|
// ── 4. Deploy ──
|
|
log(`Deploying release ${RELEASE} with tag ${TAG}...`);
|
|
|
|
try {
|
|
execSync(
|
|
`helm upgrade --install "${RELEASE}" "${CHART_DIR}"` +
|
|
` --namespace "${NAMESPACE}"` +
|
|
` --set imageRegistry="${REGISTRY}"` +
|
|
` --set imageTag="${TAG}"` +
|
|
` --set configMapName="${CONFIG_MAP}"` +
|
|
` --set pvcName="${PVC_NAME}"` +
|
|
` --timeout 5m`,
|
|
{ stdio: 'inherit' }
|
|
);
|
|
} catch {
|
|
err(`Deployment FAILED — release preserved for debugging.
|
|
|
|
Debug commands:
|
|
helm status ${RELEASE} -n ${NAMESPACE}
|
|
kubectl get pods -n ${NAMESPACE}
|
|
kubectl logs -n app <pod-name> --previous
|
|
helm rollback ${RELEASE} -n ${NAMESPACE} (rollback to previous release)
|
|
helm uninstall ${RELEASE} -n ${NAMESPACE} (remove failed release)`);
|
|
}
|
|
|
|
log(`Release ${RELEASE} deployed successfully`);
|
|
|
|
// ── 5. Verify ──
|
|
log('Checking deployment status...');
|
|
execSync(`kubectl get deployments -n "${NAMESPACE}" -l app.kubernetes.io/instance="${RELEASE}"`, { stdio: 'inherit' });
|
|
execSync(`kubectl get pods -n "${NAMESPACE}" -l app.kubernetes.io/instance="${RELEASE}"`, { stdio: 'inherit' });
|
|
execSync(`kubectl get services -n "${NAMESPACE}" -l app.kubernetes.io/instance="${RELEASE}"`, { stdio: 'inherit' });
|
|
execSync(`kubectl get ingress -n "${NAMESPACE}"`, { stdio: 'inherit' });
|
|
|
|
log('Deployment complete');
|