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
change go.mod to make current version (v2) a different module path #8852
Comments
This is a known issue with Go Modules. The semantic versioning of Prometheus versions the behavior of Prometheus as a server, not its code as a library. By changing the module path to v2, we would suggest that Prometheus obeys the contract of Go Modules as a library, but it doesn't, i.e. there are many breaking changes to expect even in a minor release. We had a lot of discussions around this, without a clear result yet. @roidelapluie is working on starting a design doc to summarize the results and come up with a conclusion. |
I see, thanks for the explanation. |
If you have a repo using go modules, what is the suggested way of building a write adapter if you can't add the module as a dependency. Unless we vendor the library, we cannot do as suggested in example documentation. Maybe the protos could be moved to |
Is there any update on this issue? Prometheus is used heavily used as a library (even though it is not intended to be so) and cannot be imported from the latest release at the point. This presents a huge risk such as not being able to patch a security issue if a vulnerability is found in the packages. |
Prometheus was not intended to be used as a library. Now that has changed, and it is intended to be used as such, even if we do not accept all general-purpose contributions. The go official wordings are clear that adding /v2 in the module name would tie is to using semver for the public API's. Having a dedicated go.mod with internal replace directives and releasing cmd/ independently requires an go.sum change for every time the code changes. On the other hand, users of Prometheus as a library require more frequent updates than users of Prometheus. And if there is a security issue in prometheus libraries that do not affect Prometheus users, tagging a new release would make everyone lose a lot of time by upgrading Prometheus for a noop change. I have still not really found a really great solution, it looks like the /v2 in module path would be the lowest cost for us and would fix 90% of the issues. |
After looking deeper, I do think that we should eventually make the move to v2, to keep things tagged. It would help casual downstream users, by clearly specifying which version of Prometheus they build against. Overall, we would need to clearly document that we do not follow semver on our interfaces, and that breaking changes to the code happen between minor releases of Prometheus. |
I'm not sure if moving to Status quoTo
Pro:
Con:
Suggested in this issueChange __ Pro:__
Con:
Another "easy" ideaHow about changing our future release tags to a format that Go Modules doesn't recognize? E.g. use Pro:
Con:
More involved approachesTo stay faithful to Go Modules, we needed to cut prometheus/prometheus into many modules, e.g. one for TSDB, one for PromQL, etc. We discussed this before. It would be a lot of additional work for the maintainers. Plus, a multi-module repository is considered to be pretty painful to handle. An attempt to get out of that is the modularise project, but it appears that despite all efforts, it hasn't got traction. ConclusionI'm really not sure what to do. All options seem to be bad in different ways. In that situation, I would just stay with the status quo because it is least work and at least doesn't create new sources of confusion. Personally, I could imagine that the separate tagging (what I titled "Another 'easy" idea" above) might be slightly less bad than the status quo and wouldn't require much additional work, but I might be missing something. |
I think that the "breakages" we make are often low-risk for consumers (it won't compile). Some parts of Prometheus are intended to be a library nowadays, so I would really like to do the change for v2, which makes it at the end easier for downstream users to know which version of Prometheus they are building against. |
Yeah, that's the best case, but it's still pretty bad for a user expecting Go Modules semantics. And it gets really bad if prometheus/prometheus is an indirect dependency. You use module foo (which depends on Prometheus v2.34) and module bar (which depends on Prometheus v2.35). You might end up in a situation where you cannot compile your code unless you change the code of your dependencies. (The same problem exist today, but at least we make it as obvious as we can that we aren't follow Go Module semantics, see above. That's why I think adding the
Yes, that's why I tend to do the "right thing", if we do anything at all. I.e. bite the bullet and maintain a multi-module repo. Or try out my idea with separate tagging for releases of Prometheus as a program vs. tags for the Go Module. |
I think separate tagging would have pretty bad side effects on downstream users that are following tags, it seems like it would cost them unnecessary efforts to adapt their patterns, probably an order of magnitude more annoying than moving to v2/. |
It appears we are both just restating what we said before. We only disagree in the impact of the various annoyances. We could go with changing to Or we declare it all not worth the risk and stay with the status quo. We should also take into account that the |
I would love to have something constructive to say. I've tried to solve this kind of problem a few times over the past 30 years and I do not know of any nice solutions where "force all users to upgrade now" is not an option.
+10 |
Alternative suggestion: As per @beorn7, change our release tags to a format that Go Modules doesn't recognise. But keep the code itself "un versioned" eg pre-v1. This sends the signal that our released binaries follow semver - but that the code doesn't, and that updating the code between any version can cause breakage (see https://go.dev/ref/mod):
This would require us to rename / change old tags, which may be a big no-no - but worth considering?
I agree; not a complete solution but one way to improve things is to make it possible for automated tools to update dependancies, and evangelise that. This way the we can find out if we break things more quickly, but also we can encourage everyone to be one the latest release. Right now eg dependabot won't update unversioned code, but renovatebot will. An extension to the above, to make this easier (and to be considered separately) would be to prefix release branches with WDYT? |
Can you clarify: your suggestion includes deleting all the |
All the historic tags would be changed to release-X.Y.Z instead of X.Y.Z or vX.Y.Z. Is that even possible? |
I would not change historic tags. What would be the effect of retracting the following releases from go.mod:
|
Oh I didn't know about retract! Should we do a fork with these changes and see how it works? (Sorry keep clicking the wrong button. Blame covid brain) |
My preference is to just move prometheus to v2. As said before, it would enable dependabot to work, and clarify which version of prometheus you are consuming. I think the cons- are not worth blocking us from doing so. |
If |
I usually find adding |
@invidian That's essentially what I proposed as "another 'easy' idea" above. Note that it requires to use a new tag format for our normal product releases (because we don't want to signal a breaking change to the users where there is on breaking change for users). Also note (as also said above) that the prometheus/prometheus as a set of libraries is pretty broad. We will have changes that are breaking somewhere with almost each minor product release. Which means we have to bump the Go Module major release more or less every six weeks. And this requires developers using prometheus/prometheus as a library to edit their import path very frequently to get updates, even if the part of the codebase they are using doesn't even have a breaking change. Go Modules have the problem of conflicting interests: On the one hand, you want small modules with a well defined and interrelated feature set so that a major version bump makes sense throughout the module. On the other hand, you want large modules to not face the complexity of managing a million small dependencies. |
That sounds like a code-smell to me. Usually it should be possible to rollout backward compatible changes by expanding the API + deprecating older calls. If that's really the case, perhaps indeed some kind of new module (generic prometheus library) should be rolled out with this repo adopting it eventually, which will have either more stable API or will be able to get version bumps more frequently? Maybe some stronger contracts should be defined around this before manifesting that using Go modules compatibility? The library could also start versioning from v0.x to account for frequent breaking changes. |
I think we could move the repository to a multi-module repository, with each part being v0.x unless / which only contains cmd/. |
That's true if you see the primary goal of prometheus/prometheus to provide a library for others to use. However, the actual primary goal is to provide a world-leading metrics-based monitoring system and maximize the innovation and dev speed for it. That's why there was so much quite controversial discussion how much effort the Prometheus devs should invest into making prometheus/prometheus also a good library for other devs to use. The priorities are obviously shifting here, with projects that are using prometheus/prometheus as a library gaining more and mori importance in the wider Prometheus ecosystem. Essentially, if we had the people do invest the effort, we could totally do a lot of things to improve the situation. It's mostly the question how much effort we can invest for it without harming the primary goals of the project. |
`go get` no longer works to install binaries with Go 1.18 and `go install` unfortunately doesn't work due to prometheus/prometheus#8852 and related issues. Thus install promtool from the Prometheos binary release. While at it bump the version to v2.34.0. Signed-off-by: Tobias Klauser <tobias@cilium.io>
`go get` no longer works to install binaries with Go 1.18 and `go install` unfortunately doesn't work due to prometheus/prometheus#8852 and related issues. Thus install promtool from the Prometheos binary release. While at it bump the version to v2.34.0. Signed-off-by: Tobias Klauser <tobias@cilium.io>
`go get` no longer works to install binaries with Go 1.18 and `go install` unfortunately doesn't work due to prometheus/prometheus#8852 and related issues. Thus install promtool from the Prometheos binary release. While at it bump the version to v2.34.0. Signed-off-by: Tobias Klauser <tobias@cilium.io>
`go get` no longer works to install binaries with Go 1.18 and `go install` unfortunately doesn't work due to prometheus/prometheus#8852 and related issues. Thus install promtool from the Prometheus binary release. While at it bump the version to v2.34.0. Signed-off-by: Tobias Klauser <tobias@cilium.io>
`go get` no longer works to install binaries with Go 1.18 and `go install` unfortunately doesn't work due to prometheus/prometheus#8852 and related issues. Thus install promtool from the Prometheus binary release. While at it bump the version to v2.34.0. Signed-off-by: Tobias Klauser <tobias@cilium.io>
prometheus 2.35.0-rc1 is avaible in go.mod as 0.35.0-rc1. I tried many things to make retract work, but it seems it just does not work for our usecase. Opened an issue at golang/go#52359 |
Hi 👋 , I just commented in golang/go/issues#52359, but three quick additional comments. I've only skimmed this issue here, so sorry if this is off base.
|
Thank you! That fixed the issue!!!! Awesome! |
To everyone on this issue: We will from now on mirror Prometheus releases to go.mod.
We have also retracted other releases from pkg.go.dev. The latest documentation is therefore available: https://pkg.go.dev/github.com/prometheus/prometheus Thank you all for your input and ideas. |
Proposal
Change the first line of go.mod to:
module github.com/prometheus/prometheus/v2
Use case. Why is this important?
it's the recommended way of releasing V2 and beyond
We have multiple projects using both v1 and v2 Prometheus in our monorepo. sharing the same import path for the incompatible versions is causing the problem
The text was updated successfully, but these errors were encountered: