Git Triggers & Webhooks
Automate workflows with Git repository event triggers.
Git Triggers & Webhooks
Git triggers allow you to automate actions when events occur in your repositories, such as pushes to specific branches.
Creating a Trigger
Create a webhook trigger for pushes:
sandboxes
.createGitTrigger({
repoId: "repo-id",
trigger: {
event: "push",
branch: ["main"], // Optional: filter by branch
fileGlob: ["*.js"], // Optional: filter by file patterns
},
action: {
type: "webhook",
url: "https://your-webhook-url.com",
},
})
.then((result) => {
console.log(`Trigger created: ${result.triggerId}`);
});Webhook Payload
The webhook receives the following payload:
interface GitTriggerPayload {
repoId: string;
branch: string; // The branch that was updated
commit: string; // The SHA of the commit
}Webhook Signing
Webhooks include a signature in the x-freestyle-signature header for verifying request authenticity. The signature is a JWT (EdDSA) containing a body_sha256 field with the SHA256 hash of the webhook payload.
The public key for verification is available at https://git.freestyle.sh/.well-known/jwks.json.
To verify a webhook:
import crypto from 'crypto';
import { createRemoteJWKSet, jwtVerify } from 'jose';
const JWKS = createRemoteJWKSet(new URL('https://git.freestyle.sh/.well-known/jwks.json'));
async function verifyWebhook(request) {
const signature = request.headers['x-freestyle-signature'];
const bodyText = await request.text(); // Get raw body text
// Verify JWT signature
const { payload } = await jwtVerify(signature, JWKS, {
algorithms: ['EdDSA'],
});
// Verify payload hash
const payloadHash = crypto
.createHash('sha256')
.update(bodyText)
.digest('hex');
if (payload.body_sha256 !== payloadHash) {
throw new Error('Payload verification failed');
}
// Parse body after verification
const body = JSON.parse(bodyText);
return { payload, body };
}Listing Triggers
sandboxes
.listGitTriggers({
repoId: "repo-id",
})
.then((triggers) => {
console.log(triggers);
});Deleting Triggers
sandboxes
.deleteGitTrigger({
repoId: "repo-id",
triggerId: "trigger-id",
})
.then(() => {
console.log("Trigger deleted");
});Local Development
For local development, use a tool like Tailscale to create a secure tunnel to your localhost.
Install Tailscale following the quickstart guide, then expose your local server:
# Replace 3000 with your server's port
tailscale funnel 3000The output provides a public URL:
Available on the internet:
https://<device name>.<tailnet id/name>.ts.net/
|-- proxy http://127.0.0.1:3000
Press Ctrl+C to exit.Use this URL as the webhook URL in your trigger configuration.