v0.2.0
A minor, and the number means what it says: read this before upgrading.
./upgrade.sh still does the work and there is nothing to run by hand, but two
things change on their own once it has run.
git fetch --tags && git checkout v0.2.0
cd infra/selfhost && ./upgrade.shTwo things that change by themselves
Linking a payment to a visitor is now a per-site switch, and it is off by
default. Two Postgres migrations add it and backfill it. A site that already
had a revenue provider connected is read as having opted in already, keeps its
switch on, and keeps linking payments to journeys exactly as before. A site that
disconnected its provider, and every site created from now on, starts with it
off. Nothing to answer, and nothing to run.
The tracker changes, so it reaches every visitor of every site within the
hour. oa.js is unversioned and cached for an hour by design. This version
sends the revenue linking hint only for a site whose switch is on, and it gains
a strict storage mode: data-storage="none" runs it memory-only, with no read
of or write to localStorage or sessionStorage.
Revenue totals, or revenue attributed
Connecting Stripe now asks which one you want, as its own step, and the same
choice lives in Settings under Integrations so it can be changed later.
Revenue totals is the default. Nothing is asked of your visitors, and
totals, refunds, disputes and fees all work. Journeys stay empty of money.
Attributed revenue ties a payment back to the visit that produced it. Your
pages send an order reference with the conversion, and that is what turns a
count into a link. It carries a consent obligation you meet as your site's
controller: the script does not hold the hint back until somebody answers, so
wiring oa.consent("granted") on your own checkout is yours to do. The screen
says so and hands you the line.
Changes are saved as soon as you make them. Visitors' browsers hold their copy
of a site's configuration for about thirty seconds, so a change reaches them a
moment later rather than instantly.
Secrets may arrive as file paths
Every variable the schemas declare now also accepts X_FILE, naming a file
whose contents become the value of X. Existing deployments are unaffected:
set no _FILE variable and nothing changes.
Three rules, all of them loud. A path is a promise, so an unreadable or empty
file is a refusal to start, unlike an absent variable which several services
treat as "this feature is off". Setting X and X_FILE together is a startup
error rather than a precedence rule. And a path resolves before the
least-privilege check, so pointing a service at a secret it is not allowed to
hold fails exactly the way pasting that secret into its environment has always
failed.
This exists because one-click platforms can generate a random string and nothing
else, and none of them can produce a keypair whose halves must match across two
services. infra/selfhost/docker-compose.keys.yml is the worked example: a
one-shot step that makes the three signing pairs inside the stack and writes each
half into its own volume, so the api holds the private halves and each verifier
sees only the public one it needs.
It has been run on a real host. Keys are generated once and never rotated on a
redeploy, the modes and ownership hold on fresh volumes, and a service started
before the keys exist refuses to start with the reason on the line and recovers
on its own rather than wedging.
infra/selfhost/docker-compose.coolify.yml is the first platform variant, for
Coolify and anything else that owns the proxy. Not yet a supported path: it has
not been run on a live Coolify install.
Also fixed
The percentages under the chart were measured against the largest row in
Locations, Sources and Devices, so the top entry always read 100%. They are a
share of the rows shown now, and blank rather than wrong when the row set was
capped.
The published privacy notice was corrected: the four short-lived values the
script keeps on a device are named, the ePrivacy basis is stated as first-party
audience measurement with its cumulative conditions, and the two features that
leave that envelope say plainly that the consent obligation is the site's.
The realtime visitor panel names the page a visitor is on, and an empty trail no
longer blames ingest lag for it.
Images
Eight, published to ghcr.io/openlabs-so/openanalytics and tagged v0.2.0:
migrate, tracker-build, api, collector, worker, query-gateway,
realtime, web. amd64. On arm64, build them instead: same compose file, one
flag.
Migrations do not go down. ./upgrade.sh takes the snapshot ./rollback.sh
needs before it starts, and a rollback discards everything recorded after it.
RELEASING.md
is what a version number here means.
Full changelog: v0.1.1...v0.2.0