Skip to content

Commit 96a7e17

Browse files
authored
Merge pull request #32 from robmorgan/add-workflows
2 parents 064f9f3 + 654ed66 commit 96a7e17

File tree

39 files changed

+442
-381
lines changed

39 files changed

+442
-381
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: golangci-lint
2+
on:
3+
push:
4+
tags:
5+
- v*
6+
branches:
7+
- master
8+
- main
9+
pull_request:
10+
paths-ignore:
11+
- "*.md"
12+
permissions:
13+
contents: read
14+
pull-requests: read
15+
jobs:
16+
golangci:
17+
name: Run golangci-lint
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v4
21+
- uses: actions/setup-go@v5
22+
with:
23+
go-version-file: go.mod
24+
- uses: golangci/golangci-lint-action@v8
25+
with:
26+
version: v2.2.2
27+
args: --verbose

.github/workflows/labeler.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: "Issue Labeler"
2+
on:
3+
issues:
4+
types: [opened]
5+
6+
jobs:
7+
triage:
8+
name: "Triage issues"
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: github/[email protected]
12+
with:
13+
repo-token: "${{ secrets.GITHUB_TOKEN }}"
14+
configuration-path: .github/labeler.yml
15+
enable-versioned-regex: 0

.github/workflows/stale.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: "Close stale issues and PRs"
2+
on:
3+
schedule:
4+
# Runs at 15:00 UTC every day.
5+
# Actions schedules run at most every 5 minutes.
6+
- cron: "0 15 * * *"
7+
permissions:
8+
issues: write
9+
pull-requests: write
10+
jobs:
11+
stale:
12+
name: Manage stale issues and PRs
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/stale@v7
16+
with:
17+
stale-issue-message: "This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 365 days."
18+
stale-pr-message: "This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 365 days."
19+
close-issue-message: "This issue was closed because it has been stalled for 365 days with no activity."
20+
close-pr-message: "This PR was closed because it has been stalled for 365 days with no activity."
21+
days-before-issue-stale: 30
22+
days-before-pr-stale: 30
23+
days-before-issue-close: 365
24+
days-before-pr-close: 365
25+
stale-issue-label: stale
26+
stale-pr-label: stale
27+
exempt-issue-labels: accepted

.github/workflows/test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ jobs:
2424
with:
2525
terraform_version: "1.0.11"
2626

27+
- uses: actions/checkout@v4
28+
2729
- name: Set up Go
2830
uses: actions/setup-go@v5
2931
with:
30-
go-version: "1.24"
31-
32-
- uses: actions/checkout@v4
32+
go-version-file: go.mod
3333

3434
- name: Run Tests
3535
run: |

.golangci.yml

Lines changed: 136 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,151 @@
1+
version: "2"
12
run:
2-
skip-dirs-use-default: true
3-
skip-dirs:
4-
- vendor
5-
- ent
6-
- graph
7-
skip-files:
8-
- ".*\\.peg\\.go$"
9-
- ".*ignored_.*.go$"
10-
- "generated.go$"
11-
- model_gen.go
12-
3+
modules-download-mode: readonly
4+
issues-exit-code: 1
5+
tests: true
136
linters:
14-
disable-all: true
157
enable:
8+
- asasalint
9+
- asciicheck
10+
- bidichk
1611
- bodyclose
17-
- depguard
18-
- dogsled
12+
- containedctx
13+
- contextcheck
14+
- cyclop
15+
- dupl
16+
- durationcheck
17+
- errorlint
18+
- exhaustive
1919
- funlen
20+
- gocognit
2021
- goconst
2122
- gocritic
2223
- gocyclo
23-
- gofmt
24-
- goimports
25-
- revive
26-
- gomnd
24+
#- godot
25+
- goheader
26+
- gomoddirectives
27+
- gomodguard
28+
- goprintffuncname
2729
- gosec
30+
- makezero
2831
- misspell
32+
- mnd
33+
- nakedret
34+
- nestif
35+
- nilerr
36+
- nilnil
37+
- noctx
38+
- nolintlint
39+
- prealloc
40+
- predeclared
41+
- promlinter
42+
- reassign
43+
- rowserrcheck
44+
- sqlclosecheck
45+
- staticcheck
46+
- testableexamples
47+
- thelper
2948
- unconvert
30-
- typecheck
49+
- unparam
50+
- usestdlibvars
51+
- wastedassign
52+
- whitespace
53+
settings:
54+
cyclop:
55+
max-complexity: 11
56+
dupl:
57+
threshold: 100
58+
errcheck:
59+
check-type-assertions: true
60+
check-blank: false
61+
errorlint:
62+
errorf: true
63+
asserts: true
64+
comparison: true
65+
exhaustive:
66+
default-signifies-exhaustive: false
67+
funlen:
68+
lines: 100
69+
statements: 50
70+
gocognit:
71+
min-complexity: 15
72+
goconst:
73+
min-len: 3
74+
min-occurrences: 3
75+
gocritic:
76+
disabled-checks:
77+
- dupImport
78+
- ifElseChain
79+
- octalLiteral
80+
- whyNoLint
81+
- wrapperFunc
82+
enabled-tags:
83+
- diagnostic
84+
- experimental
85+
- opinionated
86+
- performance
87+
- style
88+
gocyclo:
89+
min-complexity: 15
90+
godot:
91+
scope: declarations
92+
exclude:
93+
- "^fixme:"
94+
- "^todo:"
95+
capital: false
96+
misspell:
97+
locale: US
98+
nestif:
99+
min-complexity: 4
100+
prealloc:
101+
simple: true
102+
range-loops: true
103+
for-loops: false
104+
staticcheck:
105+
checks:
106+
- all
107+
- -ST1000
108+
- -ST1003
109+
- -ST1016
110+
- -ST1020
111+
- -ST1021
112+
- -ST1022
113+
dot-import-whitelist:
114+
- fmt
115+
unparam:
116+
check-exported: false
117+
whitespace:
118+
multi-if: false
119+
multi-func: false
120+
exclusions:
121+
generated: lax
31122

32-
# default
33-
- errcheck
34-
#- govet
35-
- ineffassign
36-
#- staticcheck
37-
- unused
123+
presets:
124+
- comments
125+
- common-false-positives
126+
- legacy
127+
- std-error-handling
38128

39-
linters-settings:
40-
dupl:
41-
threshold: 100
42-
funlen:
43-
lines: 100
44-
statements: 60
45-
depguard:
46-
list-type: blacklist
47-
packages:
48-
- golang.org/x/net/context
49-
- github.com/prometheus/common/log
50-
# gocyclo:
51-
# min-complexity: 15
129+
rules: []
52130

131+
warn-unused: true
53132
issues:
54-
# Excluding configuration per-path, per-linter, per-text and per-source
55-
exclude-rules:
56-
- path: _test\.go
57-
linters:
58-
- gomnd
59-
# https://github.com/go-critic/go-critic/issues/926
60-
- linters:
61-
- gocritic
62-
text: "unnecessaryDefer:"
133+
max-issues-per-linter: 0
134+
max-same-issues: 0
135+
new: false
136+
fix: false
137+
formatters:
138+
enable:
139+
- gci
140+
- gofmt
141+
- gofumpt
142+
- goimports
143+
settings:
144+
gci:
145+
sections:
146+
- standard
147+
- default
148+
- prefix(github.com/robmorgan/infraspec)
149+
goimports:
150+
local-prefixes:
151+
- github.com/robmorgan/infraspec

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ deps: ## install dependencies
77
go install mvdan.cc/gofumpt@latest
88
go install github.com/daixiang0/gci@latest
99
go install golang.org/x/tools/cmd/goimports@latest
10-
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.2.1
10+
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.2.2
1111

1212
.PHONY: tidy
1313
tidy: ## go mod tidy

cmd/init.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func runInit(cmd *cobra.Command, args []string) error {
2929
}
3030

3131
// Create the features directory
32-
if err := os.MkdirAll(featuresDir, 0o755); err != nil {
32+
if err := os.MkdirAll(featuresDir, 0o755); err != nil { //nolint:mnd
3333
return fmt.Errorf("failed to create features directory: %w", err)
3434
}
3535

cmd/new.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func runNew(cmd *cobra.Command, args []string) error {
4747
}
4848

4949
// Create features directory if it doesn't exist
50-
if err := os.MkdirAll("features", 0o755); err != nil {
50+
if err := os.MkdirAll("features", 0o755); err != nil { //nolint:mnd
5151
return fmt.Errorf("failed to create features directory: %w", err)
5252
}
5353

@@ -63,7 +63,7 @@ func runNew(cmd *cobra.Command, args []string) error {
6363
Then the service should be healthy
6464
`
6565

66-
if err := os.WriteFile(filePath, []byte(template), 0o644); err != nil {
66+
if err := os.WriteFile(filePath, []byte(template), 0o600); err != nil { //nolint:mnd
6767
return fmt.Errorf("failed to create feature file: %w", err)
6868
}
6969

@@ -86,7 +86,7 @@ func getFeatureName(filePath string) string {
8686
// Simple title case conversion
8787
words := strings.Fields(name)
8888
for i, word := range words {
89-
if len(word) > 0 {
89+
if word != "" {
9090
words[i] = strings.ToUpper(word[:1]) + strings.ToLower(word[1:])
9191
}
9292
}

internal/collections/collections.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package collections
22

33
import (
4-
"math/rand"
4+
"crypto/rand"
5+
"math/big"
56
"slices"
67
)
78

@@ -53,13 +54,22 @@ func Subtract[T comparable](a, b []T) []T {
5354
return result
5455
}
5556

57+
// cryptoRandInt generates a cryptographically secure random integer in range [0, limit)
58+
func cryptoRandInt(limit int) int {
59+
n, err := rand.Int(rand.Reader, big.NewInt(int64(limit)))
60+
if err != nil {
61+
panic(err) // TODO - we may wish to handle this more gracefully
62+
}
63+
return int(n.Int64())
64+
}
65+
5666
// RandomElement returns a random element from the slice, and a boolean indicating whether the slice was empty.
5767
func RandomElement[T any](slice []T) (T, bool) {
5868
if len(slice) == 0 {
5969
var zero T
6070
return zero, false
6171
}
6272

63-
index := rand.Intn(len(slice))
73+
index := cryptoRandInt(len(slice))
6474
return slice[index], true
6575
}

internal/collections/collections_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ func TestSubtractWithStrings(t *testing.T) {
207207
}
208208
}
209209

210-
func TestRandomElement(t *testing.T) {
210+
func TestRandomElement(t *testing.T) { //nolint:gocognit
211211
tests := []struct {
212212
name string
213213
slice []interface{}
@@ -244,7 +244,7 @@ func TestRandomElement(t *testing.T) {
244244

245245
for _, tt := range tests {
246246
t.Run(tt.name, func(t *testing.T) {
247-
if tt.iterations == 1 {
247+
if tt.iterations == 1 { //nolint:nestif
248248
value, ok := RandomElement(tt.slice)
249249
if ok != tt.wantOk {
250250
t.Errorf("RandomElement() ok = %v, want %v", ok, tt.wantOk)
@@ -273,7 +273,7 @@ func TestRandomElement(t *testing.T) {
273273
}
274274
}
275275

276-
func TestRandomElementTyped(t *testing.T) {
276+
func TestRandomElementTyped(t *testing.T) { //nolint:gocognit
277277
tests := []struct {
278278
name string
279279
slice interface{}

0 commit comments

Comments
 (0)