@plugdash/autobuild
v0.2.0
Published
Fires a Cloudflare Pages, Netlify, or Vercel build hook on every publish from EmDash
Maintainers
Readme
@plugdash/autobuild
Publish in admin, live in 60 seconds. Triggers a Cloudflare Pages, Netlify, or Vercel build hook every time you publish content in EmDash. One config line, one env var, done. Only on EmDash - this is the plugin that makes a headless CMS feel live.
Install
pnpm add @plugdash/autobuildRegister
// astro.config.mjs
import { defineConfig } from "astro/config";
import emdash from "emdash";
import { autobuildPlugin } from "@plugdash/autobuild";
export default defineConfig({
integrations: [
emdash({
plugins: [
autobuildPlugin({
hookUrl: import.meta.env.CF_PAGES_DEPLOY_HOOK,
collections: ["posts"],
debounceMs: 5000,
}),
],
}),
],
});Store the hook URL as an environment variable. Never commit it.
Getting a deploy hook URL
- Cloudflare Pages: Project -> Settings -> Builds & deployments -> Deploy hooks. Creates a URL like
https://api.cloudflare.com/client/v4/pages/webhooks/deploy_hooks/... - Netlify: Site settings -> Build & deploy -> Build hooks. Creates a URL like
https://api.netlify.com/build_hooks/... - Vercel: Project Settings -> Git -> Deploy Hooks. Creates a URL like
https://api.vercel.com/v1/integrations/deploy/...
Configuration
Admin dashboard
After installing, open the EmDash admin and go to Plugins - Autobuild - Settings. Hook URL, method, debounce window, and collections are available there. The current hook URL is shown masked (hostname + first 8 chars of path); leave the field blank on save to keep the existing value.
Config options
| Option | Type | Default | Description |
| -------------- | -------------------------- | --------------- | --------------------------------------------------------- |
| hookUrl | string | required | Deploy webhook URL. Must be https. Must not be localhost or a private IP |
| method | "POST" \| "GET" | "POST" | HTTP method. Vercel uses POST, Cloudflare Pages uses POST, Netlify uses POST or GET |
| collections | string[] | all collections | Only trigger rebuilds for these collections |
| statuses | ContentStatus[] | ["published"] | Statuses that trigger a rebuild |
| debounceMs | number | 5000 | Coalesce rapid publishes into one deploy |
| timeout | number | 5000 | Request timeout in milliseconds |
| body | Record<string, unknown> | none | Optional JSON body. Most deploy hooks accept empty POST |
| headers | Record<string, string> | none | Optional additional request headers |
| allowedHosts | string[] | auto | Override the auto-parsed allowedHosts (for CDN/LB setups) |
How it works
- Plugin registers on
content:afterSaveandcontent:afterDeletewithread:contentandnetwork:fetchcapabilities. - When a published post is saved (or any post is deleted), the plugin schedules a debounced webhook fire.
- After the debounce window elapses, it POSTs to the hook URL via
ctx.http.fetch(). - The original save/delete event is never blocked - webhook failures log but do not fail the admin operation.
Security
autobuild validates the hook URL before every fetch:
https://only. No http, no file, no other schemes.- Blocks
localhost,127.x.x.x,0.0.0.0,::1. - Blocks RFC1918 private ranges:
10.x.x.x,172.16-31.x.x,192.168.x.x. - Blocks
169.254.x.x(link-local, including the AWS instance metadata endpoint).
A misconfigured hookUrl fails closed: no fetch is made, an error is logged.
What it does not do
- Does not retry failed deploys. The next publish retries.
- Does not verify that the deploy succeeded - check your Pages/Netlify/Vercel dashboard for deploy status.
- Does not sign or authenticate requests. Deploy hooks are already secret URLs.
- Does not persist debounce state across process restarts. A pending webhook is dropped on restart.
- Does not ship a UI component. This plugin is pure infrastructure.
