Skip to content

Upgrading BrowserHive

capture-ledger is pinned to a specific BrowserHive version, not to main. The current pin is 19.0.1.

That comes from the .upstream/browserhive submodule — read at build time with git describe --tags, so this page cannot go stale. The submodule is the only upstream pin: it carries BrowserHive, the chromium-server-docker BrowserHive was tested against, the SeaweedFS config the stack mounts, and the OpenAPI document (generated/openapi.json) the manifest is checked against.

Terminal window
# 1. Move the submodule to the new tag.
git -C .upstream/browserhive fetch --tags
git -C .upstream/browserhive checkout <new-tag>
git -C .upstream/browserhive submodule update --init --recursive
git add .upstream/browserhive
# 2. Re-vendor the contract and regenerate the types (a local copy — no network).
pnpm run openapi:generate
pnpm run openapi:check # must exit 0 once committed
# 3. Rebuild from a clean state. Old volumes hold the previous bucket and
# database, which hides ordering bugs introduced by the upgrade.
pnpm run stack:down
pnpm run stack:up
# 4. Prove it end to end.
pnpm run check
./scripts/prod-smoke.sh

Chromium follows automatically: it is a submodule of the submodule, so you get the version BrowserHive itself was tested against. capture-ledger used to track it independently at main, and that is exactly how a stack break arrived — upstream moved its development Dockerfile into attic/ and every build stopped working.

An additive API change — new optional request fields — needs nothing beyond step 2: the regenerated types still compile and the tests pass untouched. That was the case for 1.6.0. Upstream runs smithy diff against the previous release on every change, so a bump that only adds members cannot have renamed or retyped an existing one out from under the copy.

Infrastructure changes are the ones that bite, because they do not show up in the OpenAPI diff at all. Two examples from the 1.5.2 → 1.6.0 move:

  • BrowserHive’s SeaweedFS entrypoint started creating the bucket itself, which made capture-ledger’s own one-shot init container redundant (and its depends_on guarantee obsolete — WAIT_FOR_S3 replaced it).
  • The upstream Chromium image moved its development Dockerfile to attic/.

After bumping, read the upstream release notes for anything that touches etc/seaweedfs/*, the entrypoint, or the compose contract.