Featurevisor

Advanced

Environments

Featurevisor is highly configurable and allows us to have any number of custom environments (like development, staging, and production). By default, projects have no environments at all.

There are 2 ways to configure environments in Featurevisor:

  • environment specific data in individual self-contained feature definitions
  • no environments at all

Custom environments

If your project needs environments, it is recommended that we have at least staging and production environments in our project.

Adding environments

We can add more environments as needed:

featurevisor.config.js
module.exports = {
tags: [
'web',
'mobile'
],
environments: [
'staging',
'production',
// add more environments here...
],
}

Above configuration will help us define our features and their rules against each environment as follows:

Environment specific rules

features/my_feature.yml
description: My feature
tags:
- web
bucketBy: userId
# rules per each environment
rules:
staging:
- key: everyone
segments: '*'
percentage: 100
production:
- key: everyone
segments: '*'
percentage: 0

See also force and expose for more information.

Generated datafiles

And the datafiles will be built per each environment in datafiles directory:

Command
$ tree datafiles
.
├── staging/
│ ├── featurevisor-web.json
│ └── featurevisor-mobile.json
├── production/
│ ├── featurevisor-web.json
│ └── featurevisor-mobile.json

Environment lanes with sets

With the environments config above, environment specific rules, force, and expose maps live inside the same feature file.

There is another way to model environments that some teams prefer: treat dev, staging, and production as independent release lanes using sets, and move changes from one lane to the next using promotions.

This approach is useful when you want each lane to be fully separate, so the same feature can have a very different definition in dev than in production, and changes flow forward only when you promote them.

You can scaffold a ready-made project for this with:

Command
$ npx featurevisor init --example=environments

Configuration

With this approach you do not define environments. You enable sets instead, and add promotionFlows to keep promotions moving in one direction:

featurevisor.config.js
module.exports = {
sets: true,
tags: ['all'],
// only allow promotions to move forward, one lane at a time
promotionFlows: [
{ from: 'dev', to: 'staging' },
{ from: 'staging', to: 'production' },
],
}

One set per lane

Each lane is a set with its own definitions under sets/<lane>/:

sets/
├── dev/
│ ├── attributes/
│ ├── segments/
│ ├── features/
│ ├── targets/
│ └── tests/
├── staging/
│ └── ...
└── production/
└── ...

The same feature key can live in every lane with different rules. Because there are no environments, rules are authored directly without an environment key:

sets/dev/features/checkoutFlow.yml
description: New checkout flow in dev
tags:
- all
bucketBy: userId
# fully rolled out in dev
rules:
- key: everyone
segments: '*'
percentage: 100
sets/production/features/checkoutFlow.yml
description: New checkout flow in production
tags:
- all
bucketBy: userId
# still off in production
rules:
- key: everyone
segments: '*'
percentage: 0

Building datafiles

Building writes datafiles under a directory per lane:

Output
datafiles/dev/featurevisor-all.json
datafiles/staging/featurevisor-all.json
datafiles/production/featurevisor-all.json

Promoting between lanes

When a feature is ready to move to the next lane, promote it:

Command
$ npx featurevisor promote --from=dev --to=staging --apply

The promotionFlows configuration above makes sure promotions only move forward, so promoting straight from dev to production is rejected.

Read more in Sets and Promotions.

No environments

Projects have no environments by default. You can omit environments from your configuration:

featurevisor.config.js
module.exports = {
tags: [
'web',
'mobile'
],
}

This will allow us to define our rollout rules directly without needing any environment specific keys:

features/my_feature.yml
description: My feature
tags:
- web
bucketBy: userId
# rules without needing environment specific keys
rules:
- key: everyone
segments: '*'
percentage: 100

The datafiles will be built without any environment:

$ tree datafiles
.
├── featurevisor-web.json
├── featurevisor-mobile.json
Previous
Tags