launch

Bootstrapping Launches as Open Source Seed Data Reconciler for SQLite

Bootstrapping 0.1 is out, open source under the Apache License 2.0. It keeps the reference data an application ships with, roles, permissions, plan tiers and the like, in step with its SQLite database on every release, without undoing what admins changed. The code is on GitHub, and ready-built binaries for Linux, macOS and Windows are on the download page.

It works by remembering. A small ledger in the database records what each apply wrote, so the next apply can compare every value three ways: the new seed, the live row and what was last applied. Values only the seed changed get updated. Values only an admin changed stay. Values both changed differently stop the apply until someone decides. The explainer goes through why that third version is the whole trick.

The quickest way to see it is the demo in every archive. Run bootstrapping-demo and an application’s roles and permissions go through three seed versions, with an admin renaming a role and removing a permission in between. The second version’s plan keeps both of the admin’s changes and still lands everything new.

The plan for the demo’s second seed version: insert billing.view; update the editor’s description; keep the admin’s name for editor; update viewer’s name to Reader; insert the admin’s billing link; keep the editor’s deleted link deleted The demo’s plan for its second version, as bst plan prints it, wrapped to fit.

What’s in Version 0.1

  • Seed files in TOML. One per table, easy to read in a pull request. Each column is owned by the merge (the default), by the seed, or by the admin after insert. Rows dropped from the seed can be kept, deleted or retired. A row can be renamed and keep its id.
  • Links by name. A link table says role_id = "editor", and Bootstrapping stores the editor role’s id, including rows the same apply inserts and tables that refer to themselves.
  • The bst command. plan, apply, status, explain and history, all with -json, and exit codes a deploy script can act on: 0 in step, 2 pending, 3 blocked by a conflict.
  • A Go library. It takes your *sql.DB from any SQLite driver, so seeds can be embedded in the application binary and applied at startup.
  • Conflicts that wait. A conflict blocks the whole apply with nothing written. Settle it with -take, or once and for all with on_conflict in the seed file.

What It Doesn’t Do Yet

It’s SQLite only for now; PostgreSQL is planned next. A reference names a row by one column, so composite references are out. It fills tables but doesn’t create them, so it runs after your migrations rather than replacing them. And it reads every managed table in full on each plan, which is fine for reference data and wrong for millions of rows.

How It Was Tested

The tests aim at the promise. 1,200 random histories of seed versions and admin edits checked 492,228 values against the merge rules after every apply, with no value overwritten without a conflict. 400 applies were killed with SIGKILL partway through, and every database was found exactly as before or exactly as after. Eight processes applied the same seed to one file at once, 60 times over, and exactly one wrote each time. 600 more histories ran three linked tables with foreign keys on, and every one of their 6,000 applies did exactly what its preview said without breaking a key. The testing post has the details, and the raw results are in the repository.

Releases go out through an automated workflow. Each binary is built from the exact commit the tests passed on, smoke-tested on its own kind of machine, and only then published.

Start with the quick start, or just run the demo.