Test Github webhook events locally
Github API offers a pretty extensive list of events and payloads it delivers over webhooks. Webhooks are the way to go if you ever wanted to build a system (bot, ci/cd, etc) that reacts to changes in repositories, being it just a new git push, a submitted pull request or a new comment from a user. Users can choose which events they want (or all of them) and Github will deliver those when they happen to an URL of their choice. For all of that to happen the webhook URL must by publicly available and there are a few quick ways to get that done: create a dummy Heroku app or use a local server and expose it to the internet via ngrok.
I've built plenty of integrations with Github API and in most cases I start by saving a few event samples that I'm interested in. Say I want to know what is being sent when someone opens a new PR or adds a new comment, or when a new release is published. In other words - I'd like to obtain a set of test JSON fixture files with event data that I can write tests against.
github-events
After scratching my own itch for a while I have finally decided to build a small tool that could get me that fancy ngrok-style experience, and by that I mean seeing the incoming events in real time without doing any legwork of setting up an endpoint or even going into github settings page.
I've put together a quick prototype in an hour just to see how far I can get. Well, the prototype did a pretty good job so I decided to open source it, you can find it on my Github. I'm also experimenting with it and adding more features as I go.
The usage is pretty straighforward, run the command (after the install):
github-events
If everything is setup just right you might see something like that:
2019/12/02 20:34:58 Configuring Github API client
2019/12/02 20:34:58 Inspecting git remote
2019/12/02 20:34:58 Fetching existing webhooks
2019/12/02 20:34:59 Generating a new key
2019/12/02 20:34:59 Creating a new webhook
2019/12/02 20:35:05 Listening to events
2019/12/02 20:36:06 Received event: issues
{"event":"issues","payload":{"action":"opened","issue":{"url":"...."}}}
# above message has been truncated
# ... more lines
# hit ^C
2019/12/02 20:37:27 Removing the webhook
The above program does a few things under the hood, firsly it figures out what
Github user and repo is currently being used (by checking git origin
remote), then
tries to setup a Github API client using either environment variable or by scanning
your local ~/.netrc
file. Then it proceeds to create a new webhook for your Github
project (so you don't have to!) that's pointed to the shared Heroku app I've created
(server code is also opensource). Webhook URLs are randomly generated.
Finally, the app connects to the same webhook URL via Websocket protocol and listens for new events. When Github sends a new event, the payload data is transmitted through this proxy-like setup to your local machine. That's it. Once the app is terminated the temporary webhook is deleted automatically.
There are a couple of other use cases in the README:
# Pipe to jq for pretty printing and colorization
github-events | jq
# Or use internal pretty print option
github-events -pretty
# Save to file
github-events > events.log
# Filter by event type
github-events -only=push
# Save each event to a file.
# They are still printed out to STDOUT.
github-events -save -pretty
Just like ngrok, github-events
supports request forwarding to your local HTTP
server. If you're running some other server like Rails on port 5000 the command
to forward would be:
github-events http://localhost:5000
That's a wrap. Please don't hesitate and reach out to me via Github for any questions, bug reports or feature requests. Oh, and don't forget to star the project!