Skip to content

Commit

Permalink
Allow more variations for a flag (#363)
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaspoignant authored Oct 12, 2022
1 parent ea8d9d0 commit e404d17
Show file tree
Hide file tree
Showing 125 changed files with 98,038 additions and 42,778 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: Setup go
uses: actions/setup-go@v3
with:
go-version: '^1.16.0'
go-version: '^1.18.0'
- run: make lint

Test:
Expand All @@ -26,7 +26,7 @@ jobs:
- name: Setup go
uses: actions/setup-go@v3
with:
go-version: '^1.16.0'
go-version: '^1.18.0'
- run: make test

Coverage:
Expand All @@ -40,7 +40,7 @@ jobs:
- name: Setup go
uses: actions/setup-go@v3
with:
go-version: '^1.16.0'
go-version: '^1.18.0'
- run: make coverage
- uses: shogo82148/actions-goveralls@v1
with:
Expand All @@ -56,7 +56,7 @@ jobs:
- name: Setup go
uses: actions/setup-go@v3
with:
go-version: '^1.16.0'
go-version: '^1.18.0'
- name: Run benchmark
run: make bench | tee bench-output.txt
- name: Download previous benchmark data
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ vendor/

# venv created for the documentation script
.venv

# binaries
cmd/migrationcli/migrationcli
2 changes: 2 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ linters-settings:
- singleCaseSwitch
golint:
min-confidence: 0.6
gosimple:
checks: ["all","-S1023"]
gofumpt:
module-path: github.com/thomaspoignant/go-feature-flag
lang-version: "1.17"
Expand Down
57 changes: 45 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,56 @@ GOCMD=go
GOTEST=$(GOCMD) test
GOVET=$(GOCMD) vet

GREEN := $(shell tput -Txterm setaf 2)
YELLOW := $(shell tput -Txterm setaf 3)
WHITE := $(shell tput -Txterm setaf 7)
CYAN := $(shell tput -Txterm setaf 6)
RESET := $(shell tput -Txterm sgr0)

.PHONY: all test build vendor

lint:
mkdir -p ./bin
# Install linters
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s latest
# Run linters
./bin/golangci-lint run --deadline=3m --timeout=3m ./...
all: help

test:
$(GOTEST) -v -race ./...
## Build:
build: build-migrationcli ## Build all the binaries and put the output in out/bin/

coverage:
$(GOTEST) -cover -covermode=count -coverprofile=coverage.cov ./...
build-migrationcli: ## Build the migration cli out/bin/
mkdir -p out/bin
GO111MODULE=on $(GOCMD) build -mod vendor -o out/bin/migrationcli ./cmd/migrationcli/

clean: ## Remove build related file
rm -fr ./bin
rm -fr ./out
rm -f ./junit-report.xml checkstyle-report.xml ./coverage.xml ./profile.cov yamllint-checkstyle.xml

vendor:
vendor: ## Copy of all packages needed to support builds and tests in the vendor directory
$(GOCMD) mod tidy
$(GOCMD) mod vendor

bench:
## Test:
test: ## Run the tests of the project
$(GOTEST) -v -race ./...

coverage: ## Run the tests of the project and export the coverage
$(GOTEST) -cover -covermode=count -coverprofile=coverage.cov ./...

bench: ## Launch the benchmark test
$(GOTEST) -bench Benchmark -cpu 2 -run=^$$

## Lint:
lint: ## Use golintci-lint on your project
mkdir -p ./bin
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s latest # Install linters
./bin/golangci-lint run --deadline=3m --timeout=3m ./... # Run linters

## Help:
help: ## Show this help.
@echo ''
@echo 'Usage:'
@echo ' ${YELLOW}make${RESET} ${GREEN}<target>${RESET}'
@echo ''
@echo 'Targets:'
@awk 'BEGIN {FS = ":.*?## "} { \
if (/^[a-zA-Z_-]+:.*?##.*$$/) {printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n", $$1, $$2} \
else if (/^## .*$$/) {printf " ${CYAN}%s${RESET}\n", substr($$1,4)} \
}' $(MAKEFILE_LIST)
180 changes: 111 additions & 69 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
> ## go-feature-flag v1 feedback
> go-feature-flag is heading towards v1 and it may require a change on how to design your flags _(no worries we will keep backward compatibility)_.
> The roadmap is now publicly available in this [issue #291](https://github.com/thomaspoignant/go-feature-flag/issues/291), feel free to comment and give any feedback.
<p align="center">
<img width="250" height="238" src="logo.png" alt="go-feature-flag logo" />
</p>
Expand Down Expand Up @@ -30,7 +26,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 +54,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 +165,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 +258,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 +303,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
Loading

0 comments on commit e404d17

Please sign in to comment.