docs Webhooks y CI/CD
Webhooks y CI/CD
Despliegues automáticos lanzados por pushes de Git, pull requests y pipelines de CI.
Cómo funciona el despliegue automático
Cuando DeployKit recibe un evento push, busca las aplicaciones cuyo repositorio y rama coinciden y encola un despliegue para cada una, exactamente igual que si hubieras pulsado Deploy. Los eventos de pull request / merge request crean, actualizan y limpian los despliegues de preview. Las propias apps de preview nunca coinciden con los eventos push. Si no coincide ninguna, el endpoint responde con un mensaje explicativo en lugar de un error.
Endpoints
/api/webhooks/github/api/webhooks/gitlab/api/webhooks/genericLas peticiones que no superan la verificación reciben un 401. Los tres endpoints comparten un límite de 120 peticiones por minuto por IP.
GitHub: usa la GitHub App
Para github.com, la configuración recomendada es la GitHub App. Registra su propio webhook, así que las aplicaciones conectadas no necesitan ningún webhook por repositorio: la sección Webhook de la aplicación simplemente indica que lo gestiona la App. Las entregas de la App se verifican con el secreto de webhook de la propia App, y además obtienes estados de commit y comentarios en las PR.
GitHub: webhook de repositorio
Sin la App, añade un webhook en tu repositorio en Settings → Webhooks. La URL también aparece en la pestaña General de la aplicación:
- Payload URL: https://your-deploykit-domain/api/webhooks/github
- Content type: application/json
- Secret: el WEBHOOK_SECRET de tu archivo .env
- Events: 'Pushes', más 'Pull requests' para los despliegues de preview
Las apps sin la conexión de la App se emparejan por URL del repositorio (se ignoran las mayúsculas, la barra final y .git ) y por rama. Un webhook de repositorio sigue funcionando después de registrar una GitHub App: se aceptan ambos secretos. Si más tarde conectas la app a través de la App, la entrega duplicada del webhook antiguo se ignora (las apps conectadas solo coinciden por instalación e id de repositorio), de modo que un push nunca despliega dos veces; puedes eliminarlo.
Webhooks de GitLab
En tu proyecto de GitLab, ve a Settings → Webhooks y añade:
- URL: https://your-deploykit-domain/api/webhooks/gitlab
- Secret token: el WEBHOOK_SECRET de tu archivo .env
- Triggers: 'Push events', más 'Merge request events' para los despliegues de preview
Abrir, actualizar o reabrir una merge request despliega su preview; fusionarla o cerrarla elimina la preview.
Webhook genérico (CI, Bitbucket, Gitea, scripts)
Cualquier sistema puede lanzar un despliegue enviando un payload JSON de tipo push a /api/webhooks/generic con una cabecera X-Webhook-Token . La rama se obtiene de ref y el repositorio de repository.clone_url, repository.html_url o repository.links.html.href (Bitbucket). Se despliega cada aplicación que coincida con esa URL y rama, incluidas las apps conectadas mediante la GitHub App.
curl -X POST https://your-deploykit-domain/api/webhooks/generic \
-H "Content-Type: application/json" \
-H "X-Webhook-Token: $DEPLOYKIT_WEBHOOK_TOKEN" \
-d '{
"ref": "refs/heads/main",
"repository": { "clone_url": "https://github.com/acme/web.git" }
}'El token es el WEBHOOK_SECRET global o el secreto de webhook propio de una aplicación. El secreto por app (de 16 a 200 caracteres) se establece mediante la API con application.update (webhookSecret); una vez definido, esa app solo se despliega con su propio secreto, de modo que puedes dar a un pipeline de CI acceso a una sola app y rotarlo sin tocar el secreto global. Los campos opcionales after / head_commit.id y head_commit.message etiquetan el despliegue; el despliegue siempre compila el head de la rama.
Desplegar desde CI/CD
El despliegue automático en cada push suele hacer innecesaria la integración con CI. Para desplegar solo después de que pasen los tests, asegúrate de que la aplicación no reciba también eventos push (sin webhook de repositorio y sin estar conectada a través de la GitHub App: las apps conectadas se despliegan en cada push) y llama después al endpoint genérico como último paso de CI:
# .github/workflows/deploy.yml
name: Deploy after tests
on:
push:
branches: [main]
jobs:
test-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: npm test
- name: Trigger DeployKit deployment
run: |
curl -fsS -X POST https://panel.yourdomain.com/api/webhooks/generic \
-H "Content-Type: application/json" \
-H "X-Webhook-Token: ${{ secrets.DEPLOYKIT_WEBHOOK_TOKEN }}" \
-d '{"ref":"${{ github.ref }}","after":"${{ github.sha }}","repository":{"clone_url":"${{ github.server_url }}/${{ github.repository }}.git"}}'También puedes llamar a la API tRPC con una sesión de usuario: inicia sesión con auth.login y llama a application.deploy con el id de la app. El usuario necesita el rol de operador en el proyecto, los tokens de acceso caducan a los 15 minutos y un despliegue que ya esté en curso devuelve un conflicto.
TOKEN=$(curl -s -X POST https://panel.yourdomain.com/trpc/auth.login \
-H "Content-Type: application/json" \
-d '{"email":"ci@example.com","password":"..."}' \
| jq -r '.result.data.accessToken')
curl -X POST https://panel.yourdomain.com/trpc/application.deploy \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"id":"your-app-id"}'Seguridad de los webhooks
- GitHub: HMAC-SHA256 de los bytes exactos de la petición, comprobado con el secreto de webhook de la GitHub App o con WEBHOOK_SECRET (se acepta cualquiera de los dos)
- GitLab: X-Gitlab-Token comparado con WEBHOOK_SECRET
- Generic: X-Webhook-Token comparado con el secreto propio de la app o con WEBHOOK_SECRET; sin un token válido, el endpoint nunca revela si un repositorio coincidió
- Todas las comparaciones son de tiempo constante; si no hay ningún secreto configurado, las entregas se rechazan (fail-closed)
WEBHOOK_SECRET pasa a ser opcional una vez registrada una GitHub App, pero conserva el valor para GitLab, el endpoint genérico y cualquier webhook de repositorio creado a mano.
¿El push no despliega? Revisa la entrega en tu proveedor de Git (GitHub: Settings → Webhooks → Recent Deliveries). Un 401 significa que el secreto no coincide; y como la firma de GitHub se calcula sobre el cuerpo sin procesar, cualquier elemento entre GitHub y DeployKit que reescriba el cuerpo de la petición también la romperá. Un 200 con "No applications found" significa que la URL del repositorio o la rama configuradas en DeployKit no coinciden con el push.