Developing new features in Eigen can be a little tricky. For very small features (like adding a single new label to a view), just send a pull request. The complicated part is when adding big features: things that will take longer than a sprint to fully build and test.
Artsy releases the app on a 2-week cadence 🔐, submitting the Monday after a sprint starts. To support this process, new features are put behind "options" so that in-progress work can be shipped without actually being visible to users. Here's how it works at a high-level:
- Work is put behind a "lab option", which can only be enabled in the admin menu (shake your device). Here is an example pull request adding a lab option.
- When the feature is ready to be released to users, we replace the lab option with an "Echo Feature." Echo is Artsy's feature-flag-as-a-service. We would put a new feature behind an Echo Feature so that, in case we accidentally ship a catastrophic bug, we can disable the feature remotely until we fix it. Here is an example pull request adding an Echo Feature.
In the past, we have used both simultaneously, using a logical or (||
) to enable the feature: either the lab option or the Echo Feature needed to be enabled. This caused a lot of problems (see note below). The current recommendation is first add a lab option while you're developing the feature. Once the feature is fully QA'd and ready to go live for users, then replace the lab option with the Echo Feature. Use the same name for both the lab option and the Echo Feature.
What's wrong with logic or-ing lab options and Echo Features?
The problem is that it conflates the responsibilities of lab options and Echo Features. Lab options are used for admins to see in-progress work; Echo Features are a safety valve so we can disable new features in the event of a catastrohpic bug. If we ship a build that respects the Echo Feature but only has in-progress work, then users who install that version but don't upgrade to the fully-featured version will see that in-progress work.
Both lab options and Echo Features get injected into Emission's options
automatically. See the Using an option in Emission section below for how to actually use these options.
Let's say you want to add a new feature, called "Marketing Banners". We'll add a new lab option called ARShowMarketingBanner
(this naming is a convention we borrow from Objective-C). You can access the lab options using through NativeModules.Emission.options
.
But where are these options set? There are two places and you need to do them both.
Inside Eigen you expose the ability to toggle options via
/Artsy/App/AROptions.m
and /Artsy/App/AROptions.h
- you use the Objective-C hash options
(note: you prefix strings/bools with an @
). These files are a bit complicated but you only have to worry about changing in a few places.
Changing /Artsy/App/AROptions.m
to add a new option would look like:
- Define your option in the header file (.h):
extern NSString *const ARShowMarketingBanner;
- Define your option in the implementation file (.m) and add to the options hash:
NSString *const ARShowMarketingBanner = @"ARShowMarketingBanner";
options = @{
+ ARShowMarketingBanner: @"Show the new marketing banner in the Artist page"
};
You'll need to re-compile the iOS app to make this show up on your launch screen in the app. This change makes the option available to be toggled by any admin: they can shake their phones to see the admin menu in Eigen.
The other way for Artsy to make configuration changes is via Artsy Echo - Echo has a concept called Features which are boolean options for features. The Features here are synced across all users devices, in Production (so be conservative about changes for people's bandwidth) and will be applied on the next launch of an app.
An lab option enabled in the Eigen admin screen will override whatever the Echo Feature is set to.
If you make Echo changes, you can update the local bundled copy of the echo settings by running make update_echo
in Eigen. This is done automatically when running pod install
.
What do we mean when we say "a new feature should be put behind a lab option or Echo Feature"? It means that the behaviour of the app changes depending on if this option is set. :
- Add your option to the Emission types file
/typings/emission.d.ts
func setupEmissionModule() {
....
options: {
+ AROptionsNewAndExcitingFeature: false,
AROptionsLotConditionReport: false,
AROptionsFilterCollectionsArtworks: false,
.....
}
}
- Use your option in code, here we are adding a new view to the hierarchy if the options is set.
+ const enableNewAndExcitingFeature = NativeModules.Emission.options.AROptionsNewAndExcitingFeature
return (<>
<TitleView />
<SummaryView />
+ { enableNewAndExcitingFeature && <NewAndExcitingFeature /> }
<>)
This works for when changing a part of Emission that already exists. But when we add entirely new things to Emission, it's often the case that Eigen needs to use the option instead. (For example, when adding a new Partner profile page.) This looks different on a case-by-base basis, and you can ask for help in the #front-end-ios Slack channel if you get stuck.