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
41 changes: 34 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,53 @@
name: CI

on:
push:
branches:
- master
pull_request:
branches:
- master
schedule:
# Run daily at 2 AM UTC to check for new vulnerabilities
- cron: "0 2 * * *"

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
timeout-minutes: 15
strategy:
matrix:
go-version: [1.23.x]
go-version: [1.25.x, 1.24.x]
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-go@v3
- uses: actions/checkout@v6
with:
persist-credentials: false

- uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go-version }}
- uses: actions/checkout@v3
cache: true

- name: golangci-lint
uses: golangci/golangci-lint-action@v3
uses: golangci/golangci-lint-action@v9
with:
version: v2.7.2

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

- name: Run govulncheck
uses: golang/govulncheck-action@v1
with:
version: v1.63
- run: go vet ./...
- run: go test ./...
go-version-input: ${{ matrix.go-version }}

- name: Test
run: go test -race ./...
73 changes: 63 additions & 10 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,66 @@
linters-settings:
gocritic:
disabled-checks:
- ifElseChain
- elseif
version: "2"

run:
timeout: 5m
tests: true

formatters:
enable:
- gofumpt

linters:
enable:
- gofmt
- govet
- gocritic
- unconvert
- revive
# Core recommended linters
- errcheck # Checks for unchecked errors
- govet # Go vet checks
- ineffassign # Detects ineffectual assignments
- staticcheck # Advanced static analysis
- unused # Finds unused code

# Code quality
- misspell # Finds commonly misspelled words
- unconvert # Unnecessary type conversions (already enabled in original)
- unparam # Finds unused function parameters
- gocritic # Various checks (already enabled in original)
- revive # Fast, configurable linter (already enabled in original)

# Security and best practices
- gosec # Security-focused linter
- bodyclose # Checks HTTP response body closed
- noctx # Finds HTTP requests without context

settings:
gocritic:
disabled-checks:
- ifElseChain
- elseif

govet:
enable-all: true
disable:
- shadow
- fieldalignment

revive:
enable-all-rules: false

exclusions:
rules:
# Exclude specific revive rules
- linters:
- revive
text: "package-comments"

- linters:
- revive
text: "exported"

# Exclude specific staticcheck rules
- linters:
- staticcheck
text: "ST1005"

# Exclude specific gocritic rules
- linters:
- gocritic
text: "ifElseChain"
15 changes: 12 additions & 3 deletions bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,21 @@ func (b *Bot) HelpMessage() string {
w := new(tabwriter.Writer)
buf := new(bytes.Buffer)
w.Init(buf, 8, 8, 8, ' ', 0)
fmt.Fprintln(w, "Command\tDescription")
if _, err := fmt.Fprintln(w, "Command\tDescription"); err != nil {
log.Printf("Error writing help header: %s", err)
return "Error generating help message"
}
for _, trigger := range b.triggers() {
command := b.commands[trigger]
fmt.Fprintf(w, "%s\t%s\n", trigger, command.Description())
if _, err := fmt.Fprintf(w, "%s\t%s\n", trigger, command.Description()); err != nil {
log.Printf("Error writing help command: %s", err)
return "Error generating help message"
}
}
if err := w.Flush(); err != nil {
log.Printf("Error flushing help writer: %s", err)
return "Error generating help message"
}
_ = w.Flush()
return BlockQuote(buf.String())
}

Expand Down
4 changes: 3 additions & 1 deletion cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ func Parse(app *kingpin.Application, args []string, stringBuffer *bytes.Buffer)

if err != nil && stringBuffer.Len() == 0 {
log.Printf("Error in parsing command: %s. got %s", args, err)
_, _ = io.WriteString(stringBuffer, fmt.Sprintf("I don't know what you mean by `%s`.\nError: `%s`\nHere's my usage:\n\n", strings.Join(args, " "), err.Error()))
if _, writeErr := io.WriteString(stringBuffer, fmt.Sprintf("I don't know what you mean by `%s`.\nError: `%s`\nHere's my usage:\n\n", strings.Join(args, " "), err.Error())); writeErr != nil {
log.Printf("Error writing error message: %s", writeErr)
}
// Print out help page if there was an error parsing command
app.Usage([]string{})
}
Expand Down
1 change: 1 addition & 0 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func (c execCommand) Run(_ string, _ []string) (string, error) {
return fmt.Sprintf("I'm in dry run mode. I would have run `%s` with args: %s", c.exec, c.args), nil
}

//nolint:gosec,noctx // Command execution is the purpose of this bot, no context available
out, err := exec.Command(c.exec, c.args...).CombinedOutput()
outAsString := string(out)
return outAsString, err
Expand Down
7 changes: 2 additions & 5 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ func (c *config) SetDryRun(dryRun bool) {

func getConfigPath() (string, error) {
currentUser, err := user.Current()

if err != nil {
return "", err
}
Expand Down Expand Up @@ -83,13 +82,11 @@ func readConfigOrDefault() config {
}

path, err := getConfigPath()

if err != nil {
return defaultConfig
}

fileBytes, err := os.ReadFile(path)

fileBytes, err := os.ReadFile(filepath.Clean(path))
if err != nil {
return defaultConfig
}
Expand All @@ -115,7 +112,7 @@ func (c config) Save() error {
return err
}

err = os.WriteFile(path, b, 0644)
err = os.WriteFile(filepath.Clean(path), b, 0o644) //nolint:gosec // Config file should be user-readable
if err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module github.com/keybase/slackbot

go 1.21
go 1.24.0

toolchain go1.23.4
toolchain go1.25.5

require (
github.com/keybase/go-keybase-chat-bot v0.0.0-20250106203511-859265729a56
github.com/keybase/go-keybase-chat-bot v0.0.0-20251212163122-450fd0812017
github.com/nlopes/slack v0.1.1-0.20180101221843-107290b5bbaf
gopkg.in/alecthomas/kingpin.v2 v2.2.6
)
Expand All @@ -17,7 +17,7 @@ require (
github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.10.0 // indirect
github.com/stretchr/testify v1.11.1 // indirect
golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/keybase/go-keybase-chat-bot v0.0.0-20250106203511-859265729a56 h1:w8ikAizh5hbXZxBXbees5iOxOoi7nH/qp1lJQ3pOPiY=
github.com/keybase/go-keybase-chat-bot v0.0.0-20250106203511-859265729a56/go.mod h1:cmXzSxB8TNJdxMKcmywTHsbv+H3WZ/92lP9nyEbCGNQ=
github.com/keybase/go-keybase-chat-bot v0.0.0-20251212163122-450fd0812017 h1:lB6jgDag58Ie9yfLSGDQiUZt60zPyRpK6aWCtovQeSo=
github.com/keybase/go-keybase-chat-bot v0.0.0-20251212163122-450fd0812017/go.mod h1:wl5lBoVNkepL8Hzs7jyqg3GS6U+by4yQeNr7oT0Evt0=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
Expand All @@ -20,8 +20,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4 h1:DZshvxDdVoeKIbudAdFEKi+f70l51luSy/7b76ibTY0=
golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
Expand Down
1 change: 0 additions & 1 deletion hybrid.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ func newHybridRunner(runner BotCommandRunner, channel string) *hybridRunner {

func (r *hybridRunner) RunCommand(args []string, _ string) error {
return r.runner.RunCommand(args, r.channel)

}

type HybridBackendMember struct {
Expand Down
Loading
Loading