Skip to content
Merged
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
100 changes: 100 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: CI

on:
pull_request:
push:
branches: [main]

jobs:
test:
name: Test (Go ${{ matrix.go-version }})
runs-on: ubuntu-latest
strategy:
matrix:
go-version: ['1.21', '1.22', '1.23']

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
cache: true

- name: Download dependencies
run: go mod download

- name: Run tests
run: go test -v -race -coverprofile=coverage.out ./...

- name: Upload coverage
if: matrix.go-version == '1.23'
uses: codecov/codecov-action@v4
with:
files: coverage.out
fail_ci_if_error: false

lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
cache: true

- name: Run golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: latest
args: --timeout=5m

build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
cache: true

- name: Build
run: go build ./...

- name: Verify go.mod is tidy
run: |
go mod tidy
git diff --exit-code go.mod go.sum

benchmark:
name: Benchmark
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
cache: true

- name: Run benchmarks
run: go test -bench=. -benchmem ./... | tee benchmark.txt

- name: Store benchmark result
uses: actions/upload-artifact@v4
with:
name: benchmark-results
path: benchmark.txt
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Binaries
*.test
*.exe
/examples/*/main
/basic

# Coverage
coverage/
*.out

# Benchmarks
benchmarks.txt
benchmark_results.txt

# Vendor
/vendor/

# IDE
/.idea/
/.vscode/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Debug
__debug_bin*
151 changes: 151 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
run:
timeout: 5m
modules-download-mode: readonly

linters:
enable:
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- unused
- bodyclose # Check HTTP response body is closed
- dupl # Code duplication
- gocognit # Cognitive complexity
- goconst # Repeated strings that could be constants
- gocritic # Opinionated linter
- gocyclo # Cyclomatic complexity
- gofmt # Formatting
- goimports # Import formatting
- gosec # Security issues
- misspell # Spelling mistakes
- nakedret # Naked returns in functions
- prealloc # Slice preallocation
- revive # Fast, configurable linter
- unconvert # Unnecessary type conversions
- unparam # Unused function parameters
- whitespace # Whitespace issues

linters-settings:
errcheck:
check-type-assertions: true
check-blank: true
exclude-functions:
- io.Copy
- io.ReadAll
- (io.Closer).Close

gocognit:
min-complexity: 20

gocyclo:
min-complexity: 15

goconst:
min-len: 3
min-occurrences: 3

gocritic:
enabled-tags:
- diagnostic
- performance
- style
disabled-checks:
- hugeParam
- whyNoLint
- commentedOutCod

gofmt:
simplify: true

goimports:
local-prefixes: github.com/oswaldom-code/go-httpclient

gosec:
excludes:
- G104 # Audit errors not checked (we handle this with errcheck)
- G304 # File path provided as taint input (not applicable for HTTP client)

misspell:
locale: US

nakedret:
max-func-lines: 30

prealloc:
simple: true
range-loops: true
for-loops: false

revive:
rules:
- name: blank-imports
- name: context-as-argument
- name: context-keys-type
- name: dot-imports
- name: error-return
- name: error-strings
- name: error-naming
- name: exported
- name: if-return
- name: increment-decrement
- name: var-naming
- name: var-declaration
- name: package-comments
- name: range
- name: receiver-naming
- name: time-naming
- name: unexported-return
- name: indent-error-flow
- name: errorf
- name: empty-block
- name: superfluous-else
- name: unused-parameter
- name: unreachable-code
- name: redefines-builtin-id

unparam:
check-exported: false

issues:
exclude-rules:
- path: _test\.go
linters:
- dupl
- gocognit
- gocyclo
- gosec
- unparam
- errcheck # Test code commonly ignores errors
- bodyclose # Test roundtrippers often return mock responses
- goconst # Test strings don't need to be constants

# Exclude revive unused-parameter in test files
- path: _test\.go
text: "unused-parameter"
linters:
- revive

# Allow complexity in internal roundtripper
- path: internal/
linters:
- gocognit
- gocyclo

# Exclude unused functions that are part of the pool API
- path: pool\.go
text: "func `acquireResponse` is unused"
linters:
- unused

max-issues-per-linter: 50
max-same-issues: 10
new: false

output:
formats:
- format: colored-line-number
print-issued-lines: true
print-linter-name: true
sort-results: true
Loading
Loading