Announcing Bass Loop #1
vito
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Bass Loop (www, repo) is a teeny tiny experimental CI/CD stack that I've been building for the past few weeks. It now drives all the CI checks for Bass, replacing GitHub actions.
Check out the demo repo to see a minimal configuration.
What is it?
Bass Loop is a GitHub app that passes GitHub events to Bass code in the repo they came from, running thunks on user-provided runtimes and providing a snappy web UI for viewing output.
How do I use it?
Install the GitHub app and create a
project.bass
in the root of your repo, providing a function like so:When Loop receives a webhook event from GitHub it loads
project.bass
from the root of the the event's repo and callsgithub-hook
. Thepayload
value is the parsed event body, andevent
is the event name. Thegithub
value is a module for interacting with GitHub. For example,(github:start-check thunk name sha)
runs a thunk as a GitHub check.The
loop.bass-lang.org
installation only forwards check suite events, push events, and release events. Let me know if you need any others, but you can always run your own Loop and enable whatever events you need. (More on that later.)Typically you'll want to run a suite of checks. There's a helper for that:
Loop doesn't have any runtimes, so it can't run any thunks on its own. Instead, everyone brings their own runtimes:
Leave this running in a terminal somewhere and Loop will start running thunks using the runner's runtimes whenever you trigger an event (e.g. a
git push
). When you're done, just Ctrl+C to stop the runner.Principles
Why am I not just using GitHub actions like everyone else?
Gotta go fast
Bass is slow in GitHub actions. There's no cache reuse because each run has its own Buildkit server. I could import/export caches, but that's slow too. Generally speaking any free tier CI/CD SaaS is slow and unreliable, and troubleshooting is often a pain in the ass.
Bass Loop is optimized for use in anger. When you view a run it dedicates the full page to the output without any extra clicks or chrome. ANSI colors are pre-rendered to HTML and served from the blobstore to make it even faster.
In general: if it can be cached, it will be cached. If there's a faster way to figure out why something failed, Bass Loop should implement it. As an example, since there's no way to skip the middle-man when going from a commit to its failed check to the full output, Bass Loop summarizes the output on the failed check page too.
Bring your own runtimes
The economics of open-source projects are unfair to maintainers. Open-source doesn't inherently generate income, so the ideal cost of infrastructure is $0. That leaves maintainers choosing between the free tier of some SaaS CI/CD tool or spending money out of their own pocket for the rest of their life. (Sponsorships help but are not reliable.)
Let's assume I don't want to use a SaaS because they all want me to write YAML, and I'm sick of YAML. I want to write code. And the free tier usually sucks. I want fast builds. So I run my own infra, using Bass of course, but if my project takes off I don't want to end up paying more and more time and money towards growing and maintaining its infrastructure.
To get there, Bass Loop reverses the relationship: the sender of a webhook event is "on the hook" for running any thunks kicked off from it, not the receiver. The sender should be capable of running their own builds - after all, they tested their changes before submitting the PR, right? As long as thunks are hermetic it shouldn't matter where they run. Why not leverage that?
So to "bring your own runtimes" just run:
Under the hood this command SSHes to
github.bass-lang.org
on port6455
using your GitHub username and SSH key, starts a local gRPC server for each runtime, and forwards the server over the SSH connection using a reverse tunnel. When you do something in GitHub that triggers a thunk run, Loop uses the tunneled runtimes to run it.Trade-offs
It's possible for a contibutor to false-pass PR checks by using a no-op runtime. This is a pretty fundamental trade-off from inverting the relationship, mitigated mostly by social dynamics: it's easy for someone to notice you faked it by running the same thunk themselves (copying the JSON from the thunk view), and the risk is getting banned following a revert. But if the stakes are too high, this could be made configurable. PRs welcome!
On the other hand, project maintainers no longer have to worry about running untrusted code, and don't have to pay to do so. That's kind of a big deal, at least to me.
Run your own
The
loop.bass-lang.org
deployment is a YOLO'd VM on a $20/mo budget that I've deployed with good oldssh
andtmux
. Please be kind to it.It uses SQLite and a blobstore, defaulting both to the local disk. Right now it's single-node, it'll be multi-node at some point.
go install github.com/vito/bass-loop/cmd/bass-loop # ... create a GitHub app ... bass-loop \ --github-app-id 123456 \ --github-app-key /private/key \ --github-app-webhook-secret hunter2
By default it listens on port 8080 for HTTP traffic (webhooks + web UI) and 6455 for SSH traffic (runtime registration).
Project status
Bass Loop is an experiment within an experiment. If you use it, you are part of the experiment! Please let me know how things go either here or in Discord. :)
I'm putting this out there to get more mileage on it, to see if people like it, and to see how much I can get out of a small deployment. I will do my best to maintain the uptime of
loop.bass-lang.org
but there are no guarantees. Expect things to change or break at any moment.Beta Was this translation helpful? Give feedback.
All reactions