Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow more variations for a flag #363

Merged
merged 60 commits into from
Oct 12, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
4d48849
Introducing the new InternalFlag and all the associated behaviors
thomaspoignant Jul 28, 2022
309335c
Fix test bug
thomaspoignant Jul 28, 2022
18fb288
Using new struct with legacy syntax
thomaspoignant Jul 29, 2022
84f729f
Remove nil field
thomaspoignant Jul 29, 2022
16e0312
Remove unused test files
thomaspoignant Jul 29, 2022
0679472
Unused util function
thomaspoignant Jul 29, 2022
9118f83
Remove println
thomaspoignant Jul 29, 2022
a229b13
Remove flag_data from variation test
thomaspoignant Jul 29, 2022
ae0b313
Remove usage of flagv1.FlagData
thomaspoignant Jul 29, 2022
cd84bf9
continue to remove flagv1
thomaspoignant Jul 29, 2022
5e158d2
Remove usage of flagv1 package
thomaspoignant Jul 29, 2022
386c299
Order for constitency
thomaspoignant Jul 29, 2022
c0a2c02
Merge remote-tracking branch 'origin/main' into more-variant
thomaspoignant Aug 1, 2022
6a46813
Remove flagv1 package
thomaspoignant Aug 1, 2022
942d2d7
Merge remote-tracking branch 'origin/main' into more-variant
thomaspoignant Aug 1, 2022
1514d89
Disable schedule step in schedule step
thomaspoignant Aug 1, 2022
988870e
Add test to ensure we cannot have scheduled step with scheduled steps
thomaspoignant Aug 1, 2022
12f0c21
converter tests
thomaspoignant Aug 1, 2022
ec35950
Add comments
thomaspoignant Aug 1, 2022
08f46c1
WIP
thomaspoignant Aug 3, 2022
145df10
WIP
thomaspoignant Aug 7, 2022
db81cf2
WIP
thomaspoignant Aug 7, 2022
f62e565
Rework the convert layer
thomaspoignant Aug 7, 2022
0507b01
Merge remote-tracking branch 'origin/main' into more-variant
thomaspoignant Aug 7, 2022
429141e
adding field
thomaspoignant Aug 7, 2022
d394e84
remove method string from the flag contract
thomaspoignant Aug 7, 2022
48d0187
Adding more test for internal flag
thomaspoignant Aug 8, 2022
cb85346
Stop using DTOv0 directly
thomaspoignant Aug 8, 2022
f2e1a4b
Manage to unmarshal multiple fields with same name
thomaspoignant Aug 8, 2022
6b1319b
wrong file
thomaspoignant Aug 8, 2022
66c2fd6
Rename cli
thomaspoignant Aug 8, 2022
4f36f99
add doc
thomaspoignant Aug 8, 2022
e949a88
Remove usage of ioutil
thomaspoignant Aug 8, 2022
724f074
Add godoc
thomaspoignant Aug 9, 2022
5dfc143
Change TOML lib to use BurntSushi/toml
thomaspoignant Aug 9, 2022
f4053ea
Merge branch 'main' into more-variant
thomaspoignant Aug 9, 2022
61968c9
Add test for new flag format
thomaspoignant Aug 9, 2022
1473330
Merge branch 'main' into more-variant
thomaspoignant Aug 9, 2022
d45b63e
Merge branch 'main' into more-variant
thomaspoignant Sep 9, 2022
54e7301
Bump github.com/google/go-cmp from 0.5.8 to 0.5.9 (#335)
dependabot[bot] Sep 9, 2022
f0964c8
Bump github.com/aws/aws-sdk-go from 1.44.93 to 1.44.94 (#336)
dependabot[bot] Sep 9, 2022
42abbde
Add a validation for the flag to avoid to have invalid flag in the cache
thomaspoignant Sep 26, 2022
9e8dbf6
Merge remote-tracking branch 'origin/main' into more-variant
thomaspoignant Sep 26, 2022
c72254c
Move the rollout options to the top level of the flag
thomaspoignant Sep 29, 2022
3db50b5
Merge remote-tracking branch 'origin/main' into more-variant
thomaspoignant Sep 29, 2022
c3f782d
update doc
thomaspoignant Oct 4, 2022
a6e3c70
Move rollout on top level
thomaspoignant Oct 4, 2022
b3272b8
migration cli binary
thomaspoignant Oct 5, 2022
d93e91e
Merge branch 'main' into more-variant
thomaspoignant Oct 5, 2022
0573fd0
Modify flagv1 for compatibility
thomaspoignant Oct 5, 2022
65c24b4
Merge branch 'main' into more-variant
thomaspoignant Oct 10, 2022
8180392
fix doc
thomaspoignant Oct 12, 2022
298511e
Bump go version CI
thomaspoignant Oct 12, 2022
f3d14d7
Fix antlr dependencies
thomaspoignant Oct 12, 2022
4a50755
Add test for convertion cli
thomaspoignant Oct 12, 2022
ec3a805
improve makefile
thomaspoignant Oct 12, 2022
dc229d4
remove unused function
thomaspoignant Oct 12, 2022
e4d8f4f
remove Print
thomaspoignant Oct 12, 2022
82951a2
remove header for v1
thomaspoignant Oct 12, 2022
51f7ad7
Format the files
thomaspoignant Oct 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
update doc
Signed-off-by: Thomas Poignant <[email protected]>
  • Loading branch information
thomaspoignant committed Oct 4, 2022
commit c3f782dd7e212a484b84e261f26771cab67579b9
176 changes: 111 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ go get github.com/thomaspoignant/go-feature-flag
```
## What is go-feature-flag?

A simple and complete feature flag solution, without any complex backend system to install, all you need is a file as your backend.
GO Feature Flag is the easiest way to start with feature flag without any complex backend system to install, all you need is a file as your backend.

No server is needed, just add a file to your central system and all your services will react to the changes in this file.

Expand Down Expand Up @@ -58,7 +58,7 @@ _The code of this demo is available in [`thomaspoignant/go-feature-flag-demo`](h

## Can I use GO Feature Flag with another language?

Originally GO Feature Flag was built to be a GOlang only library, but it limits the ecsystem too much.
Originally GO Feature Flag was built to be a GOlang only library, but it limits the ecosystem too much.
To be compatible with more language we have implemented the [GO Feature Flag Relay Proxy](https://github.com/thomaspoignant/go-feature-flag-relay-proxy).
It is a service you can host that provides an API to evaluate your flags, you can call it using HTTP to get your variation.

Expand Down Expand Up @@ -169,57 +169,89 @@ If you prefer to do it manually please follow instruction bellow.
<summary>YAML</summary>

```yaml
test-flag:
percentage: 100
rule: key eq "random-key"
true: true
false: false
default: false
disable: false
trackEvents: true
version: 1
rollout:
experimentation:
start: 2021-03-20T00:00:00.10-05:00
end: 2021-03-21T00:00:00.10-05:00

test-flag2:
rule: key eq "not-a-key"
percentage: 100
true: true
false: false
default: false
version: 12
# This is your configuration for your first flag
first-flag:
variations: # All possible return value for your feature flag
A: false
B: true
targeting: # If you want to target a subset of your users in particular
- query: key eq "random-key"
percentage:
A: 0
B: 100
defaultRule: # When no targeting match we use the defaultRule
variation: A

# A second example of a flag configuration
second-flag:
variations:
A: "valueA"
B: "valueB"
defaultValue: "a default value"
targeting:
- name: legacyRuleV0
query: key eq "not-a-key"
percentage:
A: 10
B: 90
defaultRule:
name: legacyDefaultRule
variation: defaultValue
version: "12"
experimentation:
start: 2021-03-20T00:00:00.1-05:00
end: 2021-03-21T00:00:00.1-05:00
```
</details>
<details>
<summary>JSON</summary>

```json
{
"test-flag": {
"percentage": 100,
"rule": "key eq \"random-key\"",
"true": true,
"false": false,
"default": false,
"disable": false,
"trackEvents": true,
"version": 1,
"rollout": {
"experimentation": {
"start": "2021-03-20T05:00:00.100Z",
"end": "2021-03-21T05:00:00.100Z"
"first-flag": {
"variations": {
"A": false,
"B": true
},
"targeting": [
{
"query": "key eq \"random-key\"",
"percentage": {
"A": 0,
"B": 100
}
}
],
"defaultRule": {
"variation": "A"
}
},
"test-flag2": {
"rule": "key eq \"not-a-key\"",
"percentage": 100,
"true": true,
"false": false,
"default": false,
"version": 12

"second-flag": {
"variations": {
"A": "valueA",
"B": "valueB",
"defaultValue": "a default value"
},
"targeting": [
{
"name": "legacyRuleV0",
"query": "key eq \"not-a-key\"",
"percentage": {
"A": 10,
"B": 90
}
}
],
"defaultRule": {
"name": "legacyDefaultRule",
"variation": "defaultValue"
},
"version": "12",
"experimentation": {
"start": "2021-03-20T05:00:00.100Z",
"end": "2021-03-21T05:00:00.100Z"
}
}
}
```
Expand All @@ -230,29 +262,43 @@ test-flag:
<summary>TOML</summary>

```toml
[test-flag]
percentage = 100.0
rule = "key eq \"random-key\""
true = true
false = false
default = false
disable = false
trackEvents = true
version = 1.0

[test-flag.rollout]

[test-flag.rollout.experimentation]
[first-flag.variations]
A = false
B = true

[[first-flag.targeting]]
query = 'key eq "random-key"'

[first-flag.targeting.percentage]
A = 0
B = 100

[first-flag.defaultRule]
variation = "A"

[second-flag]
version = "12"

[second-flag.variations]
A = "valueA"
B = "valueB"
defaultValue = "a default value"

[[second-flag.targeting]]
name = "legacyRuleV0"
query = 'key eq "not-a-key"'

[second-flag.targeting.percentage]
A = 10
B = 90

[second-flag.defaultRule]
name = "legacyDefaultRule"
variation = "defaultValue"

[second-flag.experimentation]
start = 2021-03-20T05:00:00.100Z
end = 2021-03-21T05:00:00.100Z

[test-flag2]
rule = "key eq \"not-a-key\""
percentage = 100.0
true = true
false = false
default = false
version = 12.0
```

</details>
Expand All @@ -261,7 +307,7 @@ All the fields to create a flag are described in the [documentation](https://doc

## Rule format

The rule format is based on the [`nikunjy/rules`](https://github.com/nikunjy/rules) library.
The query format is based on the [`nikunjy/rules`](https://github.com/nikunjy/rules) library.

All the operations can be written capitalized or lowercase (ex: `eq` or `EQ` can be used).
Logical Operations supported are `AND` `OR`.
Expand Down
24 changes: 12 additions & 12 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ During the initialization you must give a [`ffclient.Config{}`](https://pkg.go.d

## Configuration fields

| Field | Description |
|---|---|
|`Retriever` | The configuration retriever you want to use to get your flag file<br/> *See [Store your flag file](flag_file/index.md) for the configuration details*.|
|`Context` | *(optional)*<br/>The context used by the retriever.<br />Default: `context.Background()`|
|`Environment` | <a name="option_environment"></a>*(optional)*<br/>The environment the app is running under, can be checked in feature flag rules.<br />Default: `""`<br/>*Check [**"environments"** section](../flag_format/#environments) to understand how to use this parameter.*|
|`DataExporter` | *(optional)*<br/>DataExporter defines how to export data on how your flags are used.<br/> *see [export data section](data_collection/index.md) for more details*.|
|`FileFormat`| *(optional)*<br/>Format of your configuration file. Available formats are `yaml`, `toml` and `json`, if you omit the field it will try to unmarshal the file as a `yaml` file.<br/>Default: `YAML`|
|`Logger` | *(optional)*<br/>Logger used to log what `go-feature-flag` is doing.<br />If no logger is provided the module will not log anything.<br/>Default: No log|
|`Notifiers` | *(optional)*<br/>List of notifiers to call when your flag file has been changed.<br/> *See [notifiers section](./notifier/index.md) for more details*.|
|`PollingInterval` | (optional) Duration to wait before refreshing the flags.<br/>The minimum polling interval is 1 second.<br/>Default: 60 * time.Second|
|`StartWithRetrieverError` | *(optional)* If **true**, the SDK will start even if we did not get any flags from the retriever. It will serve only default values until the retriever returns the flags.<br/>The init method will not return any error if the flag file is unreachable.<br/>Default: **false**|
|`Offline`| *(optional)* If **true**, the SDK will not try to retrieve the flag file and will not export any data. No notification will be send neither.<br/>Default: false|
| Field | Description |
|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `Retriever` | The configuration retriever you want to use to get your flag file<br/> *See [Store your flag file](flag_file/index.md) for the configuration details*. |
| `Context` | *(optional)*<br/>The context used by the retriever.<br />Default: `context.Background()` |
| `Environment` | <a name="option_environment"></a>*(optional)*<br/>The environment the app is running under, can be checked in feature flag rules.<br />Default: `""`<br/>*Check [**"environments"** section](../flag_format/#environments) to understand how to use this parameter.* |
| `DataExporter` | *(optional)*<br/>DataExporter defines how to export data on how your flags are used.<br/> *see [export data section](data_collection/index.md) for more details*. |
| `FileFormat` | *(optional)*<br/>Format of your configuration file. Available formats are `yaml`, `toml` and `json`, if you omit the field it will try to unmarshal the file as a `yaml` file.<br/>Default: `YAML` |
| `Logger` | *(optional)*<br/>Logger used to log what `go-feature-flag` is doing.<br />If no logger is provided the module will not log anything.<br/>Default: No log |
| `Notifiers` | *(optional)*<br/>List of notifiers to call when your flag file has been changed.<br/> *See [notifiers section](./notifier/index.md) for more details*. |
| `PollingInterval` | (optional) Duration to wait before refreshing the flags.<br/>The minimum polling interval is 1 second.<br/>Default: 60 * time.Second |
| `StartWithRetrieverError` | *(optional)* If **true**, the SDK will start even if we did not get any flags from the retriever. It will serve only default values until the retriever returns the flags.<br/>The init method will not return any error if the flag file is unreachable.<br/>Default: **false** |
| `Offline` | *(optional)* If **true**, the SDK will not try to retrieve the flag file and will not export any data. No notification will be send neither.<br/>Default: false |

## Example
```go linenums="1"
Expand Down
12 changes: 6 additions & 6 deletions docs/data_collection/file.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ ffclient.Config{

## Configuration fields

| Field | Description |
|---|---|
|`OutputDir` | OutputDir is the location of the directory where to store the exported files.<br/>It should finish with a `/`. |
|`Format` | _(Optional)_ Format is the output format you want in your exported file.<br/>Available format: **`JSON`**, **`CSV`**.<br/>**Default: `JSON`** |
|`Filename` | _(Optional)_ Filename is the name of your output file.<br/>You can use a templated config to define the name of your exported files.<br/>Available replacement are `{{ .Hostname}}`, `{{ .Timestamp}}` and `{{ .Format}}`<br/>**Default: `flag-variation-{{ .Hostname}}-{{ .Timestamp}}.{{ .Format}}`**|
|`CsvTemplate` | _(Optional)_ CsvTemplate is used if your output format is CSV.<br/>This field will be ignored if you are using another format than CSV.<br/>You can decide which fields you want in your CSV line with a go-template syntax, please check [internal/exporter/feature_event.go](https://github.com/thomaspoignant/go-feature-flag/blob/main/internal/exporter/feature_event.go) to see what are the fields available.<br/>**Default:** `{{ .Kind}};{{ .ContextKind}};{{ .UserKey}};{{ .CreationDate}};{{ .Key}};{{ .Variation}};{{ .Value}};{{ .Default}}\n` |
| Field | Description |
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `OutputDir` | OutputDir is the location of the directory where to store the exported files.<br/>It should finish with a `/`. |
| `Format` | _(Optional)_ Format is the output format you want in your exported file.<br/>Available format: **`JSON`**, **`CSV`**.<br/>**Default: `JSON`** |
| `Filename` | _(Optional)_ Filename is the name of your output file.<br/>You can use a templated config to define the name of your exported files.<br/>Available replacement are `{{ .Hostname}}`, `{{ .Timestamp}}` and `{{ .Format}}`<br/>**Default: `flag-variation-{{ .Hostname}}-{{ .Timestamp}}.{{ .Format}}`** |
| `CsvTemplate` | _(Optional)_ CsvTemplate is used if your output format is CSV.<br/>This field will be ignored if you are using another format than CSV.<br/>You can decide which fields you want in your CSV line with a go-template syntax, please check [internal/exporter/feature_event.go](https://github.com/thomaspoignant/go-feature-flag/blob/main/internal/exporter/feature_event.go) to see what are the fields available.<br/>**Default:** `{{ .Kind}};{{ .ContextKind}};{{ .UserKey}};{{ .CreationDate}};{{ .Key}};{{ .Variation}};{{ .Value}};{{ .Default}}\n` |

Check the [godoc for full details](https://pkg.go.dev/github.com/thomaspoignant/go-feature-flag/exporter/fileexporter).
Loading