From c09a3ac7bb13b5508d78700a6769b1e011f7ad30 Mon Sep 17 00:00:00 2001 From: Brandur Date: Thu, 8 Aug 2024 18:00:45 -0700 Subject: [PATCH] Establish minimum Go version of 1.21, with toolchain of Go 1.22 This one related to #520, in which it turns out that our Go 1.21 build step has actually been automatically upgrading itself to Go 1.22, so under the radar that we didn't notice. Here, leverage a Go "toolchain" to establish a preferred version of Go for the project, but keeping a `go` directive in `go.mod`s that's at the 1.21 lower bound that we're trying to support. The presence of a `toolchain` directive prevents `go mod tidy` from upgrading the `go` directive to the latest version of Go installed. I found the easiest way to add the toolchain directive to be with `go get` [2] like: go get go@1.21 toolchain@1.22.5 Maintaining this correctly is going to be a little tricky. This is one of those classic Go features that kind of works, but various Go commands will perform all kinds of confusing behavior like stripping directives out of your file if there's anything even a tiny bit wrong, and with no explanation whatsoever. I found that to get this working I had to started with the "inner" dependencies like `rivershared` and `rivertype`, `go get` Go/toolchain there first, then work my way up the stack all the way up to the main project. I'm going to try and follow this up with some tooling to help make this easier for ourselves, and a build check that verifies in CI that nothing gets accidentally regressed as we make changes because this is _very_ easy to do accidentally. Fixes #520. [1] https://go.dev/doc/toolchain [2] https://go.dev/doc/toolchain#get --- .github/workflows/ci.yaml | 6 ++++++ CHANGELOG.md | 1 + cmd/river/go.mod | 16 ++++++++++------ cmd/river/go.sum | 12 ------------ go.mod | 4 +++- internal/jobcompleter/job_completer.go | 2 +- internal/notifier/notifier.go | 2 +- riverdriver/go.mod | 4 +++- riverdriver/riverdatabasesql/go.mod | 4 +++- .../river_database_sql_driver_test.go | 2 ++ riverdriver/riverpgxv5/go.mod | 4 +++- rivershared/go.mod | 4 +++- rivertype/go.mod | 4 +++- 13 files changed, 39 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d24d2867..7a307335 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -18,6 +18,12 @@ on: jobs: build_and_test: + env: + # The special value "local" tells Go to use the bundled Go version rather + # than trying to fetch one according to a `toolchain` value in `go.mod`. + # This ensures that we're really running the Go version in the CI matrix + # rather than one that the Go command has upgraded to automatically. + GOTOOLCHAIN: local runs-on: ubuntu-latest strategy: matrix: diff --git a/CHANGELOG.md b/CHANGELOG.md index 479285c5..de12d249 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Derive all internal contexts from user-provided `Client` context. This includes the job fetch context, notifier unlisten, and completer. [PR #514](https://github.com/riverqueue/river/pull/514). +- Lowered the `go` directives in `go.mod` to Go 1.21, which River aims to support. A more modern version of Go is specified with the `toolchain` directive. [PR #522](https://github.com/riverqueue/river/pull/522). ## [0.11.1] - 2024-08-05 diff --git a/cmd/river/go.mod b/cmd/river/go.mod index 7d605509..526d252f 100644 --- a/cmd/river/go.mod +++ b/cmd/river/go.mod @@ -1,16 +1,20 @@ module github.com/riverqueue/river/cmd/river -go 1.22.5 +go 1.21 -// replace github.com/riverqueue/river => ../.. +toolchain go1.22.5 -// replace github.com/riverqueue/river/riverdriver => ../../riverdriver +replace github.com/riverqueue/river => ../.. -// replace github.com/riverqueue/river/riverdriver/riverdatabasesql => ../../riverdriver/riverdatabasesql +replace github.com/riverqueue/river/riverdriver => ../../riverdriver -// replace github.com/riverqueue/river/riverdriver/riverpgxv5 => ../../riverdriver/riverpgxv5 +replace github.com/riverqueue/river/riverdriver/riverdatabasesql => ../../riverdriver/riverdatabasesql -// replace github.com/riverqueue/river/rivertype => ../../rivertype +replace github.com/riverqueue/river/riverdriver/riverpgxv5 => ../../riverdriver/riverpgxv5 + +replace github.com/riverqueue/river/rivershared => ../../rivershared + +replace github.com/riverqueue/river/rivertype => ../../rivertype require ( github.com/jackc/pgx/v5 v5.6.0 diff --git a/cmd/river/go.sum b/cmd/river/go.sum index a172c0a8..a3b94248 100644 --- a/cmd/river/go.sum +++ b/cmd/river/go.sum @@ -24,18 +24,6 @@ github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/riverqueue/river v0.11.1 h1:/etRDY73opKDNNeY+mPlPrIYszRdGUduFtsBmRwzChY= -github.com/riverqueue/river v0.11.1/go.mod h1:BaMj1UOC8mjMBlSY7Sjmuywm8XlkhgHkzNfH3eaX47g= -github.com/riverqueue/river/riverdriver v0.11.1 h1:AYgVhwL3Ifu6EO3fi4WjyVlHJVvbATbJnw37nSmUH6c= -github.com/riverqueue/river/riverdriver v0.11.1/go.mod h1:po4YTDEJRjxzdxK+IQ4Bu1JsW1PPQfslMdkj5rNNY9c= -github.com/riverqueue/river/riverdriver/riverdatabasesql v0.11.1 h1:b81ZT8X8Kdrulim4hJ5wmQGQyumpQPsjepA6d+MxH3Y= -github.com/riverqueue/river/riverdriver/riverdatabasesql v0.11.1/go.mod h1:Do5dgb+TsHC6O+NIyZx3SHbLIxKlEK8VeIsopgmVo1A= -github.com/riverqueue/river/riverdriver/riverpgxv5 v0.11.1 h1:tmGBw3I52Fzj/W5KesGJPF0D7xOj83rnL4igd433UyI= -github.com/riverqueue/river/riverdriver/riverpgxv5 v0.11.1/go.mod h1:rdDGaq/SOpfnqk0hRjvNAs+xqdvK6EkASh6tknbx2x4= -github.com/riverqueue/river/rivershared v0.11.1 h1:5HDZ5fPrHf68lrE2CTTTUfRfdCmfW1G6P/v0zCvor7I= -github.com/riverqueue/river/rivershared v0.11.1/go.mod h1:2egnQ7czNcW8IXKXMRjko0aEMrQzF4V3k3jddmYiihE= -github.com/riverqueue/river/rivertype v0.11.1 h1:sdrGb07cAGOy5f20HO/b2xts8Bz7lKCZLHl6jifzJ7A= -github.com/riverqueue/river/rivertype v0.11.1/go.mod h1:nDd50b/mIdxR/ezQzGS/JiAhBPERA7tUIne21GdfspQ= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= diff --git a/go.mod b/go.mod index d2e38cac..e2e2933e 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/riverqueue/river -go 1.22.5 +go 1.21 + +toolchain go1.22.5 replace github.com/riverqueue/river/riverdriver => ./riverdriver diff --git a/internal/jobcompleter/job_completer.go b/internal/jobcompleter/job_completer.go index 31588c24..257e9fed 100644 --- a/internal/jobcompleter/job_completer.go +++ b/internal/jobcompleter/job_completer.go @@ -521,7 +521,7 @@ func withRetries[T any](logCtx context.Context, baseService *baseservice.BaseSer ctx, cancel := context.WithTimeout(uncancelledCtx, timeout) defer cancel() - retVal, err := retryFunc(ctx) //nolint:contextcheck + retVal, err := retryFunc(ctx) if err != nil { // A cancelled context will never succeed, return immediately. if errors.Is(err, context.Canceled) { diff --git a/internal/notifier/notifier.go b/internal/notifier/notifier.go index 029c44fb..8419dc52 100644 --- a/internal/notifier/notifier.go +++ b/internal/notifier/notifier.go @@ -36,7 +36,7 @@ type Subscription struct { func (s *Subscription) Unlisten(ctx context.Context) { s.unlistenOnce.Do(func() { // Unlisten strips cancellation from the parent context to ensure it runs: - if err := s.notifier.unlisten(context.WithoutCancel(ctx), s); err != nil { //nolint:contextcheck + if err := s.notifier.unlisten(context.WithoutCancel(ctx), s); err != nil { s.notifier.Logger.ErrorContext(ctx, s.notifier.Name+": Error unlistening on topic", "err", err, "topic", s.topic) } }) diff --git a/riverdriver/go.mod b/riverdriver/go.mod index 35261c08..7fbaaf89 100644 --- a/riverdriver/go.mod +++ b/riverdriver/go.mod @@ -1,6 +1,8 @@ module github.com/riverqueue/river/riverdriver -go 1.21.4 +go 1.21 + +toolchain go1.22.5 replace github.com/riverqueue/river/rivertype => ../rivertype diff --git a/riverdriver/riverdatabasesql/go.mod b/riverdriver/riverdatabasesql/go.mod index e5eed7c9..3a4ebf86 100644 --- a/riverdriver/riverdatabasesql/go.mod +++ b/riverdriver/riverdatabasesql/go.mod @@ -1,6 +1,8 @@ module github.com/riverqueue/river/riverdriver/riverdatabasesql -go 1.22.5 +go 1.21 + +toolchain go1.22.5 replace github.com/riverqueue/river/riverdriver => ../ diff --git a/riverdriver/riverdatabasesql/river_database_sql_driver_test.go b/riverdriver/riverdatabasesql/river_database_sql_driver_test.go index d6daf359..f42ee284 100644 --- a/riverdriver/riverdatabasesql/river_database_sql_driver_test.go +++ b/riverdriver/riverdatabasesql/river_database_sql_driver_test.go @@ -78,6 +78,8 @@ func TestReplaceNamed(t *testing.T) { {Desc: "SliceUint64", ExpectedSQL: "SELECT ARRAY[123,124]", InputSQL: "SELECT @slice_uint64", InputArgs: map[string]any{"slice_uint64": []uint64{123, 124}}}, } for _, tt := range testCases { + tt := tt + t.Run(tt.Desc, func(t *testing.T) { t.Parallel() diff --git a/riverdriver/riverpgxv5/go.mod b/riverdriver/riverpgxv5/go.mod index 5c61b589..c5e12181 100644 --- a/riverdriver/riverpgxv5/go.mod +++ b/riverdriver/riverpgxv5/go.mod @@ -1,6 +1,8 @@ module github.com/riverqueue/river/riverdriver/riverpgxv5 -go 1.22.5 +go 1.21 + +toolchain go1.22.5 replace github.com/riverqueue/river/riverdriver => ../ diff --git a/rivershared/go.mod b/rivershared/go.mod index 56772978..a9ebe018 100644 --- a/rivershared/go.mod +++ b/rivershared/go.mod @@ -1,6 +1,8 @@ module github.com/riverqueue/river/rivershared -go 1.22.5 +go 1.21 + +toolchain go1.22.5 require ( github.com/stretchr/testify v1.9.0 diff --git a/rivertype/go.mod b/rivertype/go.mod index a273d11b..fc474293 100644 --- a/rivertype/go.mod +++ b/rivertype/go.mod @@ -1,6 +1,8 @@ module github.com/riverqueue/river/rivertype -go 1.21.4 +go 1.21 + +toolchain go1.22.5 require github.com/stretchr/testify v1.9.0