Bridge Baserow data with GitHub engineering workflows

GitHub is where technical execution happens (code, issues, deployments). Baserow is where business context lives (roadmaps, client approvals, onboarding checklists).

GitHub is where code lives. Baserow is where the business logic surrounding that code lives.

GitHub handles the code, version control, and issue tracking. However, for non-technical stakeholders; like Product, Sales, and Success teams; GitHub’s “Pull Requests” and “Commit Hashes” are opaque.

Baserow handles the structured roadmap, resource allocation, and cross-functional reporting. It translates technical progress into business status, handling roadmap prioritization, client communication, and release approvals.

Both tools are API-first. GitHub’s REST API (and GraphQL) allows for deep manipulation of repositories, issues, and pull requests. Baserow’s API handles the structured metadata that surrounds that code; deadlines, client priorities, and sprint planning.

Using both gives you a combination of code and context:

  • GitHub handles the technical execution (commits, diffs, branches).
  • Baserow handles the business logic (roadmap priorities, client reporting, resource capacity).

This guide focuses on the Universal Infrastructure pattern to connect both. We will build a standard Event Gateway that allows Baserow to trigger any action in GitHub and receive a confirmation back.

Use cases

  • Roadmap Sync: Keep product managers and developers aligned by syncing GitHub Issues to Baserow features.
  • Bug Triage: Allow support teams to log bugs in Baserow that instantly appear in the developer’s backlog.
  • Release Logs: Auto-generate changelogs in Baserow whenever a GitHub Release is published.

Architecture: Dispatch Loop

The most robust way to connect Baserow to GitHub is via the Repository Dispatch API. This acts as a universal remote control.

  1. The Signal (Baserow): Baserow sends a generic “Dispatch Event” with a payload (e.g., {"row_id": 123, "action": "provision"}).
  2. The Engine (GitHub): GitHub accepts the signal, authenticates it, and routes it to the correct Workflow (YAML file).
  3. The Feedback (GitHub): The workflow executes the task and uses the API to update the specific Baserow row with the result.

Prerequisites

Step 1: Configure the Dispatcher (Baserow)

We need Baserow to send a standardized signal. We will use Baserow Automations to format the data into the structure GitHub expects.

  1. In Baserow: Go to AutomationsCreate Automation.
  2. Trigger: Choose your event (e.g., “Row Created” or “Form Submitted”).
  3. Action: Select Send HTTP Request.
    • Method: POST

    • URL: https://api.github.com/repos/[OWNER]/[REPO]/dispatches

    • Headers:

      • Authorization: Bearer [YOUR_GITHUB_PAT]
      • Accept: application/vnd.github.v3+json
      • User-Agent: Baserow
    • Body (JSON):

      `{
        "event_type": "baserow_trigger",
        "client_payload": {
          "row_id": "{{id}}",
          "task_name": "{{Name}}",
          "status": "{{Status}}"
        }
      }`
      

Why this works universally: We are sending the row_id in the client_payload. This is the key that allows GitHub to find the exact record to update later.

Step 2: Configure the Receiver (GitHub)

GitHub needs to know how to listen for this specific signal. You define this in a YAML file inside your repository.

  1. In GitHub: Create a file at .github/workflows/baserow_handler.yml.
  2. Paste the Universal Listener:
`name: Baserow Dispatch Handler

on:
  repository_dispatch:
    types: [baserow_trigger]

jobs:
  handle_request:
    runs-on: ubuntu-latest
    steps:
      # 1. READ: Capture the context sent by Baserow
      - name: Log Payload
        run: |
          echo "Processing Row ID: ${{ github.event.client_payload.row_id }}"
          echo "Task: ${{ github.event.client_payload.task_name }}"

      # 2. ACKNOWLEDGE: Tell Baserow "I received the request"
      - name: Update Baserow Status
        run: |
          curl -X PATCH \
            -H "Authorization: Token ${{ secrets.BASEROW_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d '{"Status": "Processing"}' \
            "https://api.baserow.io/api/database/rows/table/[YOUR_TABLE_ID]/${{ github.event.client_payload.row_id }}/?user_field_names=true"

      # 3. EXECUTE: Your specific logic goes here (The "Swappable" Part)
      # Example: Create an Issue, Run a Script, or Invite a User
      - name: Run Logic
        run: echo "Executing logic for ${{ github.event.client_payload.task_name }}..."

      # 4. FINISH: Report success back to Baserow
      - name: Mark Complete
        if: success()
        run: |
          curl -X PATCH \
            -H "Authorization: Token ${{ secrets.BASEROW_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d '{"Status": "Done", "GitHub Run ID": "${{ github.run_id }}"}' \
            "https://api.baserow.io/api/database/rows/table/[YOUR_TABLE_ID]/${{ github.event.client_payload.row_id }}/?user_field_names=true"`

Note: Ensure you add BASEROW_TOKEN to your GitHub Repository Secrets.

Step 3: The Success/Failure Loop

Instead of a single “Finish” step, we split the reporting into two potential outcomes. This ensures that if a script crashes or a deployment fails, the Business team sees a “Failed” status in Baserow immediately.

Add this to the end of your baserow_handler.yml:

# 4a. REPORT SUCCESS: Only runs if all previous steps passed
      - name: Mark Complete in Baserow
        if: success()
        run: |
          curl -X PATCH \
            -H "Authorization: Token ${{ secrets.BASEROW_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d '{"Status": "Done", "Result Notes": "Successfully executed at ${{ github.event.repository.updated_at }}"}' \
            "https://api.baserow.io/api/database/rows/table/[YOUR_TABLE_ID]/${{ github.event.client_payload.row_id }}/?user_field_names=true"

      # 4b. REPORT FAILURE: Only runs if any previous step failed
      - name: Mark Failed in Baserow
        if: failure()
        run: |
          curl -X PATCH \
            -H "Authorization: Token ${{ secrets.BASEROW_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d '{"Status": "Failed", "Error Log": "Check GitHub Run ID: ${{ github.run_id }}"}' \
            "https://api.baserow.io/api/database/rows/table/[YOUR_TABLE_ID]/${{ github.event.client_payload.row_id }}/?user_field_names=true"

Universal Application

By using this single pattern (repository_dispatch + row_id payload), you can power endless workflows just by changing Step 3 in the YAML file.

Your Use Case Baserow Input GitHub Action (Step 3)
Issue Tracking “Bug Report” row created. Uses actions/create-issue to create a GitHub Issue and saves the Issue URL back to Baserow.
User Onboarding “New Hire” row created. Runs a script to invite the user to the GitHub Organization and adds them to the correct Team.
Environment Provisioning “Client A” row marked Approved. Runs Terraform to spin up a new server and saves the IP address back to Baserow.
Content Publishing “Blog Post” row marked Ready. Triggers a site rebuild (Pages/Jekyll) to publish the new content.

Alternative: Passive Monitoring (GitHub Webhooks)

While Repository Dispatch is the Active way to trigger GitHub from Baserow, GitHub Webhooks are the Passive way to update Baserow when things happen naturally in your repository (like a developer closing an issue or merging code).

The Pattern: GitHub → Baserow

  1. The Event: A developer merges a Pull Request in GitHub.
  2. The Webhook: GitHub sends a massive JSON payload to your Baserow Webhook URL.
  3. The Automation: Baserow receives the payload, finds the matching row (e.g., via the Issue number), and updates the status to “Merged.”

How to Connect:

  1. In Baserow: Create an Automation with the trigger “Receive an HTTP request”. Copy the unique Webhook URL provided.
  2. In GitHub: Go to Settings → Webhooks → Add webhook.
    • Payload URL: Paste your Baserow URL.
    • Content type: application/json.
    • Events: Select “Individual events” (e.g., Pull Requests, Issues, or Pushes).
  3. In Baserow (Mapping): Use the Baserow automation builder to “map” the incoming GitHub data. For example, map repository.name to a text field and sender.login to your “Developer” field.

Comparison: Dispatch vs. Webhook

Method Direction Rationale
Repository Dispatch Baserow → GitHub Action-Driven: Use this when a human in Baserow needs to “start” a technical process (Deploying, Provisioning).
Native Webhooks GitHub → Baserow Status-Driven: Use this when Baserow needs to “listen” to what developers are doing in their natural environment (Coding, Merging).

Using Baserow Automations + Repository Dispatch offers better security and control:

  1. Authentication: Repository Dispatch requires a secure Token, whereas standard webhooks often require complex signature verification logic on the receiving end.
  2. Custom Payloads: You can format the JSON exactly how your script needs it, rather than parsing a massive, generic webhook payload.
  3. Rate Limits: GitHub handles the queuing. If you trigger 100 events at once, GitHub Actions queues them up, preventing your server from crashing.

Universal Best Practice: Source ID

Whether you use Dispatch or Webhooks, always store the foreign ID.

  • Store the Baserow Row ID in your GitHub issue descriptions.
  • Store the GitHub Issue Number in a Baserow numerical field.

This Anchor ensures that your automation can always find the correct record, regardless of how many thousands of rows or issues you have.


Still need help? If you’re looking for something else, please feel free to make recommendations or ask us questions; we’re ready to assist you.