GitHub Integration Setup Guide

GitHub Integration Setup Guide

This guide walks you through connecting Lathe Studio to GitHub for CI/CD pipeline integration.


Prerequisites#

  • GitHub account (personal or organization)
  • GitHub repository with Actions workflows
  • Project admin access in Lathe Studio

Overview#

The GitHub integration enables:

  • CI/CD Webhooks: Automatically create builds when GitHub Actions workflows complete

Connecting GitHub#

Step 1: Create a GitHub Connection in Lathe Studio

  1. In Lathe Studio, open your project and go to Project Settings → Integrations
  2. Find GitHub and click Connect
  3. Lathe Studio generates a webhook URL containing a unique token and a webhook secret — copy both

Step 2: Configure the GitHub Webhook

  1. In GitHub, go to your repository
  2. Navigate to Settings > Webhooks
  3. Click Add webhook
  4. Configure:
    • Payload URL: the webhook URL from Lathe Studio (includes ?token=...)
    • Content type: application/json
    • Secret: the webhook secret from Lathe Studio (enables X-Hub-Signature-256 verification)
    • SSL verification: Enable
  5. Events: Select "Let me select individual events", check "Workflow runs" (or "Send me everything")
  6. Click Add webhook

Step 3: Test the Integration

  1. Trigger a workflow run in GitHub Actions
  2. Open the GitHub connection panel in Lathe Studio to see recent events
  3. If the workflow name matches a pipeline with auto-create enabled, a build appears on the Releases page

Authentication#

GitHub webhooks are authenticated by the unique token in the webhook URL (?token=...), which identifies your project's connection. When a webhook secret is configured on the connection, Lathe Studio also requires a valid X-Hub-Signature-256 HMAC-SHA256 signature on every request.


How It Works#

  1. Workflow Completes → GitHub sends the workflow_run event to your webhook URL (/api/webhooks/github?token=...)
  2. Authentication → The token identifies your project's connection; if a secret is configured, the X-Hub-Signature-256 signature must also be valid
  3. Pipeline Matching → The workflow name is matched against the pipelines configured on the connection
  4. Build Creation → When the matching pipeline has auto-create enabled (the default), a build is created in your project as soon as the workflow completes
  5. Review → Every event is recorded in the connection's recent events list, so you can confirm delivery and troubleshoot

Build Queue UI#

The Build Queue on the Releases page holds builds that arrived without a project or release assignment (for example, from the Bitbucket webhook). From the queue you can:

  • Assign to Release: Select an active release for the project
  • Select Project: Navigate to projects if the project was not auto-detected
  • Reject: Remove the build from the queue (no build created)

GitHub Actions Example#

To report test results back to Lathe Studio, create an API key (Settings > Organization > API Keys) with the results:submit scope, store it as the LATHE_STUDIO_API_KEY repository secret, then add this step to your existing .github/workflows/test.yml after your test runner finishes. The if: always() ensures results are sent even if tests fail.

name: Test and Report

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run Tests
        run: npm test -- --reporter=json --outputFile=test-results.json

      - name: Upload Results to Lathe Studio
        if: always()
        env:
          LATHE_API_KEY: ${{ secrets.LATHE_STUDIO_API_KEY }}
        run: |
          # Parse your test framework's JSON output into the Lathe Studio format.
          # Below is an example for Jest — adapt the jq filter to your framework.
          RESULTS=$(jq -c '
            [.testResults[] | .assertionResults[] | select(.status != "pending") | {
              test_identifier: .ancestorTitles + [.title] | join(" > "),
              name: .title,
              status: (if .status == "passed" then "passed" elif .status == "failed" then "failed" else "skipped" end),
              duration_ms: .duration,
              error: (if .failureMessages | length > 0 then .failureMessages[0] else null end)
            }]
          ' test-results.json)

          curl -X POST https://lathe.studio/api/v1/results/ingest \
            -H "Authorization: Bearer $LATHE_API_KEY" \
            -H "Content-Type: application/json" \
            -d "{
              \"build\": {
                \"identifier\": \"${{ github.ref_name }}-${{ github.run_number }}\",
                \"branch\": \"${{ github.ref_name }}\",
                \"commit_sha\": \"${{ github.sha }}\",
                \"url\": \"${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}\"
              },
              \"source\": {
                \"pipeline\": \"github_actions\",
                \"run_id\": \"${{ github.run_id }}\",
                \"run_url\": \"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\"
              },
              \"results\": $RESULTS
            }"

What this does:

  1. Runs your tests and outputs JSON (Jest example shown)
  2. Parses the JSON into Lathe Studio's IngestResult format
  3. Sends everything to POST /api/v1/results/ingest
  4. Lathe Studio automatically:
    • Creates a Build (or re-uses an existing one by identifier)
    • Creates a completed Test Run linked to that Build
    • Matches results to existing Test Cases by test_identifier
    • Auto-creates new Test Cases for unknown identifiers

If your API key is org-scoped (not tied to one project), also include "project_key": "YOUR-PROJECT-CODE" at the top level of the payload.

Response:

{
  "build_id": "uuid",
  "build_display_id": "main-1042",
  "test_run_id": "uuid",
  "test_run_display_id": "RUN-MOB-0123",
  "test_run_url": "/projects/.../runs/...",
  "test_cases_created": 3,
  "test_cases_linked": 47,
  "results_imported": 50
}

Adapting to other test frameworks:

For result files, lathe report <file> --project <code> reads JUnit XML, TestNG XML (testng-results.xml), NUnit 3 XML, xUnit.net v2 XML, and Cucumber JSON. It detects the format from the file or accepts --format to specify one. The direct POST /api/v1/results/ingest endpoint shown above accepts JSON payloads, not raw report files.

FrameworkApproach
JestUse --json --outputFile= then jq to map fields
PytestUse pytest-json-report plugin, map nodeid → test_identifier
JUnit XMLSend the file with lathe report
Cypress, Playwright, Postman (Newman), pytest, Appium-based suitesConfigure their JUnit XML output, then use lathe report

The only requirement is that each result has a stable test_identifier string. Use your existing display codes (TC-MOB-0042) or any unique ID — Lathe Studio will match them automatically.


Troubleshooting#

Builds not appearing

  1. Check webhook delivery in GitHub (Settings > Webhooks > Recent Deliveries)
  2. Verify the webhook URL includes the ?token= query parameter
  3. Ensure the "Workflow runs" event is selected
  4. Check the connection's recent events in Lathe Studio — if the event arrived but no build was created, the workflow name may not match any configured pipeline

Webhook signature verification fails

If using webhook secrets:

  1. Verify the secret in GitHub matches the one shown in the Lathe Studio connection panel
  2. Check that GitHub is sending the X-Hub-Signature-256 header
  3. Ensure the payload hasn't been modified

Security#

  • The webhook URL token identifies your project's connection — treat it as a secret
  • Webhook secrets are stored encrypted and used for HMAC-SHA256 signature verification
  • Results-ingest API keys are hashed using SHA-256 before storage; only the first 12 characters are kept for identification
  • Keys can be revoked at any time
  • All webhook communications use HTTPS

Unlinking GitHub#

To disconnect:

  1. Go to your GitHub repository
  2. Navigate to Settings > Webhooks
  3. Find the Lathe Studio webhook
  4. Click Delete

Note: Previously created builds remain in Lathe Studio. New builds will not be created until reconnected.


Advanced Configuration#

Pipeline Auto-Create

Each pipeline configured on the connection matches events by workflow name and can toggle automatic build creation. When auto-create is off, events are still recorded in the connection's recent events list without creating builds.


For additional help, contact support.