New to Kestra?
Use blueprints to kickstart your first workflows.
Build event-driven CI/CD in Kestra from GitHub pull request webhooks, post automated PR comments, and test the same logic locally with mock JSON payloads.
Run CI/CD logic the moment a GitHub pull request opens, without polling and without waiting on a separate scheduler. This blueprint listens for GitHub pull request webhook events, extracts the pull request metadata from the payload, and posts an automated comment back to the PR through the GitHub REST API. The same flow can be replayed locally with a hand-supplied JSON payload, so you can develop and debug webhook-driven automation offline before it ever sees live traffic. It solves a common pain point: GitHub Actions and similar tools are hard to iterate on and troubleshoot because every change needs a real event to fire.
io.kestra.plugin.core.trigger.Webhook trigger exposes a webhook endpoint secured by a key, and only fires when its io.kestra.plugin.core.condition.Expression condition confirms the pull request state is open and a comments_url is present.return task (io.kestra.plugin.core.debug.Return) resolves the GitHub comments URL using {{ trigger.body.pull_request.comments_url ?? inputs.payload.pull_request.comments_url }}, so it reads live webhook data in production and falls back to the payload JSON input during local runs.python_action task (io.kestra.plugin.scripts.python.Script) runs on a io.kestra.plugin.scripts.runner.docker.Docker task runner with the requests dependency and POSTs a comment back to the resolved URL, tagging it with {{ execution.id }} and {{ flow.id }}.The Webhook trigger turns any GitHub event into a first-class execution, so reactions are immediate rather than scheduled. Each run is fully observable with retries, replays, and a complete execution history and lineage, which native CI runners rarely expose. The whole pipeline is declarative YAML you can version and review. The decisive gap GitHub's own automation cannot fill: you cannot easily replay a past event or run the exact same logic offline with a mock payload, whereas here the ?? fallback makes local testing trivial.
WEBHOOK_KEY: the secret key that authenticates the webhook endpoint.GITHUB_ACCESS_TOKEN: a GitHub token with permission to comment on pull requests.WEBHOOK_KEY and GITHUB_ACCESS_TOKEN secrets to your Kestra instance.github trigger.payload input.trigger.body.action to handle opened, synchronized, or closed events differently.