New to Kestra?
Use blueprints to kickstart your first workflows.
Flags open pull requests missing their required CODEOWNERS review, files a GitHub issue per gap, and posts a Slack summary with the verdict.
Diagram unavailable
We could not build the topology for this blueprint. The flow itself is valid, use the YAML on the left to run it.
A CODEOWNERS file says who must review the paths they own, but GitHub never enforces the promise on its own. A pull request can sit open with zero approvals, the owners never get pinged, and the gap only surfaces after a risky change merges and someone asks who approved it. This blueprint closes that loop: it runs when a pull request opens, or from a disabled hourly schedule you switch on, reads every open pull request in one API call, works out which ones are still short of their required approving reviews, files one labeled issue per gap, and posts the verdict to Slack. Failures escalate to the ops channel, and the run exposes the verdict, the open pull request count, and the missing-review list as outputs that a merge gate can read.
pr_opened (io.kestra.plugin.core.trigger.Webhook, keyed with the CODEOWNERS_WEBHOOK_KEY secret) starts a run the moment a pull request opens. hourly_sweep (io.kestra.plugin.core.trigger.Schedule, 0 * * * *) ships with disabled: true and acts as the safety net you enable after the first clean manual run.fetch_open_prs (io.kestra.plugin.core.http.Request) performs a single GET on https://api.github.com/repos/<repo>/pulls?state=open with a Bearer token from the GITHUB_TOKEN secret and the application/vnd.github+json accept header, retrying three times before giving up. No per-pull-request call is made.evaluate_reviews (io.kestra.plugin.scripts.python.Script on python:3.11-slim) receives the response as prs.json. It accepts fixture shaped payloads as well as live ones - plain arrays, items or pull_requests wrappers, double encoded JSON, an empty array, or an empty body - skips drafts when exclude_drafts is on, and counts approving reviews from an embedded reviews list, an approvals style counter, or an approved review decision. Anything below required_approvals lands in missing_reviews with a reason, and the verdict is printed as a single ::{"outputs": ...}:: line.review_gap_gate (io.kestra.plugin.core.flow.If) branches on missing_review_count.file_issue_per_pull_request (io.kestra.plugin.core.flow.Loop) walks missing_reviews and create_review_issue (io.kestra.plugin.github.issues.Create) opens one codeowners and review-required labeled issue per pull request carrying the number, title, author, approvals on record, reason, and link.summarize_review_gaps (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) then posts the verdict, the open count, and the offending pull requests to the channel, so reviewers see the gaps right after the tickets exist.report_all_clear (io.kestra.plugin.core.log.Log) records the quiet verdict, leaving proof the sweep actually ran.errors handler (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) reports any failure with the execution id, because a sweep that dies silently is indistinguishable from a clean one.verdict, open_prs, missing_review_count, missing_reviews) that a downstream merge gate or dashboard can branch on.A cron script can list pull requests, but it cannot react to the pull request opening, open a ticket per gap, notify the channel, escalate its own failure, and keep an execution history proving the sweep ran. Kestra gives the check a webhook trigger, a conditional branch with a loop over the gaps, real plugin tasks for GitHub and Slack, a failure path that pages instead of hiding, and outputs another flow can require before a merge proceeds.
repo input.GITHUB_TOKEN: GitHub token used for the pull request read and for issue creation.SLACK_WEBHOOK_URL: Slack incoming webhook used for the gap summary and failure alerts.CODEOWNERS_WEBHOOK_KEY: Key that authenticates the pull request webhook trigger.repo to your owner/name repository and required_approvals to the review bar your CODEOWNERS policy expects.verdict output - expect COMPLIANT on a healthy repository and ACTION_REQUIRED with issues filed on a neglected one.pr_opened trigger URL, then enable hourly_sweep if you also want the periodic safety net.verdict or missing_review_count outputs.GET /repos/<repo>/contents/<path> call per changed file, or by reading the CODEOWNERS file with io.kestra.plugin.git.Clone.review-required issues with io.kestra.plugin.github.issues.Search before creating another one.missing_reviews on consecutive runs.