From 127aca5f908f2092d533acfc122668d6d8c87b23 Mon Sep 17 00:00:00 2001 From: ivanauth Date: Thu, 16 Jul 2026 16:49:48 -0400 Subject: [PATCH] chore: enforce codegen plugin versions match go.mod The buf codegen plugins run via 'go run' from magefiles/go.mod, while the generated code links the runtime libraries in the root go.mod, so the two can silently drift apart. Add a lint:depsync mage target (run by CI via lint:extra) that compares the shared plugin/runtime module versions across both go.mod files. Fix the existing drift by bumping grpc-gateway v2.28.0 -> v2.29.0 in magefiles/go.mod. go mod tidy pulls in the versions that release requires: grpc v1.79.1 -> v1.80.0, x/text v0.35.0 -> v0.36.0, and the matching genproto revisions. Regenerating with the aligned versions produced no changes to the generated code. Signed-off-by: ivanauth --- magefiles/depsync.go | 83 ++++++++++++++++++++++++++++++++++++++++++++ magefiles/go.mod | 16 +++++---- magefiles/go.sum | 20 +++++------ magefiles/lint.go | 2 +- 4 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 magefiles/depsync.go diff --git a/magefiles/depsync.go b/magefiles/depsync.go new file mode 100644 index 0000000..76dca94 --- /dev/null +++ b/magefiles/depsync.go @@ -0,0 +1,83 @@ +//go:build mage + +package main + +import ( + "fmt" + "os" + "strings" + + "golang.org/x/mod/modfile" +) + +// codegenModules lists the modules that provide both a codegen plugin (run +// from the magefiles module via `go run`; see magefiles/buf.gen.yaml) and the +// runtime library that the generated code links against (a dependency of the +// root module). Their versions must match so that generated code and runtime +// agree; keep this list in sync with magefiles/buf.gen.yaml. +// +// protoc-gen-go-grpc is intentionally absent: it lives in its own module +// (google.golang.org/grpc/cmd/protoc-gen-go-grpc) with a version series +// unrelated to the google.golang.org/grpc runtime, so there is nothing to +// compare. +var codegenModules = []string{ + "google.golang.org/protobuf", + "github.com/grpc-ecosystem/grpc-gateway/v2", + "github.com/planetscale/vtprotobuf", + "github.com/envoyproxy/protoc-gen-validate", +} + +// Depsync checks that codegen plugin versions in magefiles/go.mod match go.mod +func (Lint) Depsync() error { + fmt.Println("checking codegen plugin versions against go.mod") + + rootVersions, err := moduleVersions("go.mod") + if err != nil { + return err + } + mageVersions, err := moduleVersions("magefiles/go.mod") + if err != nil { + return err + } + + var mismatches []string + for _, mod := range codegenModules { + rootVersion, inRoot := rootVersions[mod] + mageVersion, inMage := mageVersions[mod] + if !inRoot || !inMage { + // The module is no longer used by one of the go.mod files; + // this list and magefiles/buf.gen.yaml likely need updating. + continue + } + if rootVersion != mageVersion { + mismatches = append(mismatches, fmt.Sprintf( + "%s: go.mod has %s but magefiles/go.mod has %s", + mod, rootVersion, mageVersion)) + } + } + + if len(mismatches) > 0 { + return fmt.Errorf( + "codegen plugin versions are out of sync with go.mod:\n\t%s\n"+ + "align them (e.g. `go get -C magefiles @`), then run `mage deps:tidy` and `mage gen:proto`", + strings.Join(mismatches, "\n\t")) + } + return nil +} + +func moduleVersions(path string) (map[string]string, error) { + data, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("failed to read %s: %w", path, err) + } + file, err := modfile.Parse(path, data, nil) + if err != nil { + return nil, fmt.Errorf("failed to parse %s: %w", path, err) + } + + versions := make(map[string]string, len(file.Require)) + for _, req := range file.Require { + versions[req.Mod.Path] = req.Mod.Version + } + return versions, nil +} diff --git a/magefiles/go.mod b/magefiles/go.mod index a585b72..e1b9b7d 100644 --- a/magefiles/go.mod +++ b/magefiles/go.mod @@ -2,7 +2,10 @@ module github.com/authzed/authzed-go/magefiles go 1.25.6 -require github.com/magefile/mage v1.17.0 +require ( + github.com/magefile/mage v1.17.0 + golang.org/x/mod v0.34.0 +) require ( 4d63.com/gocheckcompilerdirectives v1.3.0 // indirect @@ -136,7 +139,7 @@ require ( github.com/gostaticanalysis/comment v1.5.0 // indirect github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect github.com/gostaticanalysis/nilerr v0.1.2 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect github.com/hashicorp/go-version v1.8.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect @@ -275,18 +278,17 @@ require ( golang.org/x/crypto v0.49.0 // indirect golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect golang.org/x/exp/typeparams v0.0.0-20260209203927-2842357ff358 // indirect - golang.org/x/mod v0.34.0 // indirect golang.org/x/net v0.52.0 // indirect golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.42.0 // indirect golang.org/x/telemetry v0.0.0-20260311193753-579e4da9a98c // indirect golang.org/x/term v0.41.0 // indirect - golang.org/x/text v0.35.0 // indirect + golang.org/x/text v0.36.0 // indirect golang.org/x/tools v0.43.0 // indirect golang.org/x/vuln v1.1.4 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect - google.golang.org/grpc v1.79.1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + google.golang.org/grpc v1.80.0 // indirect google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.1 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/magefiles/go.sum b/magefiles/go.sum index db43632..6f655fe 100644 --- a/magefiles/go.sum +++ b/magefiles/go.sum @@ -306,8 +306,8 @@ github.com/gostaticanalysis/nilerr v0.1.2/go.mod h1:A19UHhoY3y8ahoL7YKz6sdjDtduw github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= github.com/gostaticanalysis/testutil v0.5.0 h1:Dq4wT1DdTwTGCQQv3rl3IvD5Ld0E6HiY+3Zh0sUGqw8= github.com/gostaticanalysis/testutil v0.5.0/go.mod h1:OLQSbuM6zw2EvCcXTz1lVq5unyoNft372msDY0nY5Hs= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs= github.com/hashicorp/go-immutable-radix/v2 v2.1.0 h1:CUW5RYIcysz+D3B+l1mDeXrQ7fUvGGCwJfdASSzbrfo= github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= @@ -737,8 +737,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -765,12 +765,12 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= -google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= -google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec= +google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.1 h1:/WILD1UcXj/ujCxgoL/DvRgt2CP3txG8+FwkUbb9110= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.1/go.mod h1:YNKnb2OAApgYn2oYY47Rn7alMr1zWjb2U8Q0aoGWiNc= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/magefiles/lint.go b/magefiles/lint.go index 03b61d6..9c86471 100644 --- a/magefiles/lint.go +++ b/magefiles/lint.go @@ -22,7 +22,7 @@ func (l Lint) All() error { // Extra lits everything that's not code func (l Lint) Extra() error { - mg.Deps(l.Yaml) + mg.Deps(l.Yaml, l.Depsync) return nil }