From 7d4c0ab6cff8ccf0ec989a85c276fd7a9fb8e35d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Theodor=20Angerg=C3=A5rd?= Date: Mon, 7 Sep 2026 20:34:52 +0200 Subject: [PATCH] ci: enforce golangci-lint standard preset --- .github/workflows/test.yml | 12 ++++++++++++ .golangci.yml | 8 ++++++++ README.md | 3 +++ go.mod | 2 +- google_mail/google_service.go | 2 +- google_mail/integration_test.go | 2 +- web/mail.go | 8 ++++++-- web/router.go | 4 +++- web/router_test.go | 2 +- 9 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 .golangci.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7ff65d6..49eca78 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,3 +18,15 @@ jobs: go-version-file: go.mod cache: true - run: go test -race ./... + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + - uses: golangci/golangci-lint-action@v9 + with: + version: v2.13.2 diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..760ef94 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,8 @@ +version: "2" + +linters: + default: standard + +run: + tests: true + timeout: 5m diff --git a/README.md b/README.md index 5aeb113..663b5a7 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,9 @@ simulates success, quota errors, service failures, and malformed responses. Run just these tests with `go test -race ./google_mail -run TestGmailIntegration`. They test our API integration contract, not Google-side permissions or delivery. +Run `golangci-lint run` with golangci-lint v2.13.2 for the same lint checks as +CI. `.golangci.yml` enables the standard default preset, including test files. + ### Manual Use Go 1.27.1, matching `go.mod`, CI, and the Docker build images. 1. Follow the steps in [Setup](#setup) and enable debug mode. diff --git a/go.mod b/go.mod index d194c0c..cfbdb59 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b github.com/spf13/viper v1.20.0 github.com/stretchr/testify v1.10.0 - golang.org/x/net v0.37.0 golang.org/x/oauth2 v0.28.0 google.golang.org/api v0.227.0 ) @@ -41,6 +40,7 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.37.0 // indirect golang.org/x/sys v0.31.0 // indirect golang.org/x/text v0.23.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect diff --git a/google_mail/google_service.go b/google_mail/google_service.go index 59fa564..8b88450 100644 --- a/google_mail/google_service.go +++ b/google_mail/google_service.go @@ -6,7 +6,7 @@ import ( "google.golang.org/api/gmail/v1" // Imports as gmail "google.golang.org/api/option" - "golang.org/x/net/context" + "context" "golang.org/x/oauth2/google" "encoding/base64" diff --git a/google_mail/integration_test.go b/google_mail/integration_test.go index 7c37f32..3f6ff92 100644 --- a/google_mail/integration_test.go +++ b/google_mail/integration_test.go @@ -111,7 +111,7 @@ func TestGmailIntegration(t *testing.T) { client := &http.Client{Timeout: 5 * time.Second} response, err := client.Do(req) require.NoError(t, err) - defer response.Body.Close() + defer func() { assert.NoError(t, response.Body.Close()) }() assert.Equal(t, tc.wantStatus, response.StatusCode) select { case assertion := <-assertions: diff --git a/web/mail.go b/web/mail.go index 829bdcc..1a61fc2 100644 --- a/web/mail.go +++ b/web/mail.go @@ -21,7 +21,9 @@ func (c *Context) SendMail(rw web.ResponseWriter, req *web.Request) { // Read request body body, err := io.ReadAll(req.Body) - req.Body.Close() + if closeErr := req.Body.Close(); closeErr != nil { + c.printError(closeErr) + } if err != nil { c.printError(err) rw.WriteHeader(http.StatusBadRequest) @@ -54,5 +56,7 @@ func (c *Context) SendMail(rw web.ResponseWriter, req *web.Request) { // Return the sent email rw.WriteHeader(http.StatusOK) - rw.Write(data) + if _, err := rw.Write(data); err != nil { + c.printError(err) + } } diff --git a/web/router.go b/web/router.go index 0061a59..3282972 100644 --- a/web/router.go +++ b/web/router.go @@ -36,7 +36,9 @@ func setMailServiceProvider(mailServiceProvider func() gotify.MailService) func( return func(c *Context, rw web.ResponseWriter, req *web.Request, next web.NextMiddlewareFunc) { c.MailService = mailServiceProvider() next(rw, req) - c.MailService.Destroy() + if err := c.MailService.Destroy(); err != nil { + c.printError(err) + } } } diff --git a/web/router_test.go b/web/router_test.go index 8dbf5ed..c723465 100644 --- a/web/router_test.go +++ b/web/router_test.go @@ -28,7 +28,7 @@ func TestRoutingContract(t *testing.T) { req.Header.Set("Authorization", "pre-shared: secret") response, err := server.Client().Do(req) require.NoError(t, err) - defer response.Body.Close() + defer func() { assert.NoError(t, response.Body.Close()) }() assert.Equal(t, tc.status, response.StatusCode) }) }