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

The Go version specified in a go.mod file should influence the installed version #344

Open
ryanmoran opened this issue Feb 27, 2023 · 6 comments

Comments

@ryanmoran
Copy link
Contributor

What version of the buildpack you are using?

1.10.5

If you were attempting to accomplish a task, what was it you were attempting to do?

I was attempting to use the version of Go that my application specifies.

The go.mod file in my app specifies 1.19, but it appears that the buildpack still chooses to install 1.18 since that is the default version specified in the buildpack.

What did you expect to happen?

I expected to see 1.19 installed since it is available in the buildpack and my app wants that version.

What was the actual behavior?

The buildpack ignores my go.mod file and installs 1.18.

@brayanhenao brayanhenao self-assigned this Mar 8, 2023
@brayanhenao brayanhenao moved this from ❓ Not scoped to 🚧 In Progress in CF Buildpacks Workstreams Mar 8, 2023
@brayanhenao
Copy link
Member

@ryanmoran Context on why we rollback this functionality some months ago #254

@ryanmoran
Copy link
Contributor Author

Assigning this to @robdimsdale

@robdimsdale
Copy link
Member

Ok, so reading #253 I think there were two separate things going on here.

Firstly, it looks like the original poster had an invalid go.mod file based on the error:

ERROR Unable to determine Go version to install: improper constraint: .x

If the go.mod file exists and contains a go version, the go version must be valid semver. .x is not a valid semver constraint. So my expectation is that something was incorrect with that app.

Secondly, it looks like the next poster had a legitimate issue - that the go version in go.mod represents a lower bound for the acceptable go version, but that the buildpack tried to use it as the exact version.

There are two more use cases to handle:

  1. the go.mod file exists but doesn't have a go version
  2. the go.mod file does not exist at all

Luckily I think #254 actually handles most of these cases already. I think the use-case we're missing - and the one @ryanmoran is asking for - is that if go.mod contains a version that the buildpack supports, and is higher than the default version in the buildpack, the buildpack should pick that version.

Laid out more explicitly:

Given a buildpack with Go 1.18 and Go 1.19, and where Go 1.18 is the default, and assuming higher-priority selection criteria (e.g. GOVERSION) are absent, then:

  • If go.mod contains go 1.18 or lower, the buildpack should select Go 1.18 - as this is the default version and it matches the lower bound constraint from the go.mod file.
  • If go.mod contains go 1.19, the buildpack should select Go 1.19 - as this is the only version that satisfies the lower bound of go 1.19 from the go.mod file.
  • If go.mod contains 1.20, the buildpack should fail - as there is no valid version of golang the buildpack can provide to satisfy the lower bound of 1.20 from the go.mod file.

Things would get a bit more complicated if the buildpack also had go 1.20, but that isn't a problem we need to solve because Go's support policy is only to support two versions at a time - so when 1.20 was released (and added to the buildpack), 1.18 would be out of support and hence can be removed from the buildpack.

cc @ForestEckhardt - does this sound right to you? If you agree with the logic above, any objections to implementing the requested feature?

@ForestEckhardt
Copy link
Member

I think that all sounds fine to me.

@robdimsdale
Copy link
Member

I think we can tie this in with #374 and both detect on go.mod and use the value of go <version> if that version is higher than our default.

Especially since go 1.22, where the go <version> is now a canonical source of truth for the version of go that should be used to build the app.

@maxmoehl
Copy link
Member

maxmoehl commented Sep 5, 2024

To me it seems like #374 will take some time to be implemented given the uncertainty around the usage of the other dependency management systems.

Regarding #253 that caused the revert: Wouldn't it be an option to ignore the go.mod version in case we can't match it up with one of the bundled go versions? In that case we would fall back to the default buildpack version and let the go compiler deal with it. So I would re-phrase your third bullet:

  • If go.mod contains a go version the buildpack does not know about, the buildpack should default to 1.18 and let the go toolchain deal with it.

Now that 1.21 is the default this allows for another scenario: unless the user explicitly sets GOTOOLCHAIN=local the go command will go ahead and download any required toolchain automatically which should alleviate most of the version selection issues today without a change to the buildpack. However, we have to deploy to air-gapped systems and are forced to set GOTOOLCHAIN=local (otherwise the download fails and the build aborts) and thus require the version selection mechanism of the buildpack to work based on the go.mod go directive.

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

No branches or pull requests

6 participants