Releases: Ch4s3/bandera
Releases · Ch4s3/bandera
v0.4.0
What's Changed
Fixed
- Ecto store: boolean gate
put/2now deletes any existing boolean row before inserting, regardless of the storedtargetvalue. Migrating from FunWithFlags (which usedtarget = "boolean") left a stale row alongside Bandera'starget = "_bandera_none"row — the upsert conflict key is(flag_name, gate_type, target)so the two sentinels didn't conflict. The symptom was a dashboard toggle that showed "on" while the summary showed "off", with the toggle appearing to do nothing.
Added
Bandera.Ecto.Migrations.fix_fun_with_flags_boolean_gates/0: one-time cleanup migration helper that normalises duplicate boolean gate rows left by a FunWithFlags-to-Bandera migration. Safe to run on a fully-migrated database.mix bandera.gen.fix_fun_with_flags_migration: scaffolds the cleanup migration file in one command, then runmix ecto.migrate.
Upgrading
{:bandera, "~> 0.4.0"}If you previously migrated from FunWithFlags, run the one-time cleanup:
mix bandera.gen.fix_fun_with_flags_migration
mix ecto.migrate
Full changelog: https://github.com/Ch4s3/bandera/blob/main/CHANGELOG.md
v0.3.0
Added
- Multivariate flags:
Bandera.variant/2andput_variants/3for stable per-actor N-way allocation. Bucketing uses a weighted SHA-256 hash — the same actor always sees the same variant across nodes and restarts. - Ecto schema v2: a nullable
valuecolumn stores variant gate payloads.Bandera.Ecto.Migrations.upgrade_v2/0migrates an existing table; new installs get the column automatically viaup/0. - Context-based targeting rules:
enable(flag, when: constraints)and a:contextmap onenabled?/2. Supported operators::eq,:neq,:in,:not_in,:contains,:gt,:gte,:lt,:lte,:matches(regex). - Reusable segments:
put_segment/2stores a named constraint set;enable(flag, for_segment: name)references it. Segment rules are expanded at evaluation time so changing a segment immediately affects every flag that uses it. - Flag prerequisites:
enable(flag, requires: other_flag)requires another flag to be enabled (or disabled with{:flag, false}) before the dependent flag can turn on. Dependency cycles and missing parents fail closed. - Scheduled activation:
enable(flag, schedule: {start, stop})enables a flag only inside an ISO-8601 UTC time window. Either bound may benilfor an open-ended start or end. Malformed windows fail closed. - Audit log:
Bandera.Audit.attach/2anddetach/1register callbacks that receive a%Bandera.Audit.Event{}on every write. Pass:bytoenable/2,disable/2, andclear/2to record who made the change. - Stale flag tracking: start
Bandera.Usagein your supervision tree and callattach/0at boot; then useBandera.stale_flags/1ormix bandera.flags --stale [--older-than N]to find flags not evaluated in the last N days (default 30). - Dashboard: inline editors for variant, rule-constraint, segment, prerequisite, and schedule gates in the expanded flag row.
- Dashboard: per-gate-type summaries shown in collapsed flag rows.
enabled?/2:defaultoption: passdefault: trueto fail open when the store is unreachable (the default behaviour remains fail closed).- Symmetric
clear/2options for variant, rule, segment, prerequisite, and schedule gates — matching the correspondingenable/2options.
Changed
- Re-added
jasonas a direct dependency (required for variant gate JSON serialization in Ecto and Redis stores). It was dropped in 0.2.0 in favour of Elixir's built-inJSONmodule, but structured gate payloads need encoder options not available in the standard library.
Fixed
stale_flags/1: negative window values are clamped to zero.- Telemetry: audit and usage handlers that raise are caught; they no longer crash the telemetry pipeline.
- Stores: JSON deserialization of unknown gate types now fails softly instead of crashing; prerequisite flag names are bound as atoms at load time.
- Prerequisites: resolution is memoized per
enabled?call; cycles and unknown parents fail closed rather than looping. - Targeting: empty rule sets now fail closed instead of granting access to all callers.
- Variant weights: negative and non-numeric weight values are rejected at write time.
- Constraint evaluation: comparisons are numeric-aware when both sides are numbers; compiled regexes are cached per constraint.
Full changelog: v0.2.0...v0.3.0
v0.2.0
What's new in 0.2.0
Added
- Phoenix LiveView flag dashboard (
Bandera.Dashboard.RouterandBandera.Dashboard.FlagsLive): grouped flags with state summaries, live search filtering, row expand/collapse, boolean toggling, actor and group gate management, percentage set/clear, and clearing a whole flag. - Cross-node live refresh: the dashboard updates in real time when flags change on other nodes, via Phoenix.PubSub.
- Themeable dashboard UI that works standalone or with daisyUI, including a switch-style boolean toggle and assorted UX polish (
Bandera.Dashboard.Theme). - Name-prefix flag grouping with a runtime-configurable
:group_separator. - Dev-only local dashboard preview server (
dev/preview.exs).
Changed
- Use Elixir's built-in
JSONmodule instead ofjason; thejasondependency has been dropped. - Require Elixir
~> 1.18.
Full Changelog: v0.1.0...v0.2.0
v0.1.0
Initial release.
Added
- Runtime-configured feature flags with the full gate model: boolean, actor, group, percentage-of-time, and percentage-of-actors.
- Public API:
Bandera.enabled?/2,enable/2,disable/2,clear/2,get_flag/1,all_flags/0,all_flag_names/0, andreload_config/0. - Persistence adapters: in-memory (default), Ecto, and Redis.
- Two-level store with an ETS cache and cross-node cache-busting notifications (Redis PubSub and Phoenix.PubSub adapters).
- Async-safe, process-scoped test layer (
Bandera.Test) backed by NimbleOwnership. :telemetryevents for reads, writes, and the persistence layer.
Full Changelog: https://github.com/Ch4s3/bandera/blob/main/CHANGELOG.md