Blueprints

CI/CD with a GitHub webhook trigger in production and a manually-supplied JSON-type input for local testing

Source

yaml
id: ci-cd-github-webhook
namespace: company.team

inputs:
  - id: payload
    type: JSON

tasks:
  - id: return
    type: io.kestra.plugin.core.debug.Return
    format: "{{ trigger.body.pull_request.comments_url ??
      inputs.payload.pull_request.comments_url }}"

  - id: python_action
    type: io.kestra.plugin.scripts.python.Script
    taskRunner:
      type: io.kestra.plugin.scripts.runner.docker.Docker
    containerImage: ghcr.io/kestra-io/pydata:latest
    script: |
      import requests
      import json

      url = "{{ outputs.return.value }}"

      headers = {
          'Authorization': 'token {{ secret('GITHUB_ACCESS_TOKEN') }}',
          'Accept': 'application/vnd.github.v3+json'
      }
      payload = {'body': 'hello from `{{ execution.id }}` in `{{ flow.id }}`'}
      response = requests.post(url, headers=headers, json=payload)

      if response.status_code == 201:
          print("Comment successfully created.")
      else:
          print(f"Failed to create comment: {response.text}")

triggers:
  - id: github
    type: io.kestra.plugin.core.trigger.Webhook
    key: "{{ secret('WEBHOOK_KEY') }}"
    conditions:
      - type: io.kestra.plugin.core.condition.ExpressionCondition
        expression: "{{ trigger.body.pull_request.state == 'open' and
          trigger.body.pull_request.comments_url }}"

About this blueprint

DevOps Git Task Runner API

This flow can be used as a template to implement a CI/CD pipeline that processes event payload from a GitHub webhook trigger. In this example, any time you open a new Pull Request, the flow will be triggered and the flow will use the payload information to implement custom actions. Here, we simply add a comment to the pull request using the Pull Request's comment URL from the event payload, but your use case might require retrieving information such as branch name, etc.
To facilitate local testing, the expression '{{ trigger.body.pull_request.comments_url ?? inputs.payload.pull_request.comments_url }}' will make sure that the flow uses a value from the webhook if the flow is triggered via a webhook, and will otherwise use the value from a manually provided input e.g. a JSON payload. This way, you can test the workflow end-to-end using a mock data provided as a JSON-type input before testing it with live data from a webhook. For more information about this usage pattern, check the following blog post.

Return

Script

Docker

Webhook

Expression Condition

New to Kestra?

Use blueprints to kickstart your first workflows.

Get started with Kestra