Hookbase
LoginGet Started Free
Back to Blog
Product Update

Test Real Webhooks in CI With Three Lines of YAML

The new hookbase/setup-tunnel GitHub Action exposes a localhost port via a public Hookbase tunnel during CI runs. Receive real webhooks from Stripe, GitHub, Shopify, or any provider against ephemeral test environments — without managing tunnel lifecycle by hand.

Hookbase Team
April 26, 2026
4 min read

The Setup

You have a webhook handler. You want to know it works against real Stripe events, real GitHub deliveries, real Shopify orders — not handcrafted fixtures that drift out of sync with the provider every six months. The handler runs fine on your laptop with hookbase tunnel 3000. But in CI? Most teams give up and write mocks instead.

That's the gap we're closing today.

Hookbase Setup Tunnel — GitHub Action

- uses: HookbaseApp/setup-tunnel@v1
  id: tunnel
  with:
    port: 3000
    api-key: ${{ secrets.HOOKBASE_API_KEY }}

- run: echo "Webhook URL is ${{ steps.tunnel.outputs.tunnel-url }}"

Three lines. The Action installs the Hookbase CLI on the runner, starts a tunnel pointing at port 3000, exposes the public URL as a step output, and tears the tunnel down automatically when the job finishes.

You point Stripe (or GitHub, Shopify, Plaid, whoever) at that URL, fire a test event, and assert your handler processed it. The same trust boundary you'd have in production — real webhook, real signature, real payload — but inside a disposable CI job.

Why This Matters

Mock-based webhook tests have a known failure mode: they pass forever, and your handler breaks the day a provider tweaks their payload format. Schema drift is silent until production.

End-to-end webhook tests catch that drift the day it happens. The reason teams don't write them is operational friction:

  • ngrok URLs change every restart, so you can't pre-register them with the provider
  • Stripe CLI works for Stripe only, and rotates the signing secret every session
  • Self-hosted tunnel solutions need infrastructure you don't want in your CI account

The Action removes all of that. Stable URL pattern, works for every provider Hookbase supports, no infrastructure of your own.

What You Get

  • Real signature verification. Hookbase verifies the provider's HMAC before forwarding. Your handler exercises the actual verification path.
  • Real retry semantics. If your handler returns 5xx, Hookbase retries with exponential backoff — exactly what production looks like.
  • Event history per CI run. Every webhook the tunnel receives is stored in your Hookbase dashboard. When a CI run fails, the payload that broke it is one click away.
  • Automatic teardown. No leaked tunnels. The Action's post-step kills the CLI cleanly, and the CLI deletes the tunnel server-side.

A Real Example: GitHub Webhook Round Trip

jobs:
  webhook-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci

      - name: Start handler
        run: npm run start &

      - uses: HookbaseApp/setup-tunnel@v1
        id: tunnel
        with:
          port: 3000
          api-key: ${{ secrets.HOOKBASE_API_KEY }}

      - name: Register a webhook with the GitHub repo
        run: |
          gh api repos/${{ github.repository }}/hooks \
            -f name=web \
            -f config[url]=${{ steps.tunnel.outputs.tunnel-url }} \
            -f config[content_type]=json \
            -f events[]=push

      - name: Push something to trigger the webhook
        run: ./scripts/trigger-test-push.sh

      - name: Assert handler processed the event
        run: ./scripts/assert-handler-saw-push.sh

Every push to that branch now exercises the full webhook path against real GitHub deliveries.

Inputs and Outputs

| Input | Required | Default | Description | |-------|----------|---------|-------------| | port | yes | — | Local port to forward | | api-key | yes | — | Hookbase API key (whr_...) | | subdomain | no | — | Custom subdomain (Pro plan) | | cli-version | no | latest | Pin a specific CLI version | | api-url | no | https://api.hookbase.app | Override the API URL | | ready-timeout-ms | no | 30000 | Timeout waiting for tunnel to connect |

| Output | Description | |--------|-------------| | tunnel-url | Public URL of the tunnel. Also exported as HOOKBASE_TUNNEL_URL env var. |

Get Started

The Action is live on the GitHub Marketplace today: HookbaseApp/setup-tunnel.

You'll need a Hookbase account (free tier covers all CI usage) and an API key from your dashboard. Drop it into your repo's Actions secrets and you're done.

Install the Action · Sign up free

product-updategithub-actionscitunnelstestingdeveloper-tools

Related Articles

Tutorial

Shopify Webhook Signature Verification, Explained

Shopify HMAC verification trips up almost every first-time integrator. Here is exactly how the signature is computed, what goes wrong, and a working implementation in Node, Python, Go, and Ruby.

Reference

Webhook Retries: What Every Provider Does Differently

Stripe retries for 3 days. GitHub gives up after one failure. Shopify retries 19 times. Knowing the rules for each provider is the difference between losing events and not. A reference table plus what it means for your handler.

Best Practices

Idempotency Keys for Webhooks: A Practical Guide

Webhooks get retried. Without idempotency, that means duplicate orders, double charges, and angry customers. Here is how to design a deduplication strategy that actually works.

Ready to Try Hookbase?

Start receiving, transforming, and routing webhooks in minutes.

Get Started Free
Hookbase

Reliable webhook infrastructure for modern teams. Built on Cloudflare's global edge network.

Product

  • Features
  • Pricing
  • Use Cases
  • Integrations
  • ngrok Alternative

Resources

  • Documentation
  • API Reference
  • CLI Guide
  • Blog
  • FAQ

Free Tools

  • All Tools
  • Webhook Bin
  • HMAC Calculator
  • JSONata Playground
  • Cron Builder
  • Payload Formatter
  • Local Testing

Legal

  • Privacy Policy
  • Terms of Service
  • Contact
  • Status

© 2026 Hookbase. All rights reserved.