Modernize: Go 1.26, dependency bumps, CI/CD - #65
Merged
Merged
Conversation
dggchat moves from the 2020 snapshot to 2023-12-06 and gorilla/websocket from 1.4.2 to 1.5.3. No API changes needed on our side. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Brings the source up to current Go and fixes several bugs found while reading it. Fixes: - !drop always reported failure. banATuser unmarshalled the response into the *http.Response rather than its error struct, so the call always errored. The ban itself went through; only the reply broke. - Six response bodies were never closed, leaking a connection on every !check, !stream, !imdb, !modify and !rename. - getATUserData returned a nil error on an empty result, so !check carried on with zero-valued data. It now returns errNotFound, matched with errors.Is instead of substring-matching "404". - "!roll 2d2 + 100" silently dropped the modifier, since Atoi cannot parse "+ 100". Whitespace is stripped before parsing. - Static commands were matched by ranging over a map, so "!foo" and "!foobar" resolved arbitrarily. Longest prefix now wins. - renameUser built its JSON body with Sprintf. Usernames are now marshalled and path-escaped. Modernization: - Drop io/ioutil; math/rand -> math/rand/v2; range-over-int, min/max, slices.Backward/Concat, strings.CutPrefix. - One shared http.Client with NewRequestWithContext, replacing a client built per call. A shutdown context is plumbed from main through the parser signature so in-flight API calls are cancelled on SIGTERM. - Split main into main/run so log.Fatal no longer skips deferred cleanup. signal.NotifyContext handles INT/TERM, SIGHUP still rotates the log, and SIGTERM now exits 0 rather than 1. - Move the static command map behind an RWMutex in store.go, with temp-file-and-rename writes, replacing two package globals and an unlocked read on every chat message. - Stream modifiers are *bool with omitempty rather than strings string-replaced back into booleans. Same wire format, now tested. - Add a -version flag reporting the commit via debug.ReadBuildInfo. Tests are table-driven and cover the store, the modifier payload, and the roll fixes. Adds .golangci.yaml. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CI now runs vet, tests under -race with coverage, golangci-lint (pinned to v2.12.2), gofmt and `go mod tidy -diff` checks, and a Dockerfile build so a broken image fails on the PR rather than on deploy. The Go version comes from go.mod instead of being hardcoded in two places. Adds `permissions: contents: read` and concurrency cancellation. CD switches to buildx with GHA layer caching and pushes a sha- tag alongside latest, so a bad deploy can be rolled back to a known image. Scopes the token to `packages: write`, groups deploys so two cannot race, and moves the ssh-action pin off a commit from February 2020 to v1.2.5. Dockerfile pins its base image, uses BuildKit cache mounts, and cross-compiles via TARGETOS/TARGETARCH rather than emulating under qemu. With -trimpath and -ldflags="-s -w" the image is ~7MB, and the commit is stamped into the binary. Adds a .dockerignore. Dependabot moves to weekly, grouped updates and now covers github-actions and docker, not just gomod. Adds a justfile (`just check` mirrors CI) and a README section covering the flags and dev workflow. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings modbot up to current Go and current GitHub Actions, and fixes a handful of bugs found while reading the code. Three commits, each independently buildable.
Rebased onto master after #64 and the PM-reply/delcommand work landed — see "Rebase notes" at the bottom for how the overlapping changes were merged.
Behavior changes worth knowing about
!dropwas always reporting failure.banATuserunmarshalled the response into the*http.Responseinstead of its error struct, so the call always errored. The ban itself went through — only the reply was broken. Mods will now get a success reply where they previously saw an error. Worth a heads-up so it doesn't read as a regression.Also:
!checkno longer proceeds on zero-valued data when angelthump returns an empty result!roll 2d2 + 100now applies the modifier —Atoican't parse"+ 100", so a spaced modifier was silently dropped!foovs!foobarresolved arbitrarily depending on map iteration orderFixes
!check,!stream,!imdb,!modifyand!renamerenameUserbuilt its JSON body withSprintf; usernames are now marshalled and path-escapedModernization
io/ioutil,math/rand→math/rand/v2, range-over-int,min/max,slices.Backward/Concat,strings.CutPrefixhttp.ClientwithNewRequestWithContext, replacing a client built per call. A shutdown context is plumbed frommainthrough the parser signature, so in-flight API calls are cancelled on SIGTERM rather than holding up shutdown.mainsplit intomain/runsolog.Fatalno longer skips deferred cleanup;signal.NotifyContextfor INT/TERM, SIGHUP still rotates the logRWMutexinstore.gowith temp-file-and-rename writes*boolwithomitemptyinstead of strings string-replaced back into booleans. Same wire format, now covered by a test.-versionflag reporting the commit viadebug.ReadBuildInfoDeps
dggchat 2020 snapshot → 2023-12-06, gorilla/websocket 1.4.2 → 1.5.3. No API changes needed. Prometheus from #64 is untouched.
CI/CD
-race+ coverage, golangci-lint (pinned v2.12.2),gofmtandgo mod tidy -diffchecks, and a Dockerfile build so a broken image fails here rather than on deploy. Go version now comes fromgo.modinstead of being hardcoded in two places. Addspermissions: contents: readand concurrency cancellation.sha-tag alongsidelatest, so a bad deploy can be rolled back to a known image.lateststill points where the deploy hook expects. Token scoped topackages: write, deploys grouped so two can't race, and the ssh-action pin moved off a commit from February 2020 to v1.2.5.TARGETOS/TARGETARCHinstead of emulating under qemu. With-trimpath -ldflags="-s -w"the image is ~7MB.EXPOSE 9090and theHEALTHCHECKfrom Expose metrics and a health check #64 are preserved.Adds a
justfile(just checkmirrors CI) and a README section for flags and dev workflow.Rebase notes
Master and this branch both changed the parser signature. They were merged rather than either side winning:
func(ctx context.Context, m message, s *dggchat.Session)— master'smessage/isPMreply routing plus this branch's context.sendMessageDedupe/sendPublicDedupeand the!m.isPMguard inrenameare kept as-is.!delcommandandnormalizeCommandNameare kept as master wrote them, re-pointed at the new store instead of thecommandsmap +mutex.b439eac(absolute path, entry count) moved intostore.go, andcommandPersistFailures.Inc()now fires from a single place covering both add and delete.checkHealthand the metrics test now useNewRequestWithContext(noctx), and the test's poll loop closes its response body (bodyclose).!addcommandstill documented the_deletion sentinel thatb439eacreplaced, and the footer still said PM replies come back in public chat. Both corrected, and!delcommanddocumented.Verification
go build,go vet,golangci-lint run,go test -race, andgo mod tidy -diffall clean on the rebased tree. Container image builds and-versionreports the commit. I also ran the pinned golangci-lint release binary against the repo to confirm the CI lint job won't trip over Go 1.26.Deliberately not done
log→log/slog:chatlog.logis the production chat log andmodbot-rotatekeys off it. Changing that output format is a separate decision.hooks/modbot.shlives outside this repo and I couldn't check what owns the mounted chatlog dir. A wrong guess breaks the deploy silently.🤖 Generated with Claude Code