Triggers and Webhooks
Triggers let you automate actions when events occur in your git repositories, such as pushes to specific branches.
Creating a Trigger
Create a webhook trigger that fires on push events.
import { freestyle } from "freestyle-sandboxes";
const { repo } = await freestyle.git.repos.create();
await repo.createTrigger({
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",
},
});When your trigger is activated, a payload is sent to the specified URL in the following format.
interface GitTriggerPayload {
repoId: string;
branch: string; // The branch that was updated
commit: string; // The SHA of the commit
}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 you can use as the webhook URL in your trigger configuration.
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.
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
List all triggers for a repository.
const triggers = await repo.listTriggers();
console.log(triggers);Deleting Triggers
Remove a trigger by its ID.
await repo.deleteTrigger({
triggerId: "trigger-id",
});