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
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,29 @@ jobs:
timeout-minutes: 15
strategy:
matrix:
go-version: [1.25.x]
go-version: [1.26.x, 1.27.x]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7.0.1
with:
persist-credentials: false

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

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

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

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

Expand Down
2 changes: 1 addition & 1 deletion base/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func FormatPushMsg(username string, repo string, branch string, numCommits int,
}

func formatCommitString(commit string, maxLen int) string {
firstLine := strings.Split(commit, "\n")[0]
firstLine, _, _ := strings.Cut(commit, "\n")
if len(firstLine) > maxLen {
firstLine = strings.TrimSpace(firstLine[:maxLen]) + "..."
}
Expand Down
3 changes: 1 addition & 2 deletions base/oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ func (o *OAuthHTTPSrv) getCallbackMsg(req OAuthRequest) (res chat1.MsgSummary, e
// LogOAuthError logs an OAuth error, scrubbing any raw token-endpoint response
// body. ErrorCode and ErrorDescription from structured OAuth errors are retained.
func LogOAuthError(debug *DebugOutput, context string, err error) {
var retrieveErr *oauth2.RetrieveError
if errors.As(err, &retrieveErr) {
if retrieveErr, ok := errors.AsType[*oauth2.RetrieveError](err); ok {
statusCode := 0
if retrieveErr.Response != nil {
statusCode = retrieveErr.Response.StatusCode
Expand Down
2 changes: 1 addition & 1 deletion elastiwatch/elastiwatch/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (h *Handler) handleDeferrals(ctx context.Context, convID chat1.ConvIDStr, _
return nil
}
for _, d := range deferrals {
body.WriteString(fmt.Sprintf("id: %d author: %s regex: %s (created: %v)\n", d.ID, d.Author, d.Regex, d.Ctime))
fmt.Fprintf(&body, "id: %d author: %s regex: %s (created: %v)\n", d.ID, d.Author, d.Regex, d.Ctime)
}
h.ChatEcho(convID, "%s", body.String())
return nil
Expand Down
6 changes: 3 additions & 3 deletions elastiwatch/elastiwatch/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ func (l *LogWatch) alertFromChunk(c chunk) {

func (l *LogWatch) alertEmail(subject string, chunks []chunk) {
var body strings.Builder
body.WriteString(fmt.Sprintf("Email sent: %s", subject))
fmt.Fprintf(&body, "Email sent: %s", subject)
for _, c := range chunks {
if c.Severity == "INFO" {
continue
}
body.WriteString(fmt.Sprintf("\n%s %d %s", c.Severity, c.Count, c.Message))
fmt.Fprintf(&body, "\n%s %d %s", c.Severity, c.Count, c.Message)
}
l.ChatEcho(l.emailConvID, "```%s```", body.String())
}
Expand Down Expand Up @@ -172,7 +172,7 @@ func (l *LogWatch) runOnce() {
Params: opensearchapi.SearchParams{
Query: `NOT severity:debug AND @timestamp:[now-1m TO now]`,
Sort: []string{"@timestamp:desc"},
Size: opensearchapi.ToPointer(10000),
Size: new(10000),
Pretty: true,
},
})
Expand Down
8 changes: 4 additions & 4 deletions gcalbot/gcalbot/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ func FormatEvent(
uri := strings.TrimPrefix(entryPoint.Uri, "https://")
switch entryPoint.EntryPointType {
case "video", "more":
conferenceData.WriteString(fmt.Sprintf("\n> Join online: %s", uri))
fmt.Fprintf(&conferenceData, "\n> Join online: %s", uri)
case "phone":
conferenceData.WriteString(fmt.Sprintf("\n> Join by phone: %s", entryPoint.Label))
fmt.Fprintf(&conferenceData, "\n> Join by phone: %s", entryPoint.Label)
if entryPoint.Pin != "" {
conferenceData.WriteString(fmt.Sprintf(" PIN: %s", entryPoint.Pin))
fmt.Fprintf(&conferenceData, " PIN: %s", entryPoint.Pin)
}
case "sip":
conferenceData.WriteString(fmt.Sprintf("\n> Join by SIP: %s", entryPoint.Label))
fmt.Fprintf(&conferenceData, "\n> Join by SIP: %s", entryPoint.Label)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion gcalbot/gcalbot/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ func (h *Handler) createEventChannel(ctx context.Context, account *Account, cale

// pre-fill db with invites so we don't send old invites
// there could be a race since this process can take up to a few seconds
// context.Background() because syncAllInvites is a background goroutine that outlives the request
//nolint:gosec // G118: Background context intentional - syncAllInvites is a background goroutine that outlives the request
go h.syncAllInvites(account, srv, channelID, calendarID)

return nil
Expand Down
2 changes: 1 addition & 1 deletion gitlabbot/gitlabbot/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func (h *Handler) handleListSubscriptions(ctx context.Context, msg chat1.MsgSumm

var res strings.Builder
for _, repo := range subscriptions {
res.WriteString(fmt.Sprintf("- *%s*\n", repo))
fmt.Fprintf(&res, "- *%s*\n", repo)
}
h.ChatEcho(msg.ConvID, "%s", res.String())
return nil
Expand Down
2 changes: 1 addition & 1 deletion gitlabbot/gitlabbot/signing.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func verifyWebhookSignature(
_, _ = mac.Write(payload)
expected := []byte("v1," + base64.StdEncoding.EncodeToString(mac.Sum(nil)))

for _, signature := range strings.Fields(signatures) {
for signature := range strings.FieldsSeq(signatures) {
if hmac.Equal([]byte(signature), expected) {
return nil
}
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module github.com/keybase/managed-bots

go 1.25.0
go 1.26.0

toolchain go1.25.5
toolchain go1.27.1

require (
github.com/aws/aws-sdk-go-v2 v1.42.1
Expand Down
8 changes: 4 additions & 4 deletions pollbot/pollbot/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ func (h *Handler) generateAnonymousPoll(ctx context.Context, convID chat1.ConvID
promptMsgID := *sendRes.Result.MessageID
var body strings.Builder
for index, option := range options {
body.WriteString(fmt.Sprintf("\n%s *%s*\n%s\n", base.NumberToEmoji(index+1), option,
h.generateVoteLink(id, index+1)))
fmt.Fprintf(&body, "\n%s *%s*\n%s\n", base.NumberToEmoji(index+1), option,
h.generateVoteLink(id, index+1))
}
h.ChatEcho(convID, "%s", body.String())
if sendRes, err = h.kbc.SendMessageByConvID(convID, "*Results*\n_No votes yet_"); err != nil {
Expand All @@ -80,9 +80,9 @@ func (h *Handler) generateAnonymousPoll(ctx context.Context, convID chat1.ConvID

func (h *Handler) generatePoll(convID chat1.ConvIDStr, prompt string, options []string) error {
var body strings.Builder
body.WriteString(fmt.Sprintf("Poll: *%s*\n\n", prompt))
fmt.Fprintf(&body, "Poll: *%s*\n\n", prompt)
for index, option := range options {
body.WriteString(fmt.Sprintf("%s %s\n", base.NumberToEmoji(index+1), option))
fmt.Fprintf(&body, "%s %s\n", base.NumberToEmoji(index+1), option)
}
body.WriteString("Tap a reaction below to register your vote!")
sendRes, err := h.kbc.SendMessageByConvID(convID, "%s", body.String())
Expand Down
1 change: 1 addition & 0 deletions triviabot/triviabot/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type question struct {

func newQuestion(aq apiQuestion) question {
a := append([]string{aq.CorrectAnswer}, aq.IncorrectAnswers...)
//nolint:gosec // G404: Using math/rand for trivia game answer shuffling, not cryptography
rand.Shuffle(len(a), func(i, j int) { a[i], a[j] = a[j], a[i] })
correctAnswer := 0
for index, answer := range a {
Expand Down
2 changes: 1 addition & 1 deletion webhookbot/webhookbot/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (h *Handler) handleList(ctx context.Context, _ string, msg chat1.MsgSummary
}
var body strings.Builder
for _, hook := range hooks {
body.WriteString(fmt.Sprintf("%s, %s\n", hook.Name, h.formURL(hook.ID)))
fmt.Fprintf(&body, "%s, %s\n", hook.Name, h.formURL(hook.ID))
}
if _, err := h.kbc.SendMessageByTlfName(msg.Sender.Username, "%s", body.String()); err != nil {
h.Debug("handleList: failed to send hook: %s", err)
Expand Down
1 change: 1 addition & 0 deletions zoombot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ func (s *BotServer) Go() (err error) {
config := &oauth2.Config{
ClientID: credentials.ClientID,
ClientSecret: credentials.ClientSecret,
//nolint:gosec // G101: False positive - these are public OAuth endpoint URLs, not credentials
Endpoint: oauth2.Endpoint{
AuthURL: "https://zoom.us/oauth/authorize",
TokenURL: "https://zoom.us/oauth/token",
Expand Down
1 change: 1 addition & 0 deletions zoombot/zoombot/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ func GetUser(client *http.Client, userID string) (*GetUserResponse, error) {

func CreateMeeting(client *http.Client, userID string, request *CreateMeetingRequest) (*CreateMeetingResponse, error) {
apiURL := fmt.Sprintf("%s/users/%s/meetings", apiBaseURLV2, userID)
//nolint:gosec // G117: False positive - Password field is a legitimate Zoom API meeting password field, not hardcoded credentials
payload, err := json.Marshal(request)
if err != nil {
return nil, err
Expand Down