Merge branch 'main' into cursor/bullmq-queue-phase-a-3038
This commit is contained in:
@@ -63,9 +63,10 @@ export default function dashboardPluginFactory(registry) {
|
||||
}
|
||||
}
|
||||
|
||||
const [active, failed, recent] = await Promise.all([
|
||||
const [active, streaks, failedEvents, recent] = await Promise.all([
|
||||
store.listRuns({ status: ["queued", "running"], limit: 10 }),
|
||||
store.listRuns({ status: "failed", limit: 20 }),
|
||||
store.listConsecutiveFailureStreaks({ minCount: 4, limit: 10 }),
|
||||
store.listRuns({ status: "failed", limit: 5 }),
|
||||
store.listRuns({ limit: 10 }),
|
||||
]);
|
||||
|
||||
@@ -76,9 +77,11 @@ export default function dashboardPluginFactory(registry) {
|
||||
brokenCount,
|
||||
running: active,
|
||||
needsAttention: {
|
||||
failed,
|
||||
consecutiveFailures: streaks.items,
|
||||
consecutiveFailureCount: streaks.total,
|
||||
brokenWorkflows,
|
||||
},
|
||||
failedEvents,
|
||||
recent,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import pino from "pino";
|
||||
import { isBinary, summarizeBinary } from "../../json-preview.js";
|
||||
import { redactString } from "../../secret-value.js";
|
||||
|
||||
const LEVEL_TO_NUM = {
|
||||
@@ -64,7 +65,9 @@ export function safeSerialize(value) {
|
||||
try {
|
||||
return JSON.parse(
|
||||
redactString(
|
||||
JSON.stringify(value, (_key, v) => {
|
||||
JSON.stringify(value, function (key, v) {
|
||||
const raw = this[key];
|
||||
if (isBinary(raw)) return summarizeBinary(raw);
|
||||
if (typeof v === "bigint") return v.toString();
|
||||
if (typeof v === "object" && v !== null) {
|
||||
if (seen.has(v)) return "[Circular]";
|
||||
|
||||
@@ -17,6 +17,15 @@ export default async function runsPlugin(fastify) {
|
||||
return { runs };
|
||||
});
|
||||
|
||||
fastify.get("/consecutive-failures", async (req) => {
|
||||
const q = /** @type {Record<string, string | undefined>} */ (req.query ?? {});
|
||||
const limit = q.limit ? Number(q.limit) : undefined;
|
||||
return store.listConsecutiveFailureStreaks({
|
||||
minCount: 4,
|
||||
limit: Number.isFinite(limit) ? limit : 200,
|
||||
});
|
||||
});
|
||||
|
||||
fastify.get("/runs/:id", async (req, reply) => {
|
||||
const { id } = /** @type {{ id: string }} */ (req.params);
|
||||
const run = await store.getRun(id);
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
listSecrets,
|
||||
upsertSecret,
|
||||
} from "../../secrets-store.js";
|
||||
import { MIN_SECRET_LENGTH } from "../../secret-value.js";
|
||||
|
||||
/**
|
||||
* @param {import("fastify").FastifyInstance} fastify
|
||||
@@ -37,10 +36,8 @@ export default async function secretsPlugin(fastify) {
|
||||
}
|
||||
|
||||
const value = String(body.value ?? "");
|
||||
if (value.length < MIN_SECRET_LENGTH) {
|
||||
return reply
|
||||
.code(400)
|
||||
.send({ error: `value must be at least ${MIN_SECRET_LENGTH} characters` });
|
||||
if (value.length === 0) {
|
||||
return reply.code(400).send({ error: "value is required" });
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -28,7 +28,7 @@ function triggerSummary(owner, workflow) {
|
||||
path: isHttp && t?.path != null ? namespacedPath(owner, t.path) : t?.path ?? null,
|
||||
schedule: t?.schedule ?? null,
|
||||
onConsecutiveFailures: t?.onConsecutiveFailures ?? null,
|
||||
triggerWorkflow: t?.triggerWorkflow ?? null,
|
||||
onFailureWorkflow: t?.onFailureWorkflow ?? null,
|
||||
auth: isHttp ? authLabel(t?.auth) : null,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user