FMG-2: upgrade Go to 1.27.1, refresh dependencies and drop gotoolkit #7

Closed
fmartingr wants to merge 2 commits from agent/full-stack-developer/92dd9c7e35da into main
Owner

Closes FMG-2

Upgrades Go and every dependency to their latest revisions, and removes the gotoolkit dependency in favour of the standard library and the libraries it was wrapping.

gotoolkit removal

It was used for three things:

  • encoding.NewTOMLEncoding() — a thin wrapper over pelletier/go-toml/v2. Now used directly, behind a new smtp2shoutrrr.LoadConfig(path) shared by both commands. Previously both cmd/smtp2shoutrrr and cmd/sendmail duplicated the open/decode/SetDefaults sequence, and neither closed the config file.
  • model.Server — a three-method interface with a single implementation. NewSMTPServer now returns a concrete *Server, and the unused IsEnabled() is gone.
  • service.NewService(...).Start()/WaitStop() — replaced by signal.NotifyContext in main. Server.Start(ctx) now owns its own lifecycle: it serves until the context is cancelled, then calls Shutdown with a 10s deadline. Behaviour matches the old service, without the indirection.

Version bumps

from to
Go 1.25.6 1.27.1
emersion/go-smtp 0.24.0 0.25.0
stretchr/testify 1.9.0 1.12.1
pelletier/go-toml/v2 2.2.3 (indirect) 2.4.3 (direct)
x/crypto/x509roots/fallback 2025-02-14 2026-09-02
alpine (Containerfile) 3.20 3.24
golangci-lint v2.8.0 v2.13.2
actions/checkout, actions/setup-go v6 v7

Indirects also refreshed (x/net 0.25.0 → 0.58.0, x/sys, x/tools, fatih/color, go-cmp, logr). containrrr/shoutrrr and emersion/go-sasl were already at their latest published revisions.

Dropping goreleaser-action

Bumping actions/goreleaser-action v6.4.0 → v7.2.3 broke the goreleaser-lint job: v7.1.0 made cosign signature verification of the action's own goreleaser download mandatory, and ci-base ships no cosign.

Rather than pin the action back, this drops it. ci-base already installs goreleaser from the upstream apt repo — that is what make build has always used — so the action was downloading a second copy of a tool the image already had. Both workflows now invoke it directly, and goreleaser check moves behind a make check target, so every CI job runs a make target like the rest of the pipeline.

Tests

Coverage 63.1% → 75.9%. New tests cover LoadConfig (parsing, defaults, missing file, invalid TOML) and the replacement lifecycle — that a cancelled context shuts the server down and releases the listener, and that a bind failure propagates out of Start.

All jobs were also run locally against Go 1.27.1: make format (clean diff), make check, make ci-lint (0 issues), make test, make build (6 targets). The release binary was smoke-tested end to end: mail accepted, forwarded to a shoutrrr generic target, and SIGTERM shut it down cleanly with exit 0.

Note: release.yml only runs on tags, so its goreleaser step is not exercised by this PR. The env vars it depends on (GITEA_TOKEN, GORELEASER_FORCE_TOKEN) are read by goreleaser itself rather than by the action, so invoking the binary directly is equivalent.

Also

Removed the unused ANONYMOUS SASL client from cmd/sendmail — its only caller was a commented-out line, and it was the last thing pulling go-sasl into that command.

Closes FMG-2 Upgrades Go and every dependency to their latest revisions, and removes the `gotoolkit` dependency in favour of the standard library and the libraries it was wrapping. ## gotoolkit removal It was used for three things: - **`encoding.NewTOMLEncoding()`** — a thin wrapper over `pelletier/go-toml/v2`. Now used directly, behind a new `smtp2shoutrrr.LoadConfig(path)` shared by both commands. Previously both `cmd/smtp2shoutrrr` and `cmd/sendmail` duplicated the open/decode/`SetDefaults` sequence, and neither closed the config file. - **`model.Server`** — a three-method interface with a single implementation. `NewSMTPServer` now returns a concrete `*Server`, and the unused `IsEnabled()` is gone. - **`service.NewService(...).Start()/WaitStop()`** — replaced by `signal.NotifyContext` in `main`. `Server.Start(ctx)` now owns its own lifecycle: it serves until the context is cancelled, then calls `Shutdown` with a 10s deadline. Behaviour matches the old service, without the indirection. ## Version bumps | | from | to | |---|---|---| | Go | 1.25.6 | 1.27.1 | | `emersion/go-smtp` | 0.24.0 | 0.25.0 | | `stretchr/testify` | 1.9.0 | 1.12.1 | | `pelletier/go-toml/v2` | 2.2.3 (indirect) | 2.4.3 (direct) | | `x/crypto/x509roots/fallback` | 2025-02-14 | 2026-09-02 | | alpine (Containerfile) | 3.20 | 3.24 | | golangci-lint | v2.8.0 | v2.13.2 | | `actions/checkout`, `actions/setup-go` | v6 | v7 | Indirects also refreshed (`x/net` 0.25.0 → 0.58.0, `x/sys`, `x/tools`, `fatih/color`, `go-cmp`, `logr`). `containrrr/shoutrrr` and `emersion/go-sasl` were already at their latest published revisions. ## Dropping `goreleaser-action` Bumping `actions/goreleaser-action` v6.4.0 → v7.2.3 broke the `goreleaser-lint` job: v7.1.0 made cosign signature verification of the action's own goreleaser download mandatory, and `ci-base` ships no cosign. Rather than pin the action back, this drops it. `ci-base` already installs goreleaser from the upstream apt repo — that is what `make build` has always used — so the action was downloading a second copy of a tool the image already had. Both workflows now invoke it directly, and `goreleaser check` moves behind a `make check` target, so every CI job runs a make target like the rest of the pipeline. ## Tests Coverage 63.1% → 75.9%. New tests cover `LoadConfig` (parsing, defaults, missing file, invalid TOML) and the replacement lifecycle — that a cancelled context shuts the server down and releases the listener, and that a bind failure propagates out of `Start`. All jobs were also run locally against Go 1.27.1: `make format` (clean diff), `make check`, `make ci-lint` (0 issues), `make test`, `make build` (6 targets). The release binary was smoke-tested end to end: mail accepted, forwarded to a shoutrrr generic target, and `SIGTERM` shut it down cleanly with exit 0. Note: `release.yml` only runs on tags, so its goreleaser step is not exercised by this PR. The env vars it depends on (`GITEA_TOKEN`, `GORELEASER_FORCE_TOKEN`) are read by goreleaser itself rather than by the action, so invoking the binary directly is equivalent. ## Also Removed the unused `ANONYMOUS` SASL client from `cmd/sendmail` — its only caller was a commented-out line, and it was the last thing pulling `go-sasl` into that command.
deps: upgrade Go to 1.27.1, refresh dependencies and drop gotoolkit
Some checks failed
CI / goreleaser-lint (pull_request) Failing after 37s
CI / format (pull_request) Successful in 1m20s
CI / test (pull_request) Successful in 2m36s
CI / lint (pull_request) Successful in 3m34s
CI / build (pull_request) Has been cancelled
8c12783e95
Replaces the gotoolkit helpers with the standard library and the
libraries they wrapped:

- gotoolkit/encoding TOML wrapper -> pelletier/go-toml/v2 directly,
  behind a new smtp2shoutrrr.LoadConfig shared by both commands.
- gotoolkit/service + gotoolkit/model.Server -> signal.NotifyContext
  and a concrete *Server whose Start shuts the listener down
  gracefully when its context is cancelled.

Also drops the unused ANONYMOUS SASL client from cmd/sendmail, bumps
alpine, golangci-lint and the CI actions, and adds coverage for config
loading and the server lifecycle.

Closes FMG-2

Co-authored-by: multica-agent <github@multica.ai>
ci: use the goreleaser from the CI image instead of goreleaser-action
All checks were successful
CI / goreleaser-lint (pull_request) Successful in 5s
CI / format (pull_request) Successful in 1m22s
CI / lint (pull_request) Successful in 3m37s
CI / test (pull_request) Successful in 3m32s
CI / build (pull_request) Successful in 5m24s
29e9343460
goreleaser-action v7.1.0 made cosign signature verification of its own
download mandatory, and ci-base ships no cosign — the goreleaser-lint
job failed on the v6.4.0 -> v7.2.3 bump.

The action was redundant anyway: ci-base already installs goreleaser
from the upstream apt repo, which is what `make build` has always used.
Both workflows now call it directly, and `goreleaser check` moves behind
a `make check` target so every CI job runs a make target.

Co-authored-by: multica-agent <github@multica.ai>
Collaborator

Superseded by #8, which carries an identical tree under the butterrobot account. Closing this one.

Superseded by #8, which carries an identical tree under the `butterrobot` account. Closing this one.
Author
Owner

#8

#8
fmartingr closed this pull request 2026-09-07 19:39:07 +02:00
All checks were successful
CI / goreleaser-lint (pull_request) Successful in 5s
CI / format (pull_request) Successful in 1m22s
CI / lint (pull_request) Successful in 3m37s
CI / test (pull_request) Successful in 3m32s
CI / build (pull_request) Successful in 5m24s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
fmartingr/smtp2shoutrrr!7
No description provided.