Deploy Hooks

One-click deploys from the ready-to-deploy Slack message

What is a deploy hook?

When pull requests merge to your default branch, Coderbuds posts a "ready to deploy" message to Slack that lists everything waiting on a production deployment. Add a deploy hook URL to a repository and that message gains a Deploy now button — one click triggers your deployment, no context switch needed.

A deploy hook fires deploys. It does not record them.

A hook is a one-way button: Coderbuds calls it, your platform deploys, and nothing comes back. A hook deploy also creates no GitHub deployment event, so there is nothing for Coderbuds to pick up either. On its own, a deploy hook leaves your DORA metrics empty and every merged pull request sitting in the ready-to-deploy queue for ever — while the deploys themselves run perfectly well.

If you deploy through a raw platform hook, add the inbound deployment webhook too. It is the half that tells Coderbuds the deploy happened. This is also why adding a hook does not tick off the "deploy tracking" step in your setup checklist: Coderbuds will not claim tracking works until it can actually see a deploy.

How it works

  1. You paste a deploy hook URL into a repository's settings (Team settings → Repositories → Configuration → Deploy hook).
  2. The next time the ready-to-deploy message updates, it includes a Deploy now button.
  3. Clicking the button asks for confirmation, then Coderbuds sends a single POST request to your hook URL.
  4. Your platform builds and deploys. The message flips to "deployed" once Coderbuds sees the production deployment — which needs either a GitHub deployment event or the inbound webhook below. A raw hook produces neither.

Where to get a hook URL

Laravel Forge

Open your site in Forge → App tab → copy the Deployment Trigger URL. Requesting it runs your site's deploy script.

Envoyer

Open your project → SettingsDeployment Hooks → copy the deployment trigger URL.

Laravel Cloud

Open your application's production environmentSettings → copy the Deploy Hook URL. A plain POST deploys the latest commit on the environment's branch.

Deploying via GitHub Actions

If your production deploy runs through a GitHub Actions workflow, choose GitHub Actions as the deploy trigger instead of a hook URL. Coderbuds lists the repository's manually dispatchable workflows (those with a workflow_dispatch trigger), and lets you pick one and fill in the input values it should send with every deploy — booleans, choices and defaults come straight from the workflow file.

This route has a bonus over a raw platform hook: when your workflow's deploy job declares a GitHub environment (e.g. environment: production), GitHub records every run as a deployment. Coderbuds picks that up automatically, so the Slack message flips to "deployed" the moment the run succeeds. A raw platform hook (e.g. calling Laravel Cloud directly) deploys just the same, but bypasses GitHub — Coderbuds can't see when it finishes unless the platform reports back through the inbound deployment webhook below.

Inbound deployment webhook

Deploys that don't go through GitHub — Laravel Cloud's deploy center, Forge quick deploys, Envoyer, or a custom CI script — are invisible to Coderbuds by default. The inbound deployment webhook closes that gap: point your platform's "deployment finished" hook at Coderbuds and every deploy is recorded, feeds your DORA metrics, completes the ready-to-deploy Slack message, and associates the deployed pull requests automatically.

Get the URL from Team settings → Repositories: open the repository, and under the deploy configuration choose Create tracking webhook. It mints a per-repository token the first time and shows the same URL on every visit after that, ready to copy.

Self-hosting, or wiring up several repositories at once? The same URL comes out of an Artisan command, with --rotate to replace a token that may have leaked:

php artisan repositories:inbound-deploy-token owner/name

The command prints a ready-to-use URL of the shape POST /api/deploy-events/{repository}/{token}. A plain POST with no body records a successful production deploy; an optional JSON body refines the record:

  • environment — defaults to the repository's production environment.
  • statussuccess (default), failure or error.
  • sha — the deployed commit, used to link the deploy to its pull requests and to de-duplicate webhook retries.
  • description — free-text note shown alongside the deployment.
  • deployer_email — when it matches a team member's Coderbuds account, the deploy is attributed to that person on the deployments-by-person leaderboard.

The token is encrypted at rest and is the only credential the endpoint accepts — a wrong or missing token simply returns 404. Replaying the same deploy (same commit and environment) within five minutes returns the original record instead of counting it twice.

Calling it from a deploy script

If your platform has no "deployment finished" webhook of its own — a Forge or Envoyer deploy script, or your own CI — report the deploy from the end of the script itself.

DEPLOY_STATUS="success"

# ... your existing steps, each marking a failure rather than aborting ...
composer install --no-interaction --prefer-dist --optimize-autoloader || DEPLOY_STATUS="failure"
php artisan migrate --force                                          || DEPLOY_STATUS="failure"
npm run build                                                        || DEPLOY_STATUS="failure"

# Last thing in the script, after the build:
curl -fsS -X POST "$CODERBUDS_DEPLOY_WEBHOOK" \
  -d "environment=production" \
  -d "status=$DEPLOY_STATUS" \
  -d "sha=$(git rev-parse HEAD)" || true

Three details matter more than they look:

  • End the line with || true. Under set -e, a failed report would abort the deploy — so a Coderbuds outage, or a rotated token, would start breaking your releases. Reporting must never be able to do that.
  • Put it last, after the asset build. Reporting before the build records a deploy that may still fail, which flatters your change-failure rate and puts a "deployed" label on a broken release.
  • Send the real status. Without set -e a script reaches its last line whatever happened earlier, so a hardcoded status=success reports every failed deploy as a good one. Carry a variable, as above, or your change-failure rate is always zero.

Keep the URL out of the script itself, so the token does not sit in your platform's UI and its edit history. A deploy script does not inherit your application's environment, so read it in — on Forge, put CODERBUDS_DEPLOY_WEBHOOK in the site's Environment editor and pull it out of the .env at the top of the script:

CODERBUDS_DEPLOY_WEBHOOK=$(grep -m1 '^CODERBUDS_DEPLOY_WEBHOOK=' .env | cut -d= -f2- | tr -d '"')

Add -d "deployer_email=..." if your CI knows who triggered the release, and the deploy is attributed to that person on the deployments-by-person leaderboard.

Security

  • The hook URL is encrypted at rest and never displayed again after saving.
  • Only Slack users linked to a team member can trigger a deploy, and every click shows a confirmation dialog first.
  • Repeated triggers within 10 minutes are rejected, so an accidental double-click can't deploy twice.
  • The Slack message records who triggered each deploy.