Odoo Scheduled Action Overdue Sentinel
Read-only count overdue Odoo scheduled actions (ir.cron) via XML-RPC on a schedule and page Slack when the background job runner looks stuck or dead.
React to Jenkins build-finished events, classify flaky vs. broken vs. slow builds, and safely auto-retry only the flaky ones.
A Jenkins build that comes back UNSTABLE is not the same problem as one that comes back
FAILURE, but most CI dashboards treat them the same way: red is red. A build where 2 of
250 tests failed because of timing flakiness deserves a quiet, automatic re-run. A build
where 180 of 250 tests failed does not, that is a real break and a retry would just burn CI
capacity while hiding the signal. A build that passed but took three times as long as usual
is a third problem entirely, a performance regression nobody will notice until it is much
worse. This blueprint reacts to every Jenkins build-finished notification, re-fetches the
authoritative build JSON, tells these three cases apart using Jenkins's own result and test
action fields, and only ever auto-retries the one case where a retry is actually sound.
This blueprint was created by Mohit Jeswani.
on_build_finished (io.kestra.plugin.core.trigger.Webhook) receives Jenkins's
Notification Plugin payload and maps name, build.number, and build.parameters onto
flow inputs, so a manual run with the defaults also works for testing.fetch_build_detail (io.kestra.plugin.core.http.Request) calls Jenkins's own
/job/{name}/{number}/api/json directly with a Basic Auth header, since the webhook
payload itself does not carry the JUnit test action's failCount/totalCount or the
estimatedDuration field this flow needs, and allowFailed: true keeps a non-200 (for
example a build that was deleted before this flow got to it) from crashing the execution.evaluate (io.kestra.plugin.core.output.OutputValues) pulls the
hudson.tasks.junit.TestResultAction entry out of actions with a jq filter (falling
back to zero counts when the job publishes no test results), computes the failing-test
ratio and the duration-vs-estimate ratio, and classifies the build as HEALTHY,
SLOW_REGRESSION, FLAKY_TESTS_AUTO_RETRY, FLAKY_TESTS_NEEDS_HUMAN, BROKEN_TESTS, or
BUILD_FAILED, folding confirm_auto_retry into the flaky classification itself.route (io.kestra.plugin.core.flow.Switch):io.kestra.plugin.jenkins.JobBuild re-triggers the same job
with its original parameters (the one safe, tool-specific remediation here), then
alerts Slack that it did.confirm_auto_retry has not
authorized this flow to retry automatically yet.confirm_auto_retry is true.FAILURE/ABORTED result, or an unreachable
Jenkins server, never retries.summary logs the final severity and fail ratio.errors alerts Slack if the flow itself fails outright, for example a malformed webhook
payload.build.parameters, so a parameterized job gets retried the same way it ran the first time.JobBuild used as a
gated remediation action in an event-driven triage gate, distinct from this repo's existing
Jenkins blueprints, which poll lastBuild to wait out a build they just triggered rather
than reacting to a finished build's own test and timing detail.Jenkins's Notification Plugin can push an event, but it has no concept of a fail-ratio
threshold, no memory of what "normal" duration looks like, and no safe way to decide when a
retry helps versus when it just hides a problem. Kestra keeps that policy
(flaky_fail_ratio_threshold, slow_regression_multiplier, confirm_auto_retry) as flow
inputs, turns one webhook event into a six-way classification, and keeps a full execution
history of every build this flow has seen, what it decided, and whether it retried.
A local Jenkins instance for end-to-end testing can be run via the official open-source
jenkins/jenkins:lts Docker image, with a test job configured to publish JUnit results so
both the flaky and non-flaky paths can be exercised.
JENKINS_API_TOKEN: Jenkins API token or password. Used to build the Basic Auth header for
fetch_build_detail and passed directly to retry_build. In Kestra OSS, provide it as
the base64-encoded environment variable SECRET_JENKINS_API_TOKEN.JENKINS_NOTIFICATION_WEBHOOK_KEY: the path segment of this flow's webhook URL; keep it
unguessable since anyone who knows it can post a fake build event. In Kestra OSS, provide
it as SECRET_JENKINS_NOTIFICATION_WEBHOOK_KEY.SLACK_WEBHOOK_URL: used by every Slack alert case and the errors block. In Kestra OSS,
provide it as SECRET_SLACK_WEBHOOK_URL.| Input | Default | Purpose |
|---|---|---|
job_name |
demo-job |
Populated from the webhook; set directly for manual testing |
build_number |
1 |
Populated from the webhook; set directly for manual testing |
build_parameters |
{} |
Populated from the webhook's build.parameters, reused by retry_build |
jenkins_server_url |
http://localhost:8080 |
Base URL used to build the /api/json request |
jenkins_username |
admin |
Paired with JENKINS_API_TOKEN for Basic Auth |
flaky_fail_ratio_threshold |
0.1 |
Fail ratio ceiling for an UNSTABLE build to count as flaky |
slow_regression_multiplier |
1.5 |
Duration-vs-estimate ceiling before a passing build counts as a regression |
confirm_auto_retry |
false |
Authorizes retry_build to actually fire for a flaky build |
{{ outputs.fetch_build_detail.body }}: the full Jenkins build JSON (result, building,
duration, estimatedDuration, actions, and everything else Jenkins returns from
/api/json), as a raw string that jq parses directly.{{ outputs.evaluate.values.severity }}: HEALTHY, SLOW_REGRESSION,
FLAKY_TESTS_AUTO_RETRY, FLAKY_TESTS_NEEDS_HUMAN, BROKEN_TESTS, or BUILD_FAILED.{{ outputs.evaluate.values.fail_ratio }} / .fail_counts: the failing-test fraction and
an N/M string, both 0/"0/0" when the job publishes no JUnit test results at all.hudson.tasks.junit.TestResultAction. A job with no test publisher reports
fail_counts as 0/0 and can only ever land in HEALTHY, SLOW_REGRESSION, or
BUILD_FAILED, never the two flaky states, since there is nothing to compute a ratio from.fetch_build_detail calls /api/json at Jenkins's default tree depth; if a test reporting
plugin nests its summary deeper than that default (uncommon, but possible), actions will
not contain it and the ratio again falls back to 0/0.JobBuild's parameters field sends form data; a job with no parameters defined at all
should receive build_parameters as {} rather than omitting the field, which is exactly
what the webhook mapping's ?? {} fallback produces.name, build.number, build.phase,
build.status, build.parameters) is version-dependent; configure it to notify on phase
FINALIZED so this flow only fires once per build, not once per phase transition.JENKINS_API_TOKEN, JENKINS_NOTIFICATION_WEBHOOK_KEY, and SLACK_WEBHOOK_URL
secrets.FINALIZED.log_healthy
fires.UNSTABLE under the
ratio threshold) with confirm_auto_retry: false; confirm alert_flaky_needs_human fires.confirm_auto_retry: true and repeat; confirm retry_build re-triggers the job and
alert_flaky_auto_retried fires.alert_broken_tests fires and nothing retries.FLAKY_TESTS_AUTO_RETRY if the SAME tests failed inconsistently across builds,
not just that this one build's ratio is low.changeSet check so a build right after a merge is never auto-retried, even if
flaky, since a real regression is more likely immediately after a code change.