Emelyn

Navigation

Turn a published release into a campaign people can understand.

Receive the release once, verify it came from GitHub, keep the original changes attached, and create a reviewable campaign instead of blindly posting a changelog.

GitHub release integration showing selected release.published event, signed webhook, payload mapping, draft and prerelease filter, campaign approval, delivery log, deduplication, and redelivery

Subscribe to one event and reject everything you did not ask for.

Create a repository or GitHub App webhook for the release event. Use JSON, HTTPS, SSL verification, and a high-entropy secret stored outside code.

  1. 01

    Copy the Emelyn endpoint

    Use the workspace-specific GitHub webhook URL. Do not add credentials to its query string.

  2. 02

    Choose application/json

    The signature must be calculated over the exact raw UTF-8 request body.

  3. 03

    Set a webhook secret

    Store the same secret in Emelyn’s encrypted integration credential.

  4. 04

    Select release events only

    Do not subscribe to every repository event.

  5. 05

    Publish a test release

    Confirm signature, event, delivery ID, mapping, and campaign state before enabling automation.

A published release becomes a source, not an automatic announcement.

Drafts and prereleases are ignored in this example. A published release creates a campaign in review mode so product language and promotion level can still be judged.

Example GitHub payload

{
  "action": "published",
  "release": {
    "id": 123456789,
    "tag_name": "v1.4.0",
    "name": "Emelyn v1.4.0",
    "body": "## What's changed
- Added campaign approvals",
    "html_url": "https://github.com/acme/app/releases/tag/v1.4.0",
    "published_at": "2026-08-29T09:30:00Z",
    "draft": false,
    "prerelease": false
  },
  "repository": { "full_name": "acme/app" }
}
GitHubEmelynUse
actiongithub.release.actionMust equal published
release.idgithub.release.idStable source identity
release.tag_namegithub.release.tag_nameVersion context
release.nametitleHuman-readable release name
release.bodysource_textClaims and changes to review
release.html_urlsource_urlPublic proof and destination
release.published_atsource_published_atFreshness and ordering

Verify first. Queue second. Process once.

GitHub recommends HMAC-SHA256 in X-Hub-Signature-256, a constant-time comparison, the unique X-GitHub-Delivery value, HTTPS, and a quick 2XX response.

Connector revision 1.0 · GitHub webhook event schema and REST API version 2022-11-28 · Last tested 29 August 2026.

const signature = request.headers.get("x-hub-signature-256");
const event = request.headers.get("x-github-event");
const delivery = request.headers.get("x-github-delivery");

verifyHmacSha256(rawBody, signature, webhookSecret);
if (event !== "release") return new Response(null, { status: 204 });
await enqueueOnce(delivery, rawBody);
return Response.json({ accepted: true }, { status: 202 });

Minimum access

Read release metadata. Repository admin is only needed to create or manage a repository webhook; do not request code write access.

Secret handling

Never log the secret or raw authorization data. Rotate by updating both sides, then send a test delivery.

Every webhook gets a result you can explain.

The delivery GUID connects GitHub’s recent-delivery view to Emelyn’s event log.

202 accepted

Verified, queued, and safe to process asynchronously.

Duplicate ignored

The same delivery or release ID will not create a second campaign.

401 rejected

Missing or invalid signature. Never retry inside Emelyn.

Manual redelivery

GitHub does not automatically redeliver failures. An admin can redeliver recent webhook deliveries.

The integration follows GitHub’s webhook contract, not an invented shortcut.

GitHub’s own guidance requires signature validation, minimum events, a fast response, delivery IDs, and manual recovery. The content workflow then adds the product judgment developers need: whether the change deserves promotion and how to explain it without release-note jargon.

Promote the change because it matters, not because a webhook fired.

Connect a repository