Skip to content

Commit c386d6f

Browse files
NEXT-24676 - Add adr for our current feature flag handling
1 parent 1a470ff commit c386d6f

File tree

4 files changed

+167
-3
lines changed

4 files changed

+167
-3
lines changed

adr/workflow/2020-08-10-feature-flag-system.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# 2020-08-10 - Feature flag system
2+
# Superseded by [Feature flags for major versions](2022-01-20-feature-flags-for-major-versions.md)
23

34
## Context
45
To provide a way to toggle code from incomplete features, the feature flag system was implemented.

adr/workflow/2020-08-19-handling-feature-flags.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# 2020-08-12 - Handling feature flags
2+
# Superseded by [Feature flags for major versions](2022-01-20-feature-flags-for-major-versions.md)
23

34
## Context
45

@@ -12,11 +13,11 @@ This adr should be used as a reference to implement a feature and get sure a MR
1213

1314
## Detailed cases
1415
### New Entity Definitions
15-
New Entity Definitions have to be hidden behind the flag in the container. [how to](./../../60-references-internals/10-core/20-feature-flag-handling.md#using-flags-for-services)
16+
New Entity Definitions have to be hidden behind the flag in the container.
1617
### New Services and other classes (subscriber, event, resolver)
17-
New Services have to be hidden behind the flag in the container. [how to](./../../60-references-internals/10-core/20-feature-flag-handling.md#using-flags-for-services)
18+
New Services have to be hidden behind the flag in the container.
1819
### Changes in current classes
19-
Changes inside current classes should be conditioned with the flag. [how to](./../../60-references-internals/10-core/20-feature-flag-handling.md#using-flags-in-methods)
20+
Changes inside current classes should be conditioned with the flag.
2021
### Additions to current classes
2122
Access to new constants or public functions cannot be prevented by the feature flag system. In this case you have to annotate the not available part with an *@internal (flag:FEATURE_NEXT_1128)* comment
2223
```php

adr/workflow/2021-01-21-deprecation-strategy.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# 2021-01-21 - Deprecation Strategy
2+
# Superseded by [Feature flags for major versions](2022-01-20-feature-flags-for-major-versions.md)
23

34
## Context
45

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# 2022-01-20 - Feature flags for major versions
2+
3+
## Context
4+
Feature flags enable the developer to create new code which is hidden behind the flag and merge it into the trunk branch, even when the code is not finalized.
5+
We use this functionality to merge breaks into the trunk early, without them already being switched active.
6+
7+
## Decision
8+
We will use feature flags for major versions to hide new code, that will be introduced in the next major version.
9+
We have only one feature flag in our core sources: `v6.5.0.0`. This feature flag is used for the breaks mentioned above.
10+
11+
## Consequences
12+
We will use the static functions of the Feature class to check if a feature is active or not. And only hide code for the next major version behind the feature flag.
13+
14+
### Activating the flag
15+
To switch flags on and off you can use the ***.env*** to configure each feature flag. Using dots inside an env variable are not allowed, so we use underscore instead:
16+
```bash
17+
V6_5_0_0=1
18+
```
19+
20+
### Using flags in PHP:
21+
The feature flag can be used in PHP to make specific code parts only executable when the flag is active.
22+
23+
### Using flags in methods
24+
When there is no option via the container you can use additional helper functions:
25+
```php
26+
use Shopware\Core\Framework\Feature;
27+
28+
class ApiController
29+
{
30+
public function indexAction(Request $request)
31+
{
32+
// some old stuff
33+
Feature::ifActive('v6.5.0.0', function() use ($request) {
34+
// awesome stuff
35+
});
36+
// some old stuff
37+
}
38+
}
39+
```
40+
41+
And you can use it for conditions:
42+
```php
43+
use Shopware\Core\Framework\Feature;
44+
45+
class ApiController
46+
{
47+
public function indexAction(Request $request)
48+
{
49+
// some old stuff
50+
if (Feature::isActive('v6.5.0.0')) {
51+
//awesome new stuff
52+
}
53+
// some old stuff
54+
}
55+
}
56+
```
57+
58+
And you can use it simply to throw exceptions:
59+
```php
60+
use Shopware\Core\Framework\Feature;
61+
62+
/**
63+
* @deprecated tag:v6.5.0 - Class is deprecated, use ... instead
64+
*/
65+
class ApiController
66+
{
67+
public function indexAction(Request $request)
68+
{
69+
Feature::triggerDeprecationOrThrow('v6.5.0.0', 'Class is deprecated, use ... instead');
70+
}
71+
}
72+
```
73+
74+
### Using flags in tests
75+
You can flag a test by using the corresponding helper function. This can also be used in the `setUp()` method.
76+
```php
77+
use Shopware\Core\Framework\Feature;
78+
79+
class ProductTest
80+
{
81+
public function testNewFeature()
82+
{
83+
Feature::skipTestIfActive('v6.5.0.0', $this);
84+
85+
// test code
86+
}
87+
}
88+
```
89+
90+
### Using flags in the administration:
91+
Also in the JavaScript code of the administration the flags can be used in various ways.
92+
93+
### Using flags for modules
94+
You can also hide complete admin modules behind a flag:
95+
```javascript
96+
97+
Module.register('sw-awesome', {
98+
flag: 'v6.5.0.0',
99+
...
100+
});
101+
```
102+
103+
### Using flags in JavaScript
104+
To use a flag in a VueJS component you can inject the feature service and use it.
105+
106+
```
107+
inject: ['feature'],
108+
...
109+
featureIsActive(flag) {
110+
return this.feature.isActive(flag);
111+
},
112+
```
113+
114+
### Using flags in templates
115+
When you want to toggle different parts of the template you can use the flag in a VueJs condition if you injected the service in the module:
116+
```html
117+
<sw-field type="text" v-if="feature.isActive('v6.5.0.0')"></sw-field>
118+
```
119+
120+
### Using flags in config.xml
121+
122+
When you want to toggle config input fields in config.xml like [basicInformatation.xml](https://gitlab.shopware.com/shopware/6/product/platform/-/blob/trunk/src/Core/System/Resources/config/basicInformation.xml), you can add a `flag` element like this:
123+
124+
```xml
125+
<input-field type="bool" flag="v6.5.0.0">
126+
<name>showTitleField</name>
127+
<label>Show title</label>
128+
<label lang="de-DE">Titel anzeigen</label>
129+
<flag>v6.5.0.0</flag>
130+
</input-field>
131+
```
132+
133+
### Using flags in the storefront:
134+
In the Storefront it works nearly similar to the admin.
135+
136+
### Using flags in storefront JavaScript
137+
```
138+
import Feature from 'src/helper/feature.helper';
139+
...
140+
data() {
141+
if (Feature.isActive('v6.5.0.0')) {
142+
console.log('v6.5.0.0 is active')
143+
}
144+
};
145+
```
146+
147+
### Using flags in storefront templates
148+
```
149+
{% if feature('v6.5.0.0') %}
150+
<span>Feature is active</span>
151+
{% endif %}
152+
```
153+
154+
155+
### Using flags in plugins:
156+
Feature flags can also be used in plugins.
157+
158+
### Major feature flag
159+
As mentioned before, we use the major feature flags (`v6.5.0.0`, `v6.6.0.0`) to signal breaks within the code ahead of time. This is an incredible help in the preparation of the next major release, as otherwise all breaks would have to be made within a short period of time.
160+
161+
This procedure can also be applied to plugins, which also use this flag and internally query it to either prepare the plugin for the next major or to support multiple Shopware major versions with one plugin version. Since each major feature flag remains after the corresponding release, they can be used as an alternative version switch to the php equivalent `version_compare`.

0 commit comments

Comments
 (0)