From 73b069644a2cccab42d32275b6f30036f5f0ee33 Mon Sep 17 00:00:00 2001 From: Jonathan Norris Date: Fri, 10 Jul 2026 09:56:18 -0400 Subject: [PATCH 1/2] chore: resolve open dependabot security alerts - golang.org/x/crypto v0.45.0 -> v0.54.0 (critical/high/medium, alerts #24-#36) - golang.org/x/net v0.47.0 -> v0.57.0 (medium, alert #23) - go directive 1.24.0 -> 1.25.0 (required by x/crypto v0.54.0) - golangci-lint-action v4 -> v8 (golangci-lint v2 required for Go 1.25) - add .golangci.yml to suppress pre-existing style checks, fix ST1005 and errcheck issues --- .github/workflows/lint.yml | 2 +- .golangci.yml | 17 +++++++++++++++++ bucketing/model_filters.go | 8 ++++---- client.go | 2 +- config_metadata_test.go | 10 +++++----- configmanager.go | 6 +----- event_manager.go | 2 +- example/hooks/main.go | 2 +- go.mod | 10 +++++----- go.sum | 16 ++++++++-------- request.go | 2 +- 11 files changed, 45 insertions(+), 32 deletions(-) create mode 100644 .golangci.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 23213088..af95af29 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -22,7 +22,7 @@ jobs: go-version-file: go.mod cache: false - name: golangci-lint - uses: golangci/golangci-lint-action@v4 + uses: golangci/golangci-lint-action@v8 with: version: latest args: --disable unused diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..c1c99dd5 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,17 @@ +version: "2" +linters: + settings: + staticcheck: + checks: + - "all" + - "-ST1000" # package comments — pre-existing + - "-ST1003" # naming conventions — pre-existing public API names + - "-ST1011" # unit-specific suffixes in public API field names + - "-ST1016" # receiver name consistency — pre-existing + - "-ST1020" # exported method comment form — pre-existing + - "-ST1021" # exported type comment form — pre-existing + - "-ST1022" # exported var comment form — pre-existing + - "-QF1001" # De Morgan's law refactors — style suggestion + - "-QF1003" # tagged switch refactors — style suggestion + - "-QF1004" # strings.ReplaceAll — style suggestion + - "-QF1008" # embedded field selectors — style suggestion diff --git a/bucketing/model_filters.go b/bucketing/model_filters.go index ca2a3acc..a233ee3f 100644 --- a/bucketing/model_filters.go +++ b/bucketing/model_filters.go @@ -165,7 +165,7 @@ func (u *UserFilter) compileValues() error { if val, ok := value.(bool); ok { boolValues = append(boolValues, val) } else { - return fmt.Errorf("filter values must be all of the same type. Expected: bool, got: %T %#v\n", value, value) + return fmt.Errorf("filter values must be all of the same type. Expected: bool, got: %T %#v", value, value) } } u.CompiledBoolVals = boolValues @@ -175,7 +175,7 @@ func (u *UserFilter) compileValues() error { if val, ok := value.(string); ok { stringValues = append(stringValues, val) } else { - return fmt.Errorf("filter values must be all of the same type. Expected: string, got: %T %#v\n", value, value) + return fmt.Errorf("filter values must be all of the same type. Expected: string, got: %T %#v", value, value) } } u.CompiledStringVals = stringValues @@ -185,12 +185,12 @@ func (u *UserFilter) compileValues() error { if val, ok := value.(float64); ok { numValues = append(numValues, val) } else { - return fmt.Errorf("filter values must be all of the same type. Expected: number, got: %T %#v\n", value, value) + return fmt.Errorf("filter values must be all of the same type. Expected: number, got: %T %#v", value, value) } } u.CompiledNumVals = numValues default: - return fmt.Errorf("filter values must be of type bool, string, or float64. Got: %T %#v\n", firstValue, firstValue) + return fmt.Errorf("filter values must be of type bool, string, or float64. Got: %T %#v", firstValue, firstValue) } return nil diff --git a/client.go b/client.go index 0ccc28d7..70ecbc80 100644 --- a/client.go +++ b/client.go @@ -661,7 +661,7 @@ func (c *Client) performRequest( httpResponse, err = c.callAPI(r) if httpResponse == nil && err == nil { - err = errors.New("Nil httpResponse") + err = errors.New("nil httpResponse") } if err != nil { time.Sleep(time.Duration(exponentialBackoff(attempt)) * time.Millisecond) // wait with exponential backoff diff --git a/config_metadata_test.go b/config_metadata_test.go index 85521435..329f84d1 100644 --- a/config_metadata_test.go +++ b/config_metadata_test.go @@ -47,7 +47,7 @@ func TestConfigMetadata_ExtractionAndStorage(t *testing.T) { client, err := NewClient(sdkKey, options) require.NoError(t, err) - defer client.Close() + defer client.Close() //nolint:errcheck // Wait for config to load time.Sleep(time.Millisecond * 500) @@ -99,7 +99,7 @@ func TestConfigMetadata_CloudSDKReturnsNil(t *testing.T) { client, err := NewClient(sdkKey, options) require.NoError(t, err) - defer client.Close() + defer client.Close() //nolint:errcheck // Test that metadata returns error for cloud SDK _, err = client.GetMetadata() @@ -170,7 +170,7 @@ func TestConfigMetadata_AvailableInAllHooks(t *testing.T) { client, err := NewClient(sdkKey, options) require.NoError(t, err) - defer client.Close() + defer client.Close() //nolint:errcheck // Wait for config to load time.Sleep(time.Millisecond * 500) @@ -261,7 +261,7 @@ func TestConfigMetadata_AvailableInErrorHook(t *testing.T) { client, err := NewClient(sdkKey, options) require.NoError(t, err) - defer client.Close() + defer client.Close() //nolint:errcheck // Wait for config to load time.Sleep(time.Millisecond * 500) @@ -302,7 +302,7 @@ func TestConfigMetadata_NullSafetyDuringInitialization(t *testing.T) { client, err := NewClient(sdkKey, options) require.NoError(t, err) - defer client.Close() + defer client.Close() //nolint:errcheck // Wait a bit for the failed config load attempt time.Sleep(time.Millisecond * 100) diff --git a/configmanager.go b/configmanager.go index 9742eada..4072a508 100644 --- a/configmanager.go +++ b/configmanager.go @@ -318,11 +318,7 @@ func (e *EnvironmentConfigManager) fetchConfig(numRetriesRemaining int, minimumL // Infinitely retry 500s util.Warnf("Config fetch failed. Status:" + resp.Status) default: - err = fmt.Errorf("unexpected response code: %d\n"+ - "Body: %s\n"+ - "URL: %s\n"+ - "Headers: %s\n"+ - "Could not download configuration. Using cached version if available %s\n", + err = fmt.Errorf("unexpected response code: %d\nBody: %s\nURL: %s\nHeaders: %s\nCould not download configuration. Using cached version if available %s", resp.StatusCode, resp.Body, e.getConfigURL(), resp.Header, resp.Header.Get("ETag")) } diff --git a/event_manager.go b/event_manager.go index 020dc7da..1e58a07f 100644 --- a/event_manager.go +++ b/event_manager.go @@ -92,7 +92,7 @@ func NewEventManager(options *Options, localBucketing InternalEventQueue, cfg *H func (e *EventManager) QueueEvent(user User, event Event) error { if e.closed { - return fmt.Errorf("devcycle client was closed, no more events can be tracked.") + return fmt.Errorf("devcycle client was closed, no more events can be tracked") } queueSize, err := e.internalQueue.UserQueueLength() if err != nil { diff --git a/example/hooks/main.go b/example/hooks/main.go index b8bfe67d..4413b1a1 100644 --- a/example/hooks/main.go +++ b/example/hooks/main.go @@ -136,5 +136,5 @@ func main() { missingVariable.Key, missingVariable.Value, missingVariable.Type_, missingVariable.IsDefaulted) } - client.Close() + _ = client.Close() } diff --git a/go.mod b/go.mod index 77f7f5c6..03f014bc 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/devcyclehq/go-server-sdk/v2 -go 1.24.0 +go 1.25.0 require ( github.com/go-playground/validator/v10 v10.25.0 @@ -22,11 +22,11 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.45.0 // indirect + golang.org/x/crypto v0.54.0 // indirect golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.57.0 // indirect + golang.org/x/sys v0.47.0 // indirect + golang.org/x/text v0.40.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d15c68c9..d9617b4f 100644 --- a/go.sum +++ b/go.sum @@ -43,16 +43,16 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/twmb/murmur3 v1.1.8 h1:8Yt9taO/WN3l08xErzjeschgZU2QSrwm1kclYq+0aRg= github.com/twmb/murmur3 v1.1.8/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= +golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= +golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= +golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/request.go b/request.go index 018c5673..efcab063 100644 --- a/request.go +++ b/request.go @@ -53,7 +53,7 @@ func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err e } if bodyBuf.Len() == 0 { - err = fmt.Errorf("invalid body type %s\n", contentType) + err = fmt.Errorf("invalid body type %s", contentType) return nil, err } return bodyBuf, nil From 45a8c29427c0ff351b9275bd8571433513248f83 Mon Sep 17 00:00:00 2001 From: Jonathan Norris Date: Mon, 13 Jul 2026 11:24:35 -0400 Subject: [PATCH 2/2] fix: replace deprecated reflect.Ptr with reflect.Pointer --- request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/request.go b/request.go index efcab063..a4e487e4 100644 --- a/request.go +++ b/request.go @@ -65,7 +65,7 @@ func detectContentType(body interface{}) string { kind := reflect.TypeOf(body).Kind() switch kind { - case reflect.Struct, reflect.Map, reflect.Ptr: + case reflect.Struct, reflect.Map, reflect.Pointer: contentType = "application/json; charset=utf-8" case reflect.String: contentType = "text/plain; charset=utf-8"