Webhooks are the backbone of Shipyard’s CI pipeline. Every time you push to a connected branch, GitHub sends a signed HTTP payload to Shipyard’s webhook endpoint. Shipyard verifies the signature, extracts the commit details, creates a build record, and triggers the build engine — all before returning a response to GitHub.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Verifieddanny/cicd-engine/llms.txt
Use this file to discover all available pages before exploring further.
How webhook registration works
When you create a project viaPOST /api/project, Shipyard immediately calls the GitHub API to register a webhook on your repository. You do not need to configure anything in GitHub manually.
- Shipyard registers the webhook to fire on
pushandpull_requestevents. Onlypushevents trigger builds;pull_requestevents are registered but not currently processed. - The webhook callback URL is set to
<WEBHOOK_CALLBACK>/api/webhookusing the value in your.env. - The webhook is configured with your
WEBHOOK_SECRETso GitHub can sign every payload. - Shipyard stores the GitHub-assigned webhook ID in the project record. When you delete a project, Shipyard uses this ID to remove the webhook from GitHub automatically.
Webhook verification
Every incoming request toPOST /api/webhook is authenticated via HMAC-SHA256 signature — there is no JWT check on this endpoint.
GitHub attaches a X-Hub-Signature-256 header to every webhook delivery formatted as sha256=<hex-digest>. Shipyard recomputes the HMAC using the raw request body and your WEBHOOK_SECRET, then compares the two values with a timing-safe comparison (timingSafeEqual from Node’s crypto module). This prevents signature brute-forcing through timing attacks.
Requests that are missing the signature header, or whose signature does not match, are rejected with a 401 response.
What happens on a push
When GitHub delivers a valid push event:- Shipyard reads the
X-GitHub-Eventheader. Apingevent (sent when the webhook is first created) is acknowledged and ignored. - For
pushevents, Shipyard extracts the commit message, author name, commit hash (payload.after), branch, and repository URL from the payload. - A new build record is inserted with status
queuedand the extracted commit metadata. - Shipyard responds to GitHub with
201to acknowledge receipt. - The build engine runs asynchronously: it clones the repo at the exact commit hash, builds a Docker image, runs your build command inside the container, and streams logs via Socket.io.
Testing webhooks locally
GitHub cannot reachlocalhost, so you need a tunneling tool to expose your local server to the internet during development.
Run either of the following commands to create a public tunnel to port 8080:
WEBHOOK_CALLBACK in your .env:
.env so the new callback URL is used when Shipyard registers webhooks for new projects.
The webhook endpoint
POST /api/webhook accepts the raw JSON payload from GitHub. The relevant fields Shipyard reads from a push event are:
| Field | Source in payload |
|---|---|
| Repository URL | payload.repository.html_url |
| Branch | payload.ref (stripped of refs/heads/ prefix) |
| Commit message | payload.commits[0].message |
| Commit author | payload.commits[0].author.name |
| Commit hash | payload.after |
404.