refactor(triggers): rename triggerWorkflow to onFailureWorkflow for clarity

- Updated all instances of `triggerWorkflow` to `onFailureWorkflow` across the codebase to improve clarity and consistency in naming.
- Adjusted related logic in workflow configurations and UI components to reflect the new naming convention.
- Enhanced error messages and documentation to align with the updated terminology.

This change aims to provide a clearer understanding of the workflow's failure handling mechanism.
This commit is contained in:
2026-08-18 11:05:39 +07:00
parent 0c416506d6
commit c668947c90
9 changed files with 112 additions and 29 deletions
+1 -1
View File
@@ -690,7 +690,7 @@ export function createRegistry(server) {
{ {
workflow: opts.key, workflow: opts.key,
consecutiveFailures, consecutiveFailures,
triggerWorkflow: failureConfig.workflowName, onFailureWorkflow: failureConfig.workflowName,
destination: destKey, destination: destKey,
}, },
"triggering failure alert workflow", "triggering failure alert workflow",
+1 -1
View File
@@ -28,7 +28,7 @@ function triggerSummary(owner, workflow) {
path: isHttp && t?.path != null ? namespacedPath(owner, t.path) : t?.path ?? null, path: isHttp && t?.path != null ? namespacedPath(owner, t.path) : t?.path ?? null,
schedule: t?.schedule ?? null, schedule: t?.schedule ?? null,
onConsecutiveFailures: t?.onConsecutiveFailures ?? null, onConsecutiveFailures: t?.onConsecutiveFailures ?? null,
triggerWorkflow: t?.triggerWorkflow ?? null, onFailureWorkflow: t?.onFailureWorkflow ?? null,
auth: isHttp ? authLabel(t?.auth) : null, auth: isHttp ? authLabel(t?.auth) : null,
}; };
}); });
+11 -5
View File
@@ -46,8 +46,7 @@ export function resolveFailureTriggerConfig(workflow, owner, runtimeTrigger) {
if (!spec) continue; if (!spec) continue;
const threshold = Number(spec.onConsecutiveFailures); const threshold = Number(spec.onConsecutiveFailures);
const workflowName = const workflowName = onFailureWorkflowName(spec);
typeof spec.triggerWorkflow === "string" ? spec.triggerWorkflow.trim() : "";
if (!Number.isFinite(threshold) || threshold < 1 || workflowName.length === 0) { if (!Number.isFinite(threshold) || threshold < 1 || workflowName.length === 0) {
return null; return null;
} }
@@ -59,6 +58,14 @@ export function resolveFailureTriggerConfig(workflow, owner, runtimeTrigger) {
return null; return null;
} }
/**
* @param {Record<string, unknown>} trigger
*/
function onFailureWorkflowName(trigger) {
const value = trigger?.onFailureWorkflow;
return typeof value === "string" ? value.trim() : "";
}
/** /**
* @param {unknown} workflow * @param {unknown} workflow
*/ */
@@ -73,14 +80,13 @@ export async function validateWorkflowFailureTriggers(workflow) {
const hasThreshold = const hasThreshold =
trigger.onConsecutiveFailures != null && trigger.onConsecutiveFailures !== ""; trigger.onConsecutiveFailures != null && trigger.onConsecutiveFailures !== "";
const hasWorkflow = const hasWorkflow = onFailureWorkflowName(trigger).length > 0;
typeof trigger.triggerWorkflow === "string" && trigger.triggerWorkflow.trim().length > 0;
if (!hasThreshold && !hasWorkflow) continue; if (!hasThreshold && !hasWorkflow) continue;
if (!hasThreshold || !hasWorkflow) { if (!hasThreshold || !hasWorkflow) {
const err = new Error( const err = new Error(
"onConsecutiveFailures and triggerWorkflow must both be set on a trigger", "onConsecutiveFailures and onFailureWorkflow must both be set on a trigger",
); );
err.statusCode = 400; err.statusCode = 400;
throw err; throw err;
@@ -8,7 +8,7 @@ scripts:
config: config:
url: https://example.com/ url: https://example.com/
outputVar: message outputVar: message
transform: > transform: |
data.hasChanges data.hasChanges
? "example.com changed (fingerprint " & data.fingerprint & ")" ? "example.com changed (fingerprint " & data.fingerprint & ")"
: "example.com unchanged since " & data.fingerprintAt : "example.com unchanged since " & data.fingerprintAt
@@ -16,3 +16,7 @@ triggers:
- type: HTTP - type: HTTP
method: POST method: POST
path: /detect-example path: /detect-example
- type: cron
schedule: "* * * * *"
onConsecutiveFailures: 3
onFailureWorkflow: dev-zte-sms
@@ -0,0 +1,50 @@
name: Jadwal Solat Jakarta ntfy
scripts:
- id: fetch
script: fetch-http.js
config:
url: https://kemenag.go.id/api/prayer-times/1301
method: GET
headers:
Content-Type: application/json
Accept: application/json
- id: transform
script: jsonata.js
config:
expression: |-
{
"title": data.httpResponse.data.date,
"message": "Imsak:" & data.httpResponse.data.imsak & "\n" &
"Subuh:" & data.httpResponse.data.subuh & "\n" &
"Dzuhur:" & data.httpResponse.data.dzuhur & "\n" &
"Ashar:" & data.httpResponse.data.ashar & "\n" &
"Maghrib:" & data.httpResponse.data.maghrib & "\n" &
"Isya:" & data.httpResponse.data.isya
}
needs:
- fetch
- id: ntfy
script: ntfy.js
config:
url: $VAR_ntfy_channel
fingerprint: true
needs:
- transform
- id: slack
script: ntfy.js
config:
url: $VAR_ntfy_channel2
fingerprint: fingerprint:ntfy2
needs:
- transform
- script: slack-webhook.js
config:
webhookUrlSecret: slack_deploy_webhook
fingerprint: true
fingerprintMaxAge: 1h
text: $INPUT_message
needs:
- transform
triggers:
- type: cron
schedule: 0 5 * * *
@@ -10,3 +10,9 @@ scripts:
- test-send-gmail.yaml - test-send-gmail.yaml
- track.yaml - track.yaml
- rss-devto-to-ntfy.yaml - rss-devto-to-ntfy.yaml
- dev-joplin-sync.yaml
- dev-joplin-daily.yaml
- dev-joplin-get-note.yaml
- web-dave.yaml
- jadwal-sholat-jakart.yaml
- detect-example-changes.yaml
@@ -0,0 +1,14 @@
name: Dab 0dev
scripts:
- script: list-webdav.js
config:
url: https://dav.0dev.web.id/books
path: /
includeDirectories: true
recursive: false
username: nsrb
passwordSecret: dav_0dev_password
triggers:
- type: HTTP
method: POST
path: /new
@@ -117,15 +117,15 @@ export function TriggerCard({
function triggerSummary(trigger, owner) { function triggerSummary(trigger, owner) {
const type = trigger?.type; const type = trigger?.type;
const failure =
trigger.onConsecutiveFailures && trigger.onFailureWorkflow
? ` · onFailure@${trigger.onFailureWorkflow}`
: "";
if (type === "HTTP") { if (type === "HTTP") {
return `${trigger.method || "POST"} ${namespacedPath(owner || "owner", trigger.path || "/")}`; return `${trigger.method || "POST"} ${namespacedPath(owner || "owner", trigger.path || "/")}${failure}`;
} }
if (type === "cron") { if (type === "cron") {
const extra = return `${trigger.schedule || ""}${failure}`;
trigger.onConsecutiveFailures && trigger.triggerWorkflow
? ` · alert@${trigger.triggerWorkflow}`
: "";
return `${trigger.schedule || ""}${extra}`;
} }
if (type === "workflow") return "callable"; if (type === "workflow") return "callable";
return ""; return "";
@@ -320,12 +320,12 @@ function FailureAlertFields({ trigger, disabled, onChange, alertDestinations })
/> />
</label> </label>
<label className="form-control"> <label className="form-control">
<span className="label py-0 text-sm">Trigger workflow</span> <span className="label py-0 text-sm">On failure, start</span>
<select <select
className="select select-sm" className="select select-sm"
value={trigger.triggerWorkflow ?? ""} value={trigger.onFailureWorkflow ?? ""}
disabled={disabled} disabled={disabled}
onChange={(e) => onChange({ ...trigger, triggerWorkflow: e.target.value })} onChange={(e) => onChange({ ...trigger, onFailureWorkflow: e.target.value })}
> >
<option value="">None</option> <option value="">None</option>
{alertDestinations.map((w) => ( {alertDestinations.map((w) => (
@@ -333,11 +333,11 @@ function FailureAlertFields({ trigger, disabled, onChange, alertDestinations })
{w.name ?? w.file} {w.name ?? w.file}
</option> </option>
))} ))}
{trigger.triggerWorkflow && {trigger.onFailureWorkflow &&
!alertDestinations.some( !alertDestinations.some(
(w) => (w.name ?? w.file) === trigger.triggerWorkflow, (w) => (w.name ?? w.file) === trigger.onFailureWorkflow,
) ? ( ) ? (
<option value={trigger.triggerWorkflow}>{trigger.triggerWorkflow}</option> <option value={trigger.onFailureWorkflow}>{trigger.onFailureWorkflow}</option>
) : null} ) : null}
</select> </select>
</label> </label>
+12 -9
View File
@@ -143,7 +143,7 @@ export function newHttpTrigger() {
response: "", response: "",
unauthorized: null, unauthorized: null,
onConsecutiveFailures: "", onConsecutiveFailures: "",
triggerWorkflow: "", onFailureWorkflow: "",
}; };
} }
@@ -158,7 +158,7 @@ export function newCronTrigger() {
response: "", response: "",
unauthorized: null, unauthorized: null,
onConsecutiveFailures: "", onConsecutiveFailures: "",
triggerWorkflow: "", onFailureWorkflow: "",
}; };
} }
@@ -173,7 +173,7 @@ export function newWorkflowTrigger() {
response: "", response: "",
unauthorized: null, unauthorized: null,
onConsecutiveFailures: "", onConsecutiveFailures: "",
triggerWorkflow: "", onFailureWorkflow: "",
}; };
} }
@@ -191,6 +191,10 @@ export function triggerDestinations(workflows, { owner, excludeFile } = {}) {
export { HTTP_METHODS }; export { HTTP_METHODS };
function readOnFailureWorkflow(raw) {
return typeof raw?.onFailureWorkflow === "string" ? raw.onFailureWorkflow : "";
}
function normalizeStep(step) { function normalizeStep(step) {
const uiId = nextUiId("step"); const uiId = nextUiId("step");
if (typeof step === "string") { if (typeof step === "string") {
@@ -266,10 +270,10 @@ function normalizeTrigger(raw) {
"response", "response",
"unauthorized", "unauthorized",
"onConsecutiveFailures", "onConsecutiveFailures",
"triggerWorkflow", "onFailureWorkflow",
]) ])
: type === "cron" : type === "cron"
? new Set(["type", "schedule", "onConsecutiveFailures", "triggerWorkflow"]) ? new Set(["type", "schedule", "onConsecutiveFailures", "onFailureWorkflow"])
: new Set(["type"]); : new Set(["type"]);
/** @type {Record<string, unknown>} */ /** @type {Record<string, unknown>} */
const extra = {}; const extra = {};
@@ -286,8 +290,7 @@ function normalizeTrigger(raw) {
raw.onConsecutiveFailures == null || raw.onConsecutiveFailures === "" raw.onConsecutiveFailures == null || raw.onConsecutiveFailures === ""
? "" ? ""
: String(raw.onConsecutiveFailures), : String(raw.onConsecutiveFailures),
triggerWorkflow: onFailureWorkflow: readOnFailureWorkflow(raw),
typeof raw.triggerWorkflow === "string" ? raw.triggerWorkflow : "",
auth: raw.auth ?? null, auth: raw.auth ?? null,
response: typeof raw.response === "string" ? raw.response : "", response: typeof raw.response === "string" ? raw.response : "",
unauthorized: raw.unauthorized ?? null, unauthorized: raw.unauthorized ?? null,
@@ -328,8 +331,8 @@ function dumpFailureTriggerFields(t, out) {
out.onConsecutiveFailures = Math.floor(threshold); out.onConsecutiveFailures = Math.floor(threshold);
} }
} }
if (typeof t.triggerWorkflow === "string" && t.triggerWorkflow.trim()) { if (typeof t.onFailureWorkflow === "string" && t.onFailureWorkflow.trim()) {
out.triggerWorkflow = t.triggerWorkflow.trim(); out.onFailureWorkflow = t.onFailureWorkflow.trim();
} }
} }