LabHit Docs

Webhook Integration

This is how LabHit runs inside the CI you already use, today. Point a repository's push webhook at a LabHit server, and every push clones the repo, reads the .labhit.yaml at the repository root, and runs that pipeline — isolated and policy-checked — with no change to your existing setup.

A dedicated GitHub App experience (commit status checks, a connect-your-repo flow, and per-repo secrets) is on the roadmap. The webhook receiver described here is the supported "runs inside your CI" path in the current release.

How It Works

  1. A push event hits POST /webhook on your LabHit server.
  2. LabHit verifies the request signature and rejects anything unrecognized.
  3. It clones the repository at the pushed commit.
  4. It reads .labhit.yaml (or .labhit.yml) from the repository root.
  5. It runs the pipeline and returns a JSON result with the run ID.

Where pipelines live. The webhook flow reads .labhit.yaml at the repo root. When you run locally with labhit run, the engine reads .labhit/pipeline.yaml instead. The YAML format is identical.

Setup

1. Configure the Webhook Secret

Set the LABHIT_WEBHOOK_SECRET environment variable on your LabHit server:

export LABHIT_WEBHOOK_SECRET="your-secret-here"

2. Add .labhit.yaml to Your Repository Root

Commit a pipeline to the root of the repository you want to build:

engine: "1"

pipeline:
  name: ci

stages:
  test:
    run: make test

  build:
    after: [test]
    run: make build

See the Pipeline Reference for the full YAML vocabulary.

3. Register the Webhook

GitHub:

  1. Go to your repository → Settings → Webhooks → Add webhook
  2. Payload URL: https://your-server.example.com/webhook
  3. Content type: application/json
  4. Secret: same value as LABHIT_WEBHOOK_SECRET
  5. Events: select "Just the push event"

GitLab:

  1. Go to your project → Settings → Webhooks
  2. URL: https://your-server.example.com/webhook
  3. Secret token: same value as LABHIT_WEBHOOK_SECRET
  4. Trigger: Push events

That's it. Push to the repository, and the pipeline runs.

Alternative: A Server-Defined Pipeline Template

If you'd rather define one pipeline on the server instead of committing a file to each repository, set LABHIT_WEBHOOK_PIPELINE to a YAML template. When this variable is set, it takes precedence over the repository's .labhit.yaml and runs for every push, with webhook variables injected:

export LABHIT_WEBHOOK_PIPELINE='engine: "1"
pipeline:
  name: ci-${{ webhook.repository }}
stages:
  checkout:
    run: git clone https://github.com/${{ webhook.repository }} repo && cd repo && git checkout ${{ webhook.commit }}
  test:
    after: [checkout]
    run: cd repo && make test
  build:
    after: [test]
    run: cd repo && make build'

Template Variables

These variables are substituted into the server-defined template:

Variable Description Example
${{ webhook.repository }} Full repository path Lab-Hit/labhit
${{ webhook.ref }} Git ref that was pushed refs/heads/main
${{ webhook.commit }} Commit SHA abc123def456
${{ webhook.provider }} Source provider github or gitlab

Response Format

The webhook endpoint returns a JSON response:

{
  "accepted": true,
  "provider": "github",
  "repository": "Lab-Hit/labhit",
  "ref": "refs/heads/main",
  "commit": "abc123def456",
  "run_id": "019506a3-1234-7000-8000-000000000001",
  "status": "Success",
  "source": ".labhit.yaml"
}

The source field reports which pipeline ran (.labhit.yaml or the server template). When no pipeline can be found and no template is configured, run_id is null.

Security

  • HMAC-SHA256 validation: GitHub webhooks are validated using the X-Hub-Signature-256 header
  • Token validation: GitLab webhooks are validated using the X-Gitlab-Token header with constant-time comparison
  • Reject unknown providers: Requests without recognized provider headers are rejected with 400
  • Reject invalid payloads: Non-JSON bodies are rejected with 400

Monitoring

Webhook-triggered pipeline runs appear in the dashboard alongside manually triggered runs. Use the SSE log stream at /pipeline/{run_id}/logs to monitor execution in real time.