Wave CI Builds Itself

rubytoolingbuilding-in-public

Wave CI is building itself now. The production wave-ci.production.yml defines the build steps (make test, make base-image, make docker-image), the deploy steps (push to our Docker registry, tag as latest), and the secrets for registry authentication. When I push a commit to the Wave CI repo, Wave CI picks it up, runs the tests, builds the Docker image, and pushes it. Watchtower on the production server notices the new image and restarts the containers.

A CI server that ships itself. That’s a good milestone.

Turbo Stream broadcasts

The big technical change this week was moving page updates from Turbo Stream responses to Turbo Stream broadcasts. The difference: responses update the page for the user who triggered the action. Broadcasts update the page for everyone who’s watching.

This matters for CI because builds run in the background. You kick off a build, and then you or someone else on the team opens the Stack page to watch it. With response-only updates, only the person who triggered the build would see live status changes. With broadcasts, the Stack index cards and header update in real time for everyone. A build finishes while your colleague is watching. They see it go green without refreshing.

The implementation uses a Broadcasts module instead of individual .turbo_stream.erb partials. The broadcast happens in a background job so the task execution thread isn’t blocked waiting for ActionCable to deliver updates.

Secrets

Server settings and secrets management landed too. Deploy steps often need credentials: registry passwords, SSH keys, API tokens. These are defined as variables in the wave-ci.yml with secret: true, which renders them as password fields in the UI and masks them in build output. The values are stored server-side and injected into the task’s environment at execution time.

Not glamorous work, but essential. You can’t deploy to a private registry without credentials, and you definitely don’t want those credentials visible in build logs.

Stack index performance

One thing that was bugging me: the Stack index page was slow when you had more than a handful of Stacks. Each card was rendering commit status, build status, deploy status, which meant multiple database queries per card. Fixed that with eager loading and a dedicated card component that batches the queries. The page loads fast now even with a dozen Stacks.

Small thing, but the index page is the first thing you see when you open Wave CI. If it’s slow, the whole tool feels slow.