Get icon
OutputValues icon
If icon
SlackIncomingWebhook icon
Log icon
Schedule icon

Jira Stale Issue SLA Compliance Gate

Run a JQL search for stale Jira issues, alert Slack with the issue keys, and log the result for engineering teams.

Categories
Business

An open Jira issue nobody has touched in weeks is easy to miss one ticket at a time; Jira's own board shows every issue looking equally current until someone sorts by updated date and scrolls. This blueprint runs the sort for you, server-side, using Jira's own query language, and reports exactly which issues have gone stale by key, not a guess from a dashboard.

This blueprint was created by Mohit Jeswani.

How it works

  1. search_stale_issues (io.kestra.plugin.jira.issues.Get) runs jql_filter against Jira's search API with fetchType: FETCH, so Jira's own query engine does the staleness filtering server-side instead of this flow paging through every issue to check client-side. Read-only; nothing in Jira is changed. allowFailure: true covers an API or auth error without failing the flow outright.
  2. evaluate (io.kestra.plugin.core.output.OutputValues) reads the matched count directly from the API response's own size field and collects the matched issue keys with a jq filter.
  3. route (io.kestra.plugin.core.flow.If):
    • compliant: logs that nothing currently matches the filter.
    • alert: posts the count and issue keys to Slack.
  4. summary logs the count and severity, closing the governance cycle.
  5. errors alerts Slack if the flow itself fails, for example an expired API token.

What you get

  • A count that is Jira's own server-side JQL match, not a client-side guess computed after paging through the whole project.
  • The exact issue keys in the Slack alert, so whoever responds can jump straight to the ticket instead of re-running the search themselves.
  • A read-only check with zero risk of commenting on or modifying a real issue.

Who it's for

  • Engineering managers and project leads who run a Jira project and need stale issues surfaced on a schedule, not discovered during a sprint retro.
  • Teams evaluating the Jira plugin who want a worked example of issues.Get used in its JQL search mode for a governance check, distinct from this repo's existing Jira blueprints, which only use issues.Create to open a new issue on flow failure rather than auditing existing ones.

Why orchestrate this with Kestra

Jira's JQL answers one query at a time; it does not keep a schedule, compare the result count against a tolerance you declare, or notify a Slack channel when stale issues pile up. Kestra keeps jql_filter and max_stale_count as flow inputs, turns the query into a Slack page naming the actual issue keys, and keeps a full execution history of every run.

Prerequisites

  • A Jira Cloud or Server project with at least one issue old enough to confirm the filter logic against.
  • A Jira API token for jira_username.
  • A Slack incoming webhook URL.

This flow calls the Jira REST API directly over HTTPS; there is no official local Jira emulator, so search_stale_issues cannot be exercised against a local Docker container.

Secrets

  • JIRA_API_TOKEN: the Jira API token used by search_stale_issues. In Kestra OSS, provide it as the base64-encoded environment variable SECRET_JIRA_API_TOKEN.
  • SLACK_WEBHOOK_URL: used by alert and the errors block. In Kestra OSS, provide it as the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.

Inputs

Input Default Purpose
jql_filter project = DEMO AND status NOT IN (Done, Closed) AND updated <= -14d JQL selecting the issues to audit
max_stale_count 1 Matched-issue count that triggers the Slack alert

Outputs

  • {{ outputs.search_stale_issues.rows }}: every matched issue (key, id, and the requested fields, defaulting to summary, status, description, labels, created, updated).
  • {{ outputs.evaluate.values.stale_count }} / .stale_keys: how many issues matched and their keys, semicolon-joined.
  • {{ outputs.evaluate.values.severity }}: OK, SLA_BREACH, or CRITICAL.

Pitfalls

  • jql_filter is the entire governance policy; a typo in the JQL (an unknown field, a bad operator) makes Jira return an error that this task surfaces via allowFailure, not a silently empty result.
  • maxResults: 50 caps the page size, but issues.Get pages through every result itself until Jira reports no more, so size always reflects the true total match count, not just the first page.
  • Jira's relative-date JQL (-14d) is evaluated by Jira's own server clock at query time, not by this flow; a project in a different timezone than expected can shift which issues count as stale by up to a day.

Quick start

  1. Add the JIRA_API_TOKEN and SLACK_WEBHOOK_URL secrets.
  2. Set jira_base_url, jira_username, and jql_filter to a real project and policy.
  3. Run the flow manually and confirm summary logs a count.
  4. Loosen jql_filter's date window until it matches a known stale issue, to confirm alert fires with its key.
  5. Enable the daily trigger once jql_filter reflects your real SLA policy.

How to extend

  • Loop over several jql_filter values with io.kestra.plugin.core.flow.Loop to enforce a different staleness policy per project or issue type in one scheduled run.
  • Chain io.kestra.plugin.jira.issues.CreateComment on each matched issue to post a "flagged as stale" note, gated behind an explicit confirm_comment input so commenting never runs by accident.
  • Group stale_keys by the fields.status.name already present in each row to route different statuses to different Slack channels.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.