Skip to content

Commit 130fdf3

Browse files
authored
Merge pull request #33 from aereal/update-workflow
Update workflow
2 parents 1ed88e7 + d79e192 commit 130fdf3

File tree

8 files changed

+183
-52
lines changed

8 files changed

+183
-52
lines changed

Diff for: .github/workflows/ci.yml

+54-32
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,67 @@ on:
77
branches:
88
- main
99
jobs:
10-
lint:
11-
runs-on: ubuntu-latest
10+
ok:
11+
needs:
12+
- test-lint
13+
if: ${{ failure() }}
14+
runs-on: ubuntu-24.04
1215
steps:
13-
- uses: actions/checkout@v4
14-
- name: lint
15-
uses: reviewdog/action-golangci-lint@v2
16-
test:
16+
- run: exit 1
17+
test-lint:
1718
strategy:
1819
matrix:
1920
go_version:
20-
- 1.21.x
21-
- 1.20.x
22-
os:
23-
- ubuntu-latest
24-
runs-on: ${{ matrix.os }}
25-
steps:
26-
- uses: actions/checkout@v4
27-
- uses: actions/setup-go@v5
28-
with:
29-
go-version: ${{ matrix.go_version }}
30-
- name: test
31-
run: go test -race -coverprofile=cover.out -covermode=atomic ./...
32-
- uses: actions/upload-artifact@v3
33-
if: strategy.job-index == 0
34-
with:
35-
name: coverage
36-
path: ./cover.out
37-
if-no-files-found: error
38-
report-coverage:
39-
runs-on: ubuntu-latest
21+
- stable
22+
- oldstable
23+
runs-on: ubuntu-24.04
4024
permissions:
4125
actions: read
4226
contents: read
4327
pull-requests: write
44-
needs:
45-
- test
28+
env:
29+
AQUA_CONFIG: ${{ github.workspace }}/aqua.yaml
30+
AQUA_POLICY_CONFIG: ${{ github.workspace }}/aqua-policy.yaml
4631
steps:
47-
- uses: actions/checkout@v4
48-
- uses: actions/download-artifact@v3
32+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
33+
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
34+
id: setup-go
35+
with:
36+
go-version: ${{ matrix.go_version }}
37+
- run: go mod download
38+
- name: build
39+
run: go build -o /dev/null ./...
40+
- name: test
41+
id: test
42+
continue-on-error: true
43+
run: go test -race -coverprofile=cover.out -covermode=atomic ./...
44+
- uses: k1LoW/octocov-action@1ad702b3118b6a055c00b01db68ca0d9f6641dbc # v1.4.0
45+
if: ${{ matrix.go_version == 'stable' && steps.test.outcome == 'success' }}
46+
- uses: aquaproj/aqua-installer@e2d0136abcf70b7a2f6f505720640750557c4b33 # v3.1.1
4947
with:
50-
name: coverage
51-
- uses: k1LoW/octocov-action@v0
48+
aqua_version: v2.43.3
49+
- run: aqua install
50+
- name: golangci-lint
51+
env:
52+
_go_version: ${{ steps.setup-go.outputs.go-version }}
53+
run: |
54+
golangci-lint run \
55+
--go "$_go_version" \
56+
--out-format line-number \
57+
--issues-exit-code 0 \
58+
--config .golangci.yml \
59+
1>lint-stdout.txt 2>/dev/stderr
60+
- name: reviewdog
61+
env:
62+
REVIEWDOG_GITHUB_API_TOKEN: ${{ github.token }}
63+
run: |
64+
reviewdog \
65+
-name golangci-lint \
66+
-f golangci-lint \
67+
-filter-mode nofilter \
68+
-reporter github-pr-check \
69+
-fail-level error \
70+
< lint-stdout.txt
71+
- name: fail
72+
if: ${{ steps.test.outcome != 'success' }}
73+
run: exit 1

Diff for: .golangci.yml

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
linters:
3+
disable-all: true
4+
enable:
5+
- asasalint
6+
- bidichk
7+
- bodyclose
8+
- contextcheck
9+
- durationcheck
10+
- errcheck
11+
- errchkjson
12+
- errorlint
13+
- exhaustive
14+
- gocheckcompilerdirectives
15+
- gochecksumtype
16+
- gosec
17+
- gosimple
18+
- govet
19+
- ineffassign
20+
- makezero
21+
- nilerr
22+
- reassign
23+
- recvcheck
24+
- spancheck
25+
- staticcheck
26+
- thelper
27+
- unparam
28+
- unused
29+
- usetesting
30+
linters-settings:
31+
errcheck:
32+
check-type-assertions: true
33+
check-blank: true
34+
disable-default-exclusions: false
35+
govet:
36+
disable-all: true
37+
enable:
38+
- appends
39+
- asmdecl
40+
- assign
41+
- atomic
42+
- atomicalign
43+
- bools
44+
- buildtag
45+
- cgocall
46+
- composites
47+
- copylocks
48+
- deepequalerrors
49+
- defers
50+
- directive
51+
- errorsas
52+
- fieldalignment
53+
- findcall
54+
- framepointer
55+
- httpresponse
56+
- ifaceassert
57+
- loopclosure
58+
- lostcancel
59+
- nilfunc
60+
- nilness
61+
- printf
62+
- reflectvaluecompare
63+
- shadow
64+
- shift
65+
- sigchanyzer
66+
- slog
67+
- sortslice
68+
- stdmethods
69+
- stdversion
70+
- stringintconv
71+
- structtag
72+
- testinggoroutine
73+
- tests
74+
- timeformat
75+
- unmarshal
76+
- unreachable
77+
- unsafeptr
78+
- unusedresult
79+
- unusedwrite
80+
- waitgroup

Diff for: .vscode/settings.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"go.lintTool": "golangci-lint",
3+
"go.lintFlags": ["--config=${workspaceFolder}/.golangci.yml"],
4+
}

Diff for: aqua-policy.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
# yaml-language-server: $schema=https://raw.githubusercontent.com/aquaproj/aqua/main/json-schema/policy.json
3+
registries:
4+
- type: standard
5+
ref: semver(">= 3.0.0")
6+
packages:
7+
- registry: standard

Diff for: aqua.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
# yaml-language-server: $schema=https://raw.githubusercontent.com/aquaproj/aqua/main/json-schema/aqua-yaml.json
3+
registries:
4+
- type: standard
5+
ref: v4.311.0 # renovate: depName=aquaproj/aqua-registry
6+
packages:
7+
- name: golangci/[email protected]
8+
- name: reviewdog/[email protected]

Diff for: middleware.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ func defaultReportRequestError(w http.ResponseWriter, err error) {
173173
}
174174
schemaErr := new(openapi3.SchemaError)
175175
if errors.As(requestErr.Err, &schemaErr) {
176-
_ = respondJSON(w, http.StatusBadRequest, rootError{
176+
_ = respondJSON(w, http.StatusBadRequest, rootError{ //nolint:errcheck
177177
Error: errorAggregate{
178178
Request: toReport(schemaErr),
179179
}})
@@ -188,7 +188,7 @@ func defaultReportResponseError(w http.ResponseWriter, err error) {
188188
return
189189
}
190190
if schemaErr := new(openapi3.SchemaError); errors.As(responseErr.Err, &schemaErr) {
191-
_ = respondJSON(w, http.StatusInternalServerError, rootError{
191+
_ = respondJSON(w, http.StatusInternalServerError, rootError{ //nolint:errcheck
192192
Error: errorAggregate{
193193
Response: toReport(schemaErr),
194194
}})
@@ -226,7 +226,7 @@ func respondErrorJSON(w http.ResponseWriter, statusCode int, err error) {
226226
type payload struct {
227227
Error *errorStruct
228228
}
229-
_ = respondJSON(w, statusCode, payload{Error: &errorStruct{Message: err.Error(), Kind: fmt.Sprintf("%T", err)}})
229+
_ = respondJSON(w, statusCode, payload{Error: &errorStruct{Message: err.Error(), Kind: fmt.Sprintf("%T", err)}}) //nolint:errcheck
230230
}
231231

232232
func respondJSON(w http.ResponseWriter, statusCode int, payload interface{}) error {

Diff for: middleware_test.go

+26-16
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,18 @@ type user struct {
4949

5050
func TestWithValidation(t *testing.T) {
5151
testCases := []struct {
52-
name string
5352
handler http.Handler
5453
request func(origin string) *http.Request
5554
routeErrReporter func(w http.ResponseWriter, r *http.Request, err error)
5655
reqErrReporter func(w http.ResponseWriter, r *http.Request, err error)
5756
resErrReporter func(w http.ResponseWriter, r *http.Request, err error)
57+
name string
5858
}{
5959
{
6060
name: "GET /users/{id}: ok",
6161
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
6262
w.Header().Set("content-type", "application/json")
63-
_ = json.NewEncoder(w).Encode(user{Name: "aereal", Age: 17, ID: "123"})
63+
_ = json.NewEncoder(w).Encode(user{Name: "aereal", Age: 17, ID: "123"}) //nolint:errcheck,errchkjson
6464
}),
6565
request: func(origin string) *http.Request {
6666
return mustRequest(newRequest(http.MethodGet, origin+"/users/123", map[string]string{}, ""))
@@ -70,7 +70,7 @@ func TestWithValidation(t *testing.T) {
7070
name: "GET /users/{id}: response error",
7171
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
7272
w.Header().Set("content-type", "application/json")
73-
_ = json.NewEncoder(w).Encode(map[string]interface{}{"name": "aereal", "age": 17})
73+
_ = json.NewEncoder(w).Encode(map[string]interface{}{"name": "aereal", "age": 17}) //nolint:errcheck,errchkjson
7474
}),
7575
request: func(origin string) *http.Request {
7676
return mustRequest(newRequest(http.MethodGet, origin+"/users/123", map[string]string{}, ""))
@@ -80,14 +80,15 @@ func TestWithValidation(t *testing.T) {
8080
name: "GET /users/{id}: response error with custom error handler",
8181
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
8282
w.Header().Set("content-type", "application/json")
83-
_ = json.NewEncoder(w).Encode(map[string]interface{}{"name": "aereal", "age": 17})
83+
_ = json.NewEncoder(w).Encode(map[string]interface{}{"name": "aereal", "age": 17}) //nolint:errcheck,errchkjson
8484
}),
8585
request: func(origin string) *http.Request {
8686
return mustRequest(newRequest(http.MethodGet, origin+"/users/123", map[string]string{}, ""))
8787
},
8888
resErrReporter: func(w http.ResponseWriter, r *http.Request, err error) {
8989
requestNonNil := r != nil
90-
_, errTypeOK := err.(*openapi3filter.ResponseError)
90+
respErr := new(openapi3filter.ResponseError)
91+
errTypeOK := errors.As(err, &respErr)
9192
w.Header().Set("content-type", "text/plain")
9293
w.WriteHeader(http.StatusInternalServerError)
9394
_, _ = fmt.Fprintf(w, "the custom response validation error handler is called: errTypeOK=%t, request=%t", errTypeOK, requestNonNil)
@@ -97,7 +98,7 @@ func TestWithValidation(t *testing.T) {
9798
name: "GET /unknown: find route error (not found)",
9899
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
99100
w.Header().Set("content-type", "application/json")
100-
_ = json.NewEncoder(w).Encode(user{Name: "aereal", Age: 17, ID: "123"})
101+
_ = json.NewEncoder(w).Encode(user{Name: "aereal", Age: 17, ID: "123"}) //nolint:errcheck,errchkjson
101102
}),
102103
request: func(origin string) *http.Request {
103104
return mustRequest(newRequest(http.MethodGet, origin+"/unknown", map[string]string{}, ""))
@@ -114,7 +115,7 @@ func TestWithValidation(t *testing.T) {
114115
name: "GET /users: find route error (method not allowed)",
115116
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
116117
w.Header().Set("content-type", "application/json")
117-
_ = json.NewEncoder(w).Encode(user{Name: "aereal", Age: 17, ID: "123"})
118+
_ = json.NewEncoder(w).Encode(user{Name: "aereal", Age: 17, ID: "123"}) //nolint:errcheck,errchkjson
118119
}),
119120
request: func(origin string) *http.Request {
120121
return mustRequest(newRequest(http.MethodGet, origin+"/users", map[string]string{}, ""))
@@ -131,7 +132,7 @@ func TestWithValidation(t *testing.T) {
131132
name: "POST /users: ok",
132133
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
133134
w.Header().Set("content-type", "application/json")
134-
_ = json.NewEncoder(w).Encode(user{Name: "aereal", Age: 17, ID: "123"})
135+
_ = json.NewEncoder(w).Encode(user{Name: "aereal", Age: 17, ID: "123"}) //nolint:errcheck,errchkjson
135136
}),
136137
request: func(origin string) *http.Request {
137138
return mustRequest(newRequest(http.MethodPost, origin+"/users", map[string]string{"content-type": "application/json"}, `{"name":"aereal","age":17}`))
@@ -156,7 +157,8 @@ func TestWithValidation(t *testing.T) {
156157
},
157158
reqErrReporter: func(w http.ResponseWriter, r *http.Request, err error) {
158159
requestNonNil := r != nil
159-
_, errTypeOK := err.(*openapi3filter.RequestError)
160+
reqErr := new(openapi3filter.RequestError)
161+
errTypeOK := errors.As(err, &reqErr)
160162
w.Header().Set("content-type", "text/plain")
161163
w.WriteHeader(http.StatusBadRequest)
162164
_, _ = fmt.Fprintf(w, "the custom response validation error handler is called: errTypeOK=%t, request=%t", errTypeOK, requestNonNil)
@@ -177,10 +179,12 @@ func TestWithValidation(t *testing.T) {
177179
if err != nil {
178180
t.Fatal(err)
179181
}
182+
t.Cleanup(func() { gotResp.Body.Close() })
180183
expectedResp, err := resumeResponse(t.Name(), gotResp)
181184
if err != nil {
182185
t.Fatal(err)
183186
}
187+
t.Cleanup(func() { expectedResp.Body.Close() })
184188
if err := testResponse(expectedResp, gotResp); err != nil {
185189
t.Error(err)
186190
}
@@ -190,8 +194,8 @@ func TestWithValidation(t *testing.T) {
190194

191195
func TestWithValidation_otel(t *testing.T) {
192196
testCases := []struct {
193-
name string
194197
buildOptions func(tp trace.TracerProvider) MiddlewareOptions
198+
name string
195199
wantSpans int
196200
}{
197201
{
@@ -226,15 +230,15 @@ func TestWithValidation_otel(t *testing.T) {
226230

227231
withOtel := func(next http.Handler) http.Handler {
228232
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
229-
ctx := otel.GetTextMapPropagator().Extract(r.Context(), propagation.HeaderCarrier(r.Header))
230-
ctx, span := tp.Tracer("test").Start(ctx, fmt.Sprintf("%s %s", r.Method, r.URL.Path))
233+
reqCtx := otel.GetTextMapPropagator().Extract(r.Context(), propagation.HeaderCarrier(r.Header))
234+
reqCtx, span := tp.Tracer("test").Start(reqCtx, fmt.Sprintf("%s %s", r.Method, r.URL.Path))
231235
defer span.End()
232-
next.ServeHTTP(w, r.WithContext(ctx))
236+
next.ServeHTTP(w, r.WithContext(reqCtx))
233237
})
234238
}
235239
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
236240
w.Header().Set("content-type", "application/json")
237-
_ = json.NewEncoder(w).Encode(user{Name: "aereal", Age: 17, ID: "123"})
241+
_ = json.NewEncoder(w).Encode(user{Name: "aereal", Age: 17, ID: "123"}) //nolint:errcheck,errchkjson
238242
})
239243
srv := httptest.NewServer(withOtel(WithValidation(tc.buildOptions(tp))(handler)))
240244
defer srv.Close()
@@ -328,8 +332,14 @@ func testResponse(expected, got *http.Response) error {
328332
if got.StatusCode != expected.StatusCode {
329333
return fmt.Errorf("StatusCode: got=%d expected=%d", got.StatusCode, expected.StatusCode)
330334
}
331-
expectedBody, _ := io.ReadAll(expected.Body)
332-
gotBody, _ := io.ReadAll(got.Body)
335+
expectedBody, err := io.ReadAll(expected.Body)
336+
if err != nil {
337+
return err
338+
}
339+
gotBody, err := io.ReadAll(got.Body)
340+
if err != nil {
341+
return err
342+
}
333343
defer func() {
334344
// rewind body
335345
expected.Body = io.NopCloser(bytes.NewReader(expectedBody))

Diff for: response_writer.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func (rw *bufferingResponseWriter) emit() {
1919
if rw.statusCode != 0 {
2020
rw.rw.WriteHeader(rw.statusCode)
2121
}
22-
_, _ = rw.buf.WriteTo(rw.rw)
22+
_, _ = rw.buf.WriteTo(rw.rw) //nolint:errcheck
2323
}
2424

2525
func (rw *bufferingResponseWriter) Write(b []byte) (int, error) {

0 commit comments

Comments
 (0)