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
- A push event hits
POST /webhookon your LabHit server. - LabHit verifies the request signature and rejects anything unrecognized.
- It clones the repository at the pushed commit.
- It reads
.labhit.yaml(or.labhit.yml) from the repository root. - It runs the pipeline and returns a JSON result with the run ID.
Where pipelines live. The webhook flow reads
.labhit.yamlat the repo root. When you run locally withlabhit run, the engine reads.labhit/pipeline.yamlinstead. 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:
- Go to your repository → Settings → Webhooks → Add webhook
- Payload URL:
https://your-server.example.com/webhook - Content type:
application/json - Secret: same value as
LABHIT_WEBHOOK_SECRET - Events: select "Just the push event"
GitLab:
- Go to your project → Settings → Webhooks
- URL:
https://your-server.example.com/webhook - Secret token: same value as
LABHIT_WEBHOOK_SECRET - 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-256header - Token validation: GitLab webhooks are validated
using the
X-Gitlab-Tokenheader 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.