Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 8 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: "2"

linters:
default: standard

run:
tests: true
timeout: 5m
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion google_mail/google_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion google_mail/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
8 changes: 6 additions & 2 deletions web/mail.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
}
4 changes: 3 additions & 1 deletion web/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion web/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})
}
Expand Down
Loading