diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index ef8788ac7..000000000 --- a/.drone.yml +++ /dev/null @@ -1,75 +0,0 @@ ---- -# This file must be signed. You can do so with the `mage drone` command - -kind: pipeline -type: docker -name: main - -platform: - os: linux - arch: amd64 - -trigger: - branch: main - event: - - push - -steps: -- name: build - image: grafana/grafana-plugin-ci:1.9.5 - commands: - - mage -v build - -- name: lint - image: grafana/grafana-plugin-ci:1.9.5 - commands: - - mage -v lint - -- name: test - image: grafana/grafana-plugin-ci:1.9.5 - commands: - # -race requires cgo + a C compiler - - apt update - - apt install -y gcc - - mage -v testRace - environment: - CGO_ENABLED: "1" ---- -kind: pipeline -type: docker -name: pr - -platform: - os: linux - arch: amd64 - -trigger: - event: - - pull_request - -steps: -- name: build - image: grafana/grafana-plugin-ci:1.9.5 - commands: - - mage -v build - -- name: lint - image: grafana/grafana-plugin-ci:1.9.5 - commands: - - mage -v lint - -- name: test - image: grafana/grafana-plugin-ci:1.9.5 - commands: - # -race requires cgo + a C compiler - - apt update - - apt install -y gcc - - mage -v testRace - environment: - CGO_ENABLED: "1" - ---- -kind: signature -hmac: cee688a6f8ed3ecb1ddd384e349a6556d28b23b298057d8fa02da37ab50b0ba7 - -... diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..229a5c410 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,53 @@ +name: CI Pipeline + +on: + push: + branches: + - main + pull_request: + +permissions: + contents: read + +env: + GOLANGCI_LINT_VERSION: v1.61.0 + +jobs: + lint-build-test: + name: Lint, Build, and Test + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup go + uses: actions/setup-go@v5 + with: + go-version-file: ./go.mod + + - name: Run golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: ${{env.GOLANGCI_LINT_VERSION}} + args: | + "./..." --timeout=7m + skip-cache: true + install-mode: binary + + - name: Setup Mage + uses: magefile/mage-action@v3 + with: + install-only: true + + - name: Build + run: | + mage -v build + + - name: Install test dependencies + run: | + sudo apt update + sudo apt install -y gcc + + - name: Test + run: | + CGO_ENABLED=1 mage -v testRace diff --git a/.golangci.toml b/.golangci.toml index 8dab26044..68b89d82c 100644 --- a/.golangci.toml +++ b/.golangci.toml @@ -1,5 +1,5 @@ -[run] -skip-files = ["data/.*\\.gen\\.go", "data/generic_nullable_vector\\.go", "data/generic_vector\\.go"] +[issues] +exclude-files = ["data/.*\\.gen\\.go", "data/generic_nullable_vector\\.go", "data/generic_vector\\.go"] [linters-settings.golint] min-confidence = 1 @@ -39,7 +39,7 @@ enable = [ "misspell", "nakedret", "rowserrcheck", - "exportloopref", + "copyloopvar", "staticcheck", "stylecheck", "typecheck", @@ -59,3 +59,8 @@ enable = [ [[issues.exclude-rules]] linters = ["errorlint"] text = "non-wrapping format verb for fmt.Errorf" +[[issues.exclude-rules]] +linters = ["staticcheck"] +text = "SA1019" +[linters-settings.gosec] +excludes = ["G115"] \ No newline at end of file diff --git a/backend/json.go b/backend/json.go index 2754b00bc..ad4a3dc3d 100644 --- a/backend/json.go +++ b/backend/json.go @@ -1,7 +1,7 @@ package backend import ( - "fmt" + "errors" "sort" "unsafe" @@ -166,7 +166,7 @@ func readDataResponseJSON(rsp *DataResponse, iter *jsoniter.Iterator) { for l2Field := iter.ReadObject(); l2Field != ""; l2Field = iter.ReadObject() { switch l2Field { case "error": - rsp.Error = fmt.Errorf(iter.ReadString()) + rsp.Error = errors.New(iter.ReadString()) case "status": rsp.Status = Status(iter.ReadInt32()) diff --git a/data/frame_json_test.go b/data/frame_json_test.go index 9deee2850..ce14e6468 100644 --- a/data/frame_json_test.go +++ b/data/frame_json_test.go @@ -511,7 +511,7 @@ func readNullable{{.Type}}VectorJSON(iter *jsoniter.Iterator, size int) (*nullab tname := caser.String(tstr) tuppr := strings.ToUpper(tstr) - fmt.Printf(" case arrow." + tuppr + ":\n\t\tent = writeArrowData" + tname + "(stream, col)\n") + fmt.Printf(" case arrow.%s:\n\t\tent = writeArrowData%s(stream, col)\n", tuppr, tname) } for _, tstr := range types { @@ -550,8 +550,8 @@ func readNullable{{.Type}}VectorJSON(iter *jsoniter.Iterator, size int) (*nullab for _, tstr := range types { tname := caser.String(tstr) - fmt.Printf(" case FieldType" + tname + ": return read" + tname + "VectorJSON(iter, size)\n") - fmt.Printf(" case FieldTypeNullable" + tname + ": return readNullable" + tname + "VectorJSON(iter, size)\n") + fmt.Printf(" case FieldType%s: return read%sVectorJSON(iter, size)\n", tname, tname) + fmt.Printf(" case FieldTypeNullable%s: return readNullable%sVectorJSON(iter, size)\n", tname, tname) } assert.FailNow(t, "fail so we see the output") diff --git a/data/sqlutil/converter.go b/data/sqlutil/converter.go index 7662549c9..7394ec8b5 100644 --- a/data/sqlutil/converter.go +++ b/data/sqlutil/converter.go @@ -143,7 +143,7 @@ type Converter struct { func DefaultConverterFunc(t reflect.Type) func(in interface{}) (interface{}, error) { return func(in interface{}) (interface{}, error) { inType := reflect.TypeOf(in) - if inType == reflect.PtrTo(t) { + if inType == reflect.PointerTo(t) { n := reflect.ValueOf(in) return n.Elem().Interface(), nil @@ -180,7 +180,7 @@ func NewDefaultConverter(name string, nullable bool, t reflect.Type) Converter { v := reflect.New(t) var fieldType data.FieldType - if v.Type() == reflect.PtrTo(t) { + if v.Type() == reflect.PointerTo(t) { v = v.Elem() fieldType = data.FieldTypeFor(v.Interface()) } else { diff --git a/data/sqlutil/converter_test.go b/data/sqlutil/converter_test.go index 7bb1ed26e..e0b0e8c7c 100644 --- a/data/sqlutil/converter_test.go +++ b/data/sqlutil/converter_test.go @@ -173,7 +173,7 @@ func TestDefaultConverter(t *testing.T) { assert.Equal(t, reflect.TypeOf(value).String(), v.Type.String()) } else { // nullable fields should not exactly match - kind := reflect.PtrTo(v.Type).String() + kind := reflect.PointerTo(v.Type).String() valueKind := reflect.TypeOf(value).String() if !strings.HasPrefix(kind, "*sql.Null") { assert.Equal(t, valueKind, kind) diff --git a/data/time_series.go b/data/time_series.go index f4d191d0b..5cfb2857c 100644 --- a/data/time_series.go +++ b/data/time_series.go @@ -66,7 +66,7 @@ func (t TimeSeriesType) String() string { func (f *Frame) TimeSeriesSchema() TimeSeriesSchema { var tsSchema TimeSeriesSchema tsSchema.Type = TimeSeriesTypeNot - if f.Fields == nil || len(f.Fields) == 0 { + if len(f.Fields) == 0 { return tsSchema } diff --git a/data/time_series_field_sort_test.go b/data/time_series_field_sort_test.go index 24810d3c2..6d748f63e 100644 --- a/data/time_series_field_sort_test.go +++ b/data/time_series_field_sort_test.go @@ -119,7 +119,7 @@ func TestSortWideFrameFields(t *testing.T) { require.NoError(t, err) if diff := cmp.Diff(tt.frameToSort, tt.afterSort, FrameTestCompareOptions()...); diff != "" { t.Errorf("Result mismatch (-want +got):\n%s", diff) - t.Logf(tt.frameToSort.StringTable(-1, -1)) + t.Log(tt.frameToSort.StringTable(-1, -1)) } }) } @@ -210,7 +210,7 @@ func TestSortWideFrameFields_MixedLabels(t *testing.T) { require.NoError(t, err) if diff := cmp.Diff(tt.frameToSort, tt.afterSort, FrameTestCompareOptions()...); diff != "" { t.Errorf("Result mismatch (-want +got):\n%s", diff) - t.Logf(tt.frameToSort.StringTable(-1, -1)) + t.Log(tt.frameToSort.StringTable(-1, -1)) } }) } diff --git a/experimental/concurrent/concurrent.go b/experimental/concurrent/concurrent.go index 8aa6bac65..cec8235d4 100644 --- a/experimental/concurrent/concurrent.go +++ b/experimental/concurrent/concurrent.go @@ -2,6 +2,7 @@ package concurrent import ( "context" + "errors" "fmt" "net/http" @@ -52,7 +53,7 @@ func QueryData(ctx context.Context, req *backend.QueryDataRequest, fn QueryDataF if theErr, ok := r.(error); ok { err = theErr } else if theErrString, ok := r.(string); ok { - err = fmt.Errorf(theErrString) + err = errors.New(theErrString) } else { err = fmt.Errorf("unexpected error - %w", err) } diff --git a/experimental/e2e/config/types.go b/experimental/e2e/config/types.go index d46400e86..96894ef6f 100644 --- a/experimental/e2e/config/types.go +++ b/experimental/e2e/config/types.go @@ -70,14 +70,14 @@ func LoadConfig(path string) (*Config, error) { cfg.Address = "127.0.0.1:9999" } - if cfg.Storage == nil || len(cfg.Storage) == 0 { + if len(cfg.Storage) == 0 { cfg.Storage = []*StorageConfig{{ Type: StorageTypeHAR, Path: "fixtures/e2e.har", }} } - if cfg.Hosts == nil || len(cfg.Hosts) == 0 { + if len(cfg.Hosts) == 0 { cfg.Hosts = make([]string, 0) } diff --git a/experimental/golden_response_checker.go b/experimental/golden_response_checker.go index a9436f508..1586362a9 100644 --- a/experimental/golden_response_checker.go +++ b/experimental/golden_response_checker.go @@ -2,6 +2,8 @@ package experimental import ( "bufio" + "errors" + // ignoring the G505 so that the checksum matches git hash // nolint:gosec "crypto/sha1" @@ -69,7 +71,7 @@ func CheckGoldenDataResponse(path string, dr *backend.DataResponse, updateFile b } if len(errorString) > 0 { - return errorAfterUpdate(fmt.Errorf(errorString), path, dr, updateFile) + return errorAfterUpdate(errors.New(errorString), path, dr, updateFile) } return nil // OK diff --git a/go.mod b/go.mod index a9ba51d0b..b72e708f7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/grafana/grafana-plugin-sdk-go -go 1.21 +go 1.22 require ( github.com/apache/arrow/go/v15 v15.0.2