This commit is contained in:
Adityasinghvats 2025-06-13 22:26:43 +05:30
commit 80e07f092e
11 changed files with 245 additions and 12 deletions

View File

@ -4,6 +4,7 @@ on:
branches:
- main
pull_request:
merge_group:
permissions:
# Required: allow read access to the content for analysis.
@ -28,4 +29,4 @@ jobs:
uses: golangci/golangci-lint-action@v6
with:
version: v1.64
only-new-issues: true
only-new-issues: true

View File

@ -57,7 +57,7 @@ jobs:
go-version-file: 'go.mod'
- name: Run all integration tests with Dagger
uses: dagger/dagger-for-github@v5
uses: dagger/dagger-for-github@b81317a976cb7f7125469707321849737cd1b3bc # v7
with:
workdir: .
verb: run

View File

@ -1,4 +1,4 @@
FROM alpine:3.21
FROM alpine:3.22
COPY ./openfeature usr/local/bin/openfeature

View File

@ -10,6 +10,11 @@ test-integration-csharp:
@echo "Running C# integration test with Dagger..."
@go run ./test/integration/cmd/csharp/run.go
.PHONY: test-integration-go
test-integration-go:
@echo "Running Go integration test with Dagger..."
@go run ./test/integration/cmd/go/run.go
.PHONY: test-integration
test-integration:
@echo "Running all integration tests with Dagger..."

14
go.mod
View File

@ -3,18 +3,18 @@ module github.com/open-feature/cli
go 1.23.0
require (
dagger.io/dagger v0.18.9
dagger.io/dagger v0.18.10
github.com/google/go-cmp v0.7.0
github.com/iancoleman/strcase v0.3.0
github.com/invopop/jsonschema v0.13.0
github.com/pterm/pterm v0.12.80
github.com/pterm/pterm v0.12.81
github.com/spf13/afero v1.14.0
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/spf13/viper v1.20.1
github.com/stretchr/testify v1.10.0
github.com/xeipuuv/gojsonschema v1.2.0
golang.org/x/text v0.25.0
golang.org/x/text v0.26.0
gopkg.in/yaml.v3 v3.0.1
)
@ -22,7 +22,7 @@ require (
atomicgo.dev/cursor v0.2.0 // indirect
atomicgo.dev/keyboard v0.2.9 // indirect
atomicgo.dev/schedule v0.1.0 // indirect
github.com/99designs/gqlgen v0.17.73 // indirect
github.com/99designs/gqlgen v0.17.74 // indirect
github.com/Khan/genqlient v0.8.1 // indirect
github.com/adrg/xdg v0.5.3 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
@ -75,12 +75,12 @@ require (
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20250530174510-65e920069ea6 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/sync v0.14.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sync v0.15.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
google.golang.org/grpc v1.72.2 // indirect
google.golang.org/grpc v1.73.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
)

14
go.sum
View File

@ -8,8 +8,12 @@ atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs=
atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU=
dagger.io/dagger v0.18.9 h1:IXZhlGm893LuqYFpo6VHtaCAEP6Qz0VjMhLvyKQVl1Y=
dagger.io/dagger v0.18.9/go.mod h1:e6Y+sAPWh04pHvBf4s3sSiOe1QMoCEcccmMv898RnZA=
dagger.io/dagger v0.18.10 h1:Ibyz5LqxjjEHfLMlaU9PJ3xt3ju7p29RWy0lVfvSNU0=
dagger.io/dagger v0.18.10/go.mod h1:VSj+2HMd/EnaCVt7gTY70p8LBW+oQDYjA1XTadr8vBE=
github.com/99designs/gqlgen v0.17.73 h1:A3Ki+rHWqKbAOlg5fxiZBnz6OjW3nwupDHEG15gEsrg=
github.com/99designs/gqlgen v0.17.73/go.mod h1:2RyGWjy2k7W9jxrs8MOQthXGkD3L3oGr0jXW3Pu8lGg=
github.com/99designs/gqlgen v0.17.74 h1:1FuVtkXxOc87xpKio3f6sohREmec+Jvy86PcYOuwgWo=
github.com/99designs/gqlgen v0.17.74/go.mod h1:a+iR6mfRLNRp++kDpooFHiPWYiWX3Yu1BIilQRHgh10=
github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs=
github.com/Khan/genqlient v0.8.1/go.mod h1:R2G6DzjBvCbhjsEajfRjbWdVglSH/73kSivC9TLWVjU=
github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs=
@ -106,6 +110,8 @@ github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5b
github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s=
github.com/pterm/pterm v0.12.80 h1:mM55B+GnKUnLMUSqhdINe4s6tOuVQIetQ3my8JGyAIg=
github.com/pterm/pterm v0.12.80/go.mod h1:c6DeF9bSnOSeFPZlfs4ZRAFcf5SCoTwvwQ5xaKGQlHo=
github.com/pterm/pterm v0.12.81 h1:ju+j5I2++FO1jBKMmscgh5h5DPFDFMB7epEjSoKehKA=
github.com/pterm/pterm v0.12.81/go.mod h1:TyuyrPjnxfwP+ccJdBTeWHtd/e0ybQHkOS/TakajZCw=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
@ -206,11 +212,15 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -238,6 +248,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
@ -249,6 +261,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8=
google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -9,8 +9,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="OpenFeature" Version="2.3.2" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.6" />
<PackageReference Include="OpenFeature" Version="2.6.0" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,13 @@
module github.com/open-feature/cli/test/go-integration
go 1.22
require github.com/open-feature/go-sdk v1.15.0
require (
github.com/go-logr/logr v1.4.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.6.0 // indirect
golang.org/x/net v0.21.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
)

View File

@ -0,0 +1,90 @@
package main
import (
"context"
"fmt"
"os"
generated "github.com/open-feature/cli/test/go-integration/openfeature"
"github.com/open-feature/go-sdk/openfeature"
"github.com/open-feature/go-sdk/openfeature/memprovider"
)
func main() {
if err := run(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func run() error {
// Set up the in-memory provider with test flags
provider := memprovider.NewInMemoryProvider(map[string]memprovider.InMemoryFlag{
"discountPercentage": {
State: memprovider.Enabled,
DefaultVariant: "default",
Variants: map[string]any{
"default": 0.15,
},
},
"enableFeatureA": {
State: memprovider.Enabled,
DefaultVariant: "default",
Variants: map[string]any{
"default": false,
},
},
"greetingMessage": {
State: memprovider.Enabled,
DefaultVariant: "default",
Variants: map[string]any{
"default": "Hello there!",
},
},
"usernameMaxLength": {
State: memprovider.Enabled,
DefaultVariant: "default",
Variants: map[string]any{
"default": 50,
},
},
})
// Set the provider and wait for it to be ready
err := openfeature.SetProviderAndWait(provider)
if err != nil {
return fmt.Errorf("Failed to set provider: %w", err)
}
ctx := context.Background()
evalCtx := openfeature.NewEvaluationContext("someid", map[string]any{})
// Use the generated code for all flag evaluations
enableFeatureA, err := generated.EnableFeatureA.Value(ctx, evalCtx)
if err != nil {
return fmt.Errorf("Error evaluating boolean flag: %w", err)
}
fmt.Printf("enableFeatureA: %v\n", enableFeatureA)
discount, err := generated.DiscountPercentage.Value(ctx, evalCtx)
if err != nil {
return fmt.Errorf("Failed to get discount: %w", err)
}
fmt.Printf("Discount Percentage: %.2f\n", discount)
greetingMessage, err := generated.GreetingMessage.Value(ctx, evalCtx)
if err != nil {
return fmt.Errorf("Error evaluating string flag: %w", err)
}
fmt.Printf("greetingMessage: %v\n", greetingMessage)
usernameMaxLength, err := generated.UsernameMaxLength.Value(ctx, evalCtx)
if err != nil {
return fmt.Errorf("Error evaluating int flag: %v\n", err)
}
fmt.Printf("usernameMaxLength: %v\n", usernameMaxLength)
fmt.Println("Generated Go code compiles successfully!")
return nil
}

View File

@ -0,0 +1,101 @@
package main
import (
"context"
"fmt"
"os"
"path/filepath"
"dagger.io/dagger"
"github.com/open-feature/cli/test/integration"
)
// Test implements the integration test for the Go generator
type Test struct {
// ProjectDir is the absolute path to the root of the project
ProjectDir string
// TestDir is the absolute path to the test directory
TestDir string
}
// New creates a new Test
func New(projectDir, testDir string) *Test {
return &Test{
ProjectDir: projectDir,
TestDir: testDir,
}
}
// Run executes the Go integration test using Dagger
func (t *Test) Run(ctx context.Context, client *dagger.Client) (*dagger.Container, error) {
// Source code container
source := client.Host().Directory(t.ProjectDir)
testFiles := client.Host().Directory(t.TestDir, dagger.HostDirectoryOpts{
Include: []string{"test.go", "go.mod"},
})
// Build the CLI
cli := client.Container().
From("golang:1.23-alpine").
WithExec([]string{"apk", "add", "--no-cache", "git"}).
WithDirectory("/src", source).
WithWorkdir("/src").
WithExec([]string{"go", "mod", "tidy"}).
WithExec([]string{"go", "mod", "download"}).
WithExec([]string{"go", "build", "-o", "cli", "./cmd/openfeature"})
// Generate Go client
generated := cli.WithExec([]string{
"./cli", "generate", "go",
"--manifest=/src/sample/sample_manifest.json",
"--output=/tmp/generated",
"--package-name=openfeature",
})
// Get generated files
generatedFiles := generated.Directory("/tmp/generated")
// Test Go compilation with the generated files
goContainer := client.Container().
From("golang:1.23-alpine").
WithExec([]string{"apk", "add", "--no-cache", "git"}).
WithWorkdir("/app").
WithDirectory("/app", testFiles).
WithDirectory("/app/openfeature", generatedFiles).
WithExec([]string{"go", "mod", "tidy"}).
WithExec([]string{"go", "build", "-o", "test", "-v"}).
WithExec([]string{"./test"})
return goContainer, nil
}
// Name returns the name of the integration test
func (t *Test) Name() string {
return "go"
}
func main() {
ctx := context.Background()
// Get project root
projectDir, err := filepath.Abs(os.Getenv("PWD"))
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get project dir: %v\n", err)
os.Exit(1)
}
// Get test directory
testDir, err := filepath.Abs(filepath.Join(projectDir, "test/go-integration"))
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get test dir: %v\n", err)
os.Exit(1)
}
// Create and run the Go integration test
test := New(projectDir, testDir)
if err := integration.RunTest(ctx, test); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}

View File

@ -20,6 +20,15 @@ func main() {
os.Exit(1)
}
// Run the Go integration test
goCmd := exec.Command("go", "run", "github.com/open-feature/cli/test/integration/cmd/go")
goCmd.Stdout = os.Stdout
goCmd.Stderr = os.Stderr
if err := goCmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error running Go integration test: %v\n", err)
os.Exit(1)
}
// Add more tests here as they are available
fmt.Println("=== All integration tests passed successfully ===")