Skip to main content

7 posts tagged with "ci"

View All Tags

CI-Job and Muti-Job: self-healing CI and mutation loops with headless Genies

· 10 min read

A Trick is the most boring primitive we have. It runs your container once, watches it finish, records the exit codes, and tears itself down. No routing, no Genie, no second act. So when someone proposed building "self-healing CI" on top of it, the obvious reaction was: with what? There's nobody home in a Trick.

That turned out to be the point. The Trick stays dumb; the intelligence lives elsewhere — a separate coding Genie that wakes up after the job is done, reads what went wrong, and tries to fix it. Compose a one-shot job with that out-of-band agent and you get a loop that runs your tests and, when they're red, takes a swing at making them green. We call the patterns CI-Job and Muti-Job, and the cleverness is never inside the Trick.

How we organize end-to-end tests for a stateful platform

· 9 min read

Most end-to-end suites test a stateless web app: click a button, the DOM changes, assert on the new DOM — all inside one browser tab. Our suite doesn't have that luxury. When a Fibe test clicks "Launch", a real Docker-Compose project starts spinning up on a real Marquee — a Docker host that might be a Scaleway VM in Paris or someone's laptop. The interesting state isn't in the page; it's a container, somewhere else, that doesn't exist yet and won't for the next forty seconds.

That single fact reshapes everything: the test is inherently async, the work is genuinely slow, and the thing you're asserting on is a remote process you don't control. Get the structure wrong and the suite goes red half the time for reasons nobody can explain, until everyone stops trusting it. This post covers the patterns that make browser tests against remote, stateful infrastructure boring and reliable.

Cron and commits: scheduling jobs and triggering them from Git

· 14 min read

You already have a Trick — a job-mode Template that runs your tests, takes a backup, or migrates a database, then exits and records a result. So far you've been launching it by hand. The next move is to stop: have Fibe fire it at 3 a.m. every night, or fire it the instant someone pushes a commit. Both are two extra keys in the template's metadata block. No external cron daemon, no GitHub Actions YAML, no second CI runner that drifts away from your dev environment.

This guide is the hands-on version. We'll wire up a nightly Postgres backup on a cron schedule and a test-runner that fires on every pull request, and we'll be precise about the parts that trip people up: which branch a triggered run actually checks out, why a schedule that "should" fire at midnight runs at the wrong hour, and what Fibe does not tell GitHub when a run finishes.

How we test a Docker platform across five languages

· 20 min read

Most products are software that runs on infrastructure. Fibe's product is infrastructure: a Player funds a Marquee (a Docker host), and on it we deploy Playgrounds, Tricks, and AI agent sidecars as Docker-Compose projects, route them through Traefik with real wildcard TLS, and continuously heal them with a reconciler. When the thing you ship is "a Docker daemon does what the database said it should," your test pyramid has a problem the textbook diagram never warns you about: the genuinely end-to-end test needs a genuine Docker daemon, and that is slow, heavy, and flaky in all the classic ways.

So we test in five languages, with surfaces that range from sub-millisecond Rust unit tests to a ten-minute Docker-in-Docker run that spins up a real Playground. The interesting part isn't the list. It's the rule we use to decide which surface a given change actually deserves, and how a pile of formal models lets us not write some tests at all.

bin/check-full: the quality gate behind every change

· 10 min read

There is exactly one thing you need to know before opening a pull request against the Fibe Rails app: run bin/check-full. Not "run RuboCop, then Sorbet, then remember the architecture script, then the specs, oh and did you regenerate coverage?" Just the one command. If it's green, your change is ready for human eyes. If it's red, it tells you precisely what to fix.

That simplicity is the point — and it matters even more now that coding agents draft so many of our changes. This is the story of our canonical quality gate: what's inside it, and why it's one command instead of a checklist.

The image build gate: one build per commit, verified

· 10 min read

Here is a bug that does not look like a bug. You push a commit, a build kicks off, it goes green, your environment comes up. Everything works. Except the image inside it was built from a different commit than the one you pushed — a stale checkout, a cached layer, a race between two builds for the same branch. Nothing errored. The dashboard says success. And you spend an afternoon debugging code that was never actually deployed.

That class of failure — a build confidently wrong about what it produced — is the one we decided never to ship to a Player. So Fibe's image builds follow one stubborn rule: a build must be deterministic and honest about which commit it produced. This post is about how each build record enforces that, and the two checks that will fail a build rather than let it lie.

Tricks: headless one-shot Playgrounds for automation

· 9 min read

Most platforms ship a development environment and a CI system as two separate products. They drift. What worked in your dev container fails in CI for reasons nobody can reproduce, and you lose an afternoon discovering the CI runner is on a different base image, network, everything.

We didn't want two runtimes. A Trick is a Playground with one flag flipped — job mode — running the exact same environment engine, on the same Marquee, from the same Template. It has no UI to attach to and a defined notion of done: it runs, it exits, it records a result. If your tests pass in a Playground, they pass in a Trick — there's no second runtime to drift away from.