Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: bump go to 1.23.4 and gqlgen to v0.17.51 #607

Merged
merged 2 commits into from
Dec 30, 2024

Conversation

michaelcaulley
Copy link
Contributor

@michaelcaulley michaelcaulley commented Dec 18, 2024

Summary

  • bump go to 1.23.4 and gqlgen to v0.17.51

@michaelcaulley michaelcaulley force-pushed the go-and-gql-version-bump branch from 3af58ab to ea64e7e Compare December 18, 2024 20:39
@michaelcaulley michaelcaulley force-pushed the go-and-gql-version-bump branch from ea64e7e to 159f393 Compare December 18, 2024 21:42
@michaelcaulley michaelcaulley changed the title chore: bump go to 1.23.4 and gqlgen to v0.17.60 chore: bump go to 1.23.4 and gqlgen to v0.17.51 Dec 18, 2024
@vitorfalcaor
Copy link

Hey @michaelcaulley are you able to get this merged, please? I have another dep on 1.23.4 and code-gen is breaking for me.

@michaelcaulley
Copy link
Contributor Author

@a8m , is the failing lint rule unrelated? It looks like everything passed except two lint issues.

@a8m
Copy link
Member

a8m commented Dec 28, 2024

Master is green (I just merged a PR yesterday), so something in the upgrade cause it to fail.

image

@michaelcaulley michaelcaulley force-pushed the go-and-gql-version-bump branch from cf60dc8 to 44c4de5 Compare December 28, 2024 15:33
@michaelcaulley michaelcaulley force-pushed the go-and-gql-version-bump branch from 44c4de5 to 769c44e Compare December 28, 2024 15:36
@michaelcaulley
Copy link
Contributor Author

@a8m I bumped the golangci-lint version, and the checks are passing. However, I did have two errors related to a potential int overflow during a cast to int32. I added a check and returned an error if an overflow occurred. This change is in the second commit. Can you please check it before merging?

Copy link
Member

@a8m a8m left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution, @michaelcaulley.

@a8m a8m merged commit 40c9e7b into ent:master Dec 30, 2024
4 checks passed
@vitorfalcaor
Copy link

Thank you @michaelcaulley for working on this and thanks @a8m for reviewing and approving it!

@StevenACoffman
Copy link
Contributor

@a8m @michaelcaulley @vitorfalcaor Thanks for your work!

I see that this PR has a comment that says that gqlgen version v0.17.52 has an issue with ent field collection. It blames commit: 99designs/gqlgen@f81239e

The blamed gqlgen commit was merged 99designs/gqlgen#3287
This was to fix 99designs/gqlgen#3285 by reverting 99designs/gqlgen#3203

Currently gqlgen v0.17.61 is the latest. It is not clear to me if there remains any problem with gqlgen and ent field collection.
Please point me to an open issue in gqlgen (or PR) describing (or fixing) the ent field collection problem.

@StevenACoffman
Copy link
Contributor

I opened #609 to see if there's anything amiss in the current v0.17.61 version.

@vitorfalcaor
Copy link

I was just able to test this and I am actually still running into modelgen: unable to find type: backend/ent/company.ListingSegment error. I initially thought this PR would fix it, since codegen started failing for me after I had to bump my golang version from 1.22 to 1.23.4. I also have gqlgen v0.17.61. @StevenACoffman what would be a concrete next step here? Should I open an issue in the gqlgen repo with my gqlgen.yml file?

@StevenACoffman
Copy link
Contributor

StevenACoffman commented Dec 30, 2024

@vitorfalcaor If you can provide something I can reproduce locally, that would be very helpful.

The two biggest changes that have happened in gqlgen and gqlparser recently are that we no longer allow the invalid empty GraphQL arguments (()) and we no longer allow null key fieldsets in the apollo federation plugin.

(The GraphQL specification does not allow empty arguments, but the specification's wording of that restriction was originally confusing, and the reference test suite did not require it. After they clarified the wording and tightened the specification tests, gqlparser was no longer compliant.)

The error message you are reporting is not consistent with either one of these big changes, so something I can reproduce would be needed for me to help more.

@michaelcaulley
Copy link
Contributor Author

michaelcaulley commented Dec 31, 2024

Hi, @StevenACoffman. I'll create an example in the next week or two. I initially tried the latest version of gqlgen but saw n+1 queries instead of ent properly doing field collection to use a SQL join. I worked backward from the latest version to find one that worked ok, which led me to use version 0.17.51.

Edit: I just tried 0.17.61, and I no longer see any issues with it. I can try to find the problematic version sometime later; perhaps I had a mismatch in my go.mod, and what contrib included?

For now, I see no reason not to bump the version all the way to the latest, 0.17.61.

@StevenACoffman
Copy link
Contributor

Ok, that's great news. Thanks for checking. So hopefuly #609 is approved and can get merged then.

@StevenACoffman
Copy link
Contributor

@michaelcaulley Can you look to see what is wrong with my build of #609 ?

@vitorfalcaor
Copy link

vitorfalcaor commented Jan 2, 2025

Hey @StevenACoffman, Happy New Year! I was able to repro the issue of type not found by following these steps:

  1. git clone https://github.com/a8m/ent-graphql-example
  2. Edit go.mod and replace go 1.19 with go 1.23.4
  3. Run go mod tidy
  4. Run gqlgen --config gqlgen.yml –> Make sure that you have the latest version, I cloned the master branch of gqlgen and ran go install . prior to running this command.

Expected output:

modelgen: unable to find type: todo/ent/todo.Status

After diving deeper into this issue I found these two insights:

  1. So far this issue only happened with ENUM types, both in the ent-graphql-example repo and in my own private project
  2. I was able to pinpoint the issue as coming from here: https://github.com/99designs/gqlgen/blob/master/internal/code/packages.go#L111. When using go 1.22 this property is correctly populated. But when using go 1.23.4 the property pkg.TypesInfo is empty. When printing it I see: &{map[] map[] map[] map[] map[] map[] map[] [] map[]}. This later will cause indexDefs to return an empty Object since the for loop won't execute, given that TypesInfo is empty: https://github.com/99designs/gqlgen/blob/master/codegen/config/binder.go#L167

Please let me know if you prefer that I open an issue, but it seems that this is an issue with golang.org/x/tools and not gqlgen itself.

@StevenACoffman
Copy link
Contributor

StevenACoffman commented Jan 2, 2025

I made a8m/ent-graphql-example#12 to avoid any miscommunication.

go mod edit -go=1.23.4
go get github.com/99designs/gqlgen@v0.17.62
go get entgo.io/ent@v0.14.1
go get entgo.io/contrib@v0.6.0
go mod tidy

That is the state of where that PR is. However, in this state if I run:

go run -mod=mod github.com/99designs/gqlgen --config gqlgen.yml

I get these errors:

validation failed: packages.Load: -: # todo
./prelude.resolvers.go:16:7: invalid receiver type __FieldResolver (pointer or interface type)
./prelude.resolvers.go:21:7: invalid receiver type __FieldResolver (pointer or interface type)
./prelude.resolvers.go:51:6: __FieldResolver redeclared in this block
	./generated.go:104:6: other declaration of __FieldResolver
./prelude.resolvers.go:52:6: __TypeResolver redeclared in this block
	./generated.go:111:6: other declaration of __TypeResolver
./generated.go:2456:33: cannot call pointer method Description on __FieldResolver
./generated.go:2497:33: cannot call pointer method Args on __FieldResolver
./generated.go:2551:33: cannot call pointer method Type on __FieldResolver
./generated.go:2617:33: cannot call pointer method IsDeprecated on __FieldResolver
./generated.go:2661:33: cannot call pointer method DeprecationReason on __FieldResolver
./generated.go:3375:32: cannot call pointer method Fields on __TypeResolver
./prelude.resolvers.go:21:7: too many errors
/Users/steve/Documents/git/ent-graphql-example/prelude.resolvers.go:51:6: __FieldResolver redeclared in this block
/Users/steve/Documents/git/ent-graphql-example/generated.go:104:6: 	other declaration of __FieldResolver
/Users/steve/Documents/git/ent-graphql-example/prelude.resolvers.go:52:6: __TypeResolver redeclared in this block
/Users/steve/Documents/git/ent-graphql-example/generated.go:111:6: 	other declaration of __TypeResolver
/Users/steve/Documents/git/ent-graphql-example/generated.go:2456:33: cannot call pointer method Description on __FieldResolver
/Users/steve/Documents/git/ent-graphql-example/generated.go:2497:33: cannot call pointer method Args on __FieldResolver
/Users/steve/Documents/git/ent-graphql-example/generated.go:2551:33: cannot call pointer method Type on __FieldResolver
/Users/steve/Documents/git/ent-graphql-example/generated.go:2617:33: cannot call pointer method IsDeprecated on __FieldResolver
/Users/steve/Documents/git/ent-graphql-example/generated.go:2661:33: cannot call pointer method DeprecationReason on __FieldResolver
/Users/steve/Documents/git/ent-graphql-example/generated.go:3375:32: cannot call pointer method Fields on __TypeResolver
/Users/steve/Documents/git/ent-graphql-example/prelude.resolvers.go:16:7: invalid receiver type __FieldResolver (pointer or interface type)
/Users/steve/Documents/git/ent-graphql-example/prelude.resolvers.go:21:7: invalid receiver type __FieldResolver (pointer or interface type)
/Users/steve/Documents/git/ent-graphql-example/prelude.resolvers.go:26:7: invalid receiver type __FieldResolver (pointer or interface type)
/Users/steve/Documents/git/ent-graphql-example/prelude.resolvers.go:31:7: invalid receiver type __FieldResolver (pointer or interface type)
/Users/steve/Documents/git/ent-graphql-example/prelude.resolvers.go:36:7: invalid receiver type __FieldResolver (pointer or interface type)
/Users/steve/Documents/git/ent-graphql-example/prelude.resolvers.go:41:7: invalid receiver type __TypeResolver (pointer or interface type)
/Users/steve/Documents/git/ent-graphql-example/prelude.resolvers.go:46:56: invalid composite literal type __FieldResolver
/Users/steve/Documents/git/ent-graphql-example/prelude.resolvers.go:49:54: invalid composite literal type __TypeResolver

exit status 1

@vitorfalcaor
Copy link

Also commenting here to keep everyone in the loop.

Thanks for creating this @StevenACoffman! I got the same result as you, but if I run go run -mod=mod github.com/99designs/gqlgen@latest --config gqlgen.yml (note the @latest) gives me:

go: github.com/99designs/gqlgen@v0.17.62 requires go >= 1.22.5; switching to go1.22.10
modelgen: unable to find type: todo/ent/todo.Status
exit status 1

Can you try repro'ing this, please?

@StevenACoffman
Copy link
Contributor

StevenACoffman commented Jan 3, 2025

Yeah, I can reproduce this, but I'm not sure what has changed in x/tools that causes this. Do we need to add there in gqlgen https://github.com/99designs/gqlgen/blob/master/internal/code/packages.go#L111 a new config option to the packages Load?

@vitorfalcaor
Copy link

Hey @StevenACoffman I don't think so. This is the first time I am dealing with this code, so I am learning as we go. I tested adding other options to the Config, but I wasn't successful.

I did run one interesting test. I added a main.go to the root of my project with:

func main() {
	pkgs := []string{
		"backend/nonexistentpackage",
	}

	p, err := packages.Load(&packages.Config{
		Mode: packages.NeedName |
			packages.NeedFiles |
			packages.NeedTypes |
			packages.NeedSyntax |
			packages.NeedTypesInfo |
			packages.NeedModule,
	}, pkgs...)

	if err != nil {
		fmt.Println("err: ", err)
	}

	for _, pkg := range p {
		fmt.Println("pkg: ", pkg)
		fmt.Println(len(pkg.TypesInfo.Types))
	}
}

This code prints:

pkg: backend/nonexistentpackage
0

I then tested this code with an actual name for a local package and it did work just fine. This indicates that what's happening in the gqlgen instance is that packages.Load isn't finding the user's packages. I am not sure what to do next here, any ideas?

@StevenACoffman
Copy link
Contributor

StevenACoffman commented Jan 4, 2025

Hmm, I tried setting the toolchain directive in the go.mod, as I wondered if it was something to do with golang/go#62114

Can you try doing:

export GOTOOLCHAIN=1.23.4

and try it again to see if it is different?

I can look again on Monday, but if you figure it out before hand, let me know.

@vitorfalcaor
Copy link

@StevenACoffman AMAZING! This fixed it! Please note that it didn't work when setting &packages.Config{..., Env: append(os.Environ(), "GOTOOLCHAIN=go1.23.4"), but it did work by simply doing export GOTOOLCHAIN=go1.23.4.

Thank you so much for the help!

@StevenACoffman
Copy link
Contributor

StevenACoffman commented Jan 4, 2025

Glad you have a workaround, but Ugh, this is going to cause other people problems.

@vitorfalcaor, can you dump out your os.Exec("go env") and your os.Environ() before that line so I can see what is different?

I think if you used:

err := os.Setenv("GOTOOLCHAIN","go1.23.4")

it would work, but only if you are using that specific version of Go for that line. Go 1.23.3 will have loaded the packages and then it will download and use a local Go 1.23.4 toolchain that doesn't have it.

You got:

go: github.com/99designs/gqlgen@v0.17.62 requires go >= 1.22.5; switching to go1.22.10

So I think when you are using go run -mod=mod github.com/99designs/gqlgen@latest --config gqlgen.yml the Go version you executed it with downloads the Go 1.22.10 toolchain, but the ent-graphql-example downloads the Go 1.23.4 toolchain, gqlgen's toolchain (1.22.10) can't see the packages in the Go 1.23.4 toolchain (or possibly your Go 1.22.5 toolchain has them somewhere).

Forcing both the runtime and toolchain to match for every place fixes it, but figuring out how to detect what that is and set it is tricky.

@vitorfalcaor
Copy link

Hey @StevenACoffman just to complement what I shared earlier, I also had to clone https://github.com/99designs/gqlgen, do a go get golang.org/x/tools@latest in the local gqlgen repo, then go install . and that fixed the issue.

Here's the output of what you requested. Command:

cmd := exec.Command("go", "env")
output, _ := cmd.Output()
fmt.Println("go env: ", string(output))
fmt.Println("os.Environ(): ", os.Environ())

Output:

go env:  GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/root/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/root/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.4.linux-arm64'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='go1.23.4'
GOTOOLDIR='/root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.4.linux-arm64/pkg/tool/linux_arm64'
GOVCS=''
GOVERSION='go1.23.4'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/root/.config/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/workspace/backend/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build4124926892=/tmp/go-build -gno-record-gcc-switches'

os.Environ():  [PROJECT_ROOT=/workspace BROWSER=/vscode/cursor-server/bin/linux-arm64/316e524257c2ea23b755332b0a72c50cf23e1b00/bin/helpers/browser.sh PATH=/vscode/cursor-server/bin/linux-arm64/316e524257c2ea23b755332b0a72c50cf23e1b00/bin/remote-cli:/root/go/bin:/root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin OLDPWD=/workspace TERM_PROGRAM=vscode VSCODE_IPC_HOOK_CLI=/tmp/vscode-ipc-e16c9b32-b4a8-4c03-ae3a-54ecd2b8d831.sock _=/root/go/bin/gqlgen]

@StevenACoffman
Copy link
Contributor

StevenACoffman commented Jan 4, 2025

Thanks! And that output was with or without the local environment variable GOTOOLCHAIN set and exported?

I cannot force gqlgen to use a later x/tools as I can't move gqlgen to require Go 1.23 until Go 1.24 is released in February (or really until Go AppEngine supports Go 1.23 so my work can use it in their prod)

@vitorfalcaor
Copy link

That output was with export GOTOOLCHAIN=go1.23.4 and with the local installation of gqlgen@latest, while also bumping x/tools. What other tests would you like me to run?

Got it, thank you for providing this context. In this case, what would you recommend I do? Keep a local copy of gqlgen and bump x/tools? Is it feasible to bump the version of gqlgen and x/tools, so the existing version continues using 1.22 and x/tools 0.24?

@StevenACoffman
Copy link
Contributor

StevenACoffman commented Jan 4, 2025

Can you run unset GOTOOLCHAIN and then redump the go env for me?

cmd := exec.Command("go", "env")
output, _ := cmd.Output()
fmt.Println("go env: ", string(output))

If you unset GOTOOLCHAIN and first compile gqlgen into a local binary (go build -o ~/go/bin/gqlgen github.com/99designs/gqlgen), and then execute that binary (~/go/bin/gqlgen --config gqlgen.yml) I think you may not have the issue at all, since you will have one less toolchain for the packages to get lost in.

If that doesn't work, updating your local Go to 1.23.4 and then repeating the above (compiling gqlgen, then executing the binary gqlgen) should work since then there's only one Go toolchain involved.

If that doesn't work, then locally updating your copy of gqlgen to the latest x/tools, compiling that into a binary with the now Go 1.23.4 local Go, and executing that gqlgen should definitely work since both at compile time and runtime, there's only one Go toolchain and only one x/tools.

@vitorfalcaor
Copy link

The first options worked well: compile gqlgen into a local binary (go build -o /go/bin/gqlgen github.com/99designs/gqlgen), and then execute that binary (/go/bin/gqlgen --config gqlgen.yml).

Here's the test:

Setup:

  1. git clone https://github.com/99designs/gqlgen
  2. Edit packages.go to add the command
  3. go install .
  4. cd into my repo, then gqlgen --config ...

Output:

go env:  GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/root/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/root/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.4.linux-arm64'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.4.linux-arm64/pkg/tool/linux_arm64'
GOVCS=''
GOVERSION='go1.23.4'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/root/.config/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/workspace/backend/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3756876503=/tmp/go-build -gno-record-gcc-switches'

Thanks for all the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants