My disdain for GitHub actions seems to increase daily. I just want simple CI. I don’t want to find some random persons action and have to pin to a version of it. I don’t want to learn their specific options. I don’t want to have to make a change, push it to test it, and find out something doesn’t work, over and over again. Yes I’ve tried act but it doesn’t behave exactly the same and sometimes things get wonky. I essentially want GitLab CI where I just use a container image that has what I want in it for that project, but can use it with other providers.

Woodpecker

Woodpecker is a simple CI tool that fits the bill. It’s forked from Drone before the license change. It’s open source and uses containers to run the pipelines. The only downside that I have encountered (so far) is that because it’s not a first party CI for GitHub, it requires webhooks to run the pipeline. I’m hosting it at home, so I don’t want to expose Woodpecker to the world. So rather than do what a normal person would do and run it on a provider, I did it the hard way.

NATS

I love NATS and use it when I can. A while ago I wrote a library to convert NATS messages to SSE. This library also will handle publishing messages, request/reply, and KV. I wrote a small gateway that uses this library and is hosted in Fly.io. These requests use Synadia Cloud as a backbone and requests are routed either to a service that’s directly connected to Synadia, or through them down through my leaf node connection to my NATS setup in my house. All of the services use JWT authentication and I can easily limit permissions for services.

Proxy

So back to my issue. I didn’t want to expose Woodpecker running here to the internet. So I leveraged what I already have set up through my gateway. I added a specific route to my gateway for CI requests. They flow through a request/reply handler from the SSE library and down to my NATS leaf node. I wrote a small NATS service from my boilerplate setup that takes the NATS message, and converts it back to an HTTP request and sends that to Woodpecker. Woodpecker can respond to that request and that flows back through NATS to the gateway and then back to GitHub.

Here’s a diagram (it’s simple but has pretty animated lines)

proxy