-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
runtime/debug: document BuildInfo.Main.Version == "(devel)" #29228
Comments
We could perhaps detect the case where the main module happens to be a pristine checkout with a semantically-versioned tag, although that might be misleading if some other module has a cyclic requirement specifying a higher version than the tag. |
+1. I thought being able to print the program’s main module’s version was the whole point of embedding build information into the binary. |
#26404 (comment) is some separate uncertainty about when and why I think this issue is still fully separate from #26404, as this is just about documenting |
It looks like one way to get the version to show up, is to make a new module referring to the one you actually want to build; and then build the target module.
|
Or even just any of the current VCS state. For Caddy's builds, we use tag if clean, or if not clean: nearest tag, commit SHA, and build date (although I can understand why build date is a bad idea if seeking reproducible builds). For now, @mark-rushakoff's workaround is quite handy. +1 to this though, some version info on the main module would be immensely helpful. |
As observed in #33926, currently it's possible to end up building a binary with the same main module version but with different dependency versions. People who intend to use the main module version as the binary version should be careful. |
Using the “main module” version as the binary version (in the sense of https://tip.golang.org/cmd/go/#hdr-The_main_module_and_the_build_list) should be fine as long as the module doesn't have filesystem-local Unfortunately, that is not the version that the So I agree that the |
Will this be a high priority for Go 1.14? It could really ease the burden of build-from-souce workflows. Like, a lot. |
@mholt, this is unlikely to happen in Go 1.14. (We have a pretty full slate of issues already, and any time the |
Is using the git command really a requirement of this feature? Wouldn't it be possible to get the relevant metadata directly from .git/HEAD? |
@mback2k,
|
The original point of this issue was simply documenting what it means when BuildInfo.Main.Version returns the string |
BuildInfo.Main.Version always returns "(devel)". I oppose documenting this, because I believe this is a bug: BuildInfo.Main.Version always returns "(devel)" even when the main module is versioned at HEAD. Documenting that it always returns "(devel)" makes it appear as correct behavior and makes it hard or impossible to change later. Let's fix the actual problem, not document the bug as expected behavior. |
@mholt, we can document the current behavior in a way that does not promise that behavior for all time. For example, we can document that |
nit:
The intention was that the BuildInfo.Main is the module that contains the main package, not the main module described in https://golang.org/cmd/go/#hdr-The_main_module_and_the_build_list I hope correcting the documentation error will help explaining this BuildInfo.Main.Version == "(devel)" case. |
Yeah, I think what we want is the version for the "main module" - the module that contains the main package. |
**Public-Facing Changes** None. **Description** With context from golang/go#29228, the result of runtime/debug.BuildInfo.Main.Version is not well defined. Here we use an internally-defined Version as our library version in all contexts. We also add a test when using a go library release tag `go/mcap/v1.2.3` that the Version string is correct. This PR also changes the behaviour of `Writer` to only append the existing library version if it's different from the current version. This removes the awkward behaviour of `mcap filter` where the resulting mcap Library would be `mcap go #(devel); mcap go #(devel); mcap go #(devel)...`. Fixes #591
`weaver version` is supposed to print out the weaver module version, something like: ``` $ weaver version weaver v0.15.0 ``` Previously, we used [`runtime.ReadBuildInfo`][ReadBuildInfo] to read the version of the main module. However, I realized that this version was always the string `(devel)`. At first, I thought the version was `(devel)` when on a non-tagged commit, but later realized that it is literally always `(devel)`: golang/go#29228. I did some Googling to figure out how to print out the current module version, but it seems impossible? This PR gives up and sticks with showing the git commit. It's not as clear, but you can look up the commit in the repo history to find the module version. [ReadBuildInfo]: https://pkg.go.dev/runtime/debug#ReadBuildInfo
`weaver version` is supposed to print out the weaver module version, something like: ``` $ weaver version weaver v0.15.0 ``` Previously, we used [`runtime.ReadBuildInfo`][ReadBuildInfo] to read the version of the main module. However, I realized that this version was always the string `(devel)`. At first, I thought the version was `(devel)` when on a non-tagged commit, but later realized that it is literally always `(devel)`: golang/go#29228. I did some Googling to figure out how to print out the current module version, but it seems impossible? This PR gives up and sticks with showing the git commit. It's not as clear, but you can look up the commit in the repo history to find the module version. [ReadBuildInfo]: https://pkg.go.dev/runtime/debug#ReadBuildInfo
`weaver version` is supposed to print out the weaver module version, something like: ``` $ weaver version weaver v0.15.0 ``` Previously, we used [`runtime.ReadBuildInfo`][ReadBuildInfo] to read the version of the main module. However, I realized that this version was always the string `(devel)`. At first, I thought the version was `(devel)` when on a non-tagged commit, but later realized that it is literally always `(devel)`: golang/go#29228. I did some Googling to figure out how to print out the current module version, but it seems impossible? This PR gives up and sticks with showing the git commit. It's not as clear, but you can look up the commit in the repo history to find the module version. [ReadBuildInfo]: https://pkg.go.dev/runtime/debug#ReadBuildInfo
> Module Version We want a `weaver version` command that prints out the weaver module version the `weaver` binary was built with, or failing that, the commit at which the binary was built. Unfortunately, both of these things are hard. There is currently no nice way to automatically get the version of the main module in a go program [1]. There is a way to get the git commit using `debug.ReadBuildInfo()` [2], but when `go install`ing a binary, the version control information is stripped. Browsing existing open source projects, it seems the standard practice is to hard code the module version in the code. This PR does that and updates the `weaver version` command to use it: ``` $ weaver version weaver v0.17.0 linux/amd64 ``` > Other Versions The weaver repo has two other versioned APIs: the deployer API version and the codegen version. Currently, the deployer API version is the latest module version where the deployer API changed (and the same for the codegen version). We discussed offline the idea of replacing the three versions (module, deployer API, codegen) with just the module version. Then, we could write additional code to check version compatibility. Is codegen v0.17.3 incompatible with v0.12.0, for example? When trying to implement this, however, I ran into some problems. For example, let's say a deployer is at version v0.10.0 and tries to deploy an app at version v0.12.0. Is deployer API version v0.12.0 compatible with version v0.10.0? Well, the deployer was written before v0.12.0 was even created, so it doesn't have a good way to know. The codegen version is also tricky because it relies on some compiler tricks to prevent an app from compiling if it has code generated with a stale version of `weaver generate`. I'm not sure how to implement these tricks without hardcoding a codegen version. Because of these challenges, I decided to stick with our current approach to versioning, for now at least. To clean things up a bit though, I moved all versioning related code to `runtime/version.go`. I also moved some code to the `bin` package because it felt more appropriate there. [1]: golang/go#29228 [2]: https://pkg.go.dev/runtime/debug#ReadBuildInfo
> Module Version We want a `weaver version` command that prints out the weaver module version the `weaver` binary was built with, or failing that, the commit at which the binary was built. Unfortunately, both of these things are hard. There is currently no nice way to automatically get the version of the main module in a go program [1]. There is a way to get the git commit using `debug.ReadBuildInfo()` [2], but when `go install`ing a binary, the version control information is stripped. Browsing existing open source projects, it seems the standard practice is to hard code the module version in the code. This PR does that and updates the `weaver version` command to use it: ``` $ weaver version weaver v0.17.0 linux/amd64 ``` > Other Versions The weaver repo has two other versioned APIs: the deployer API version and the codegen version. Currently, the deployer API version is the latest module version where the deployer API changed (and the same for the codegen version). We discussed offline the idea of replacing the three versions (module, deployer API, codegen) with just the module version. Then, we could write additional code to check version compatibility. Is codegen v0.17.3 incompatible with v0.12.0, for example? When trying to implement this, however, I ran into some problems. For example, let's say a deployer is at version v0.10.0 and tries to deploy an app at version v0.12.0. Is deployer API version v0.12.0 compatible with version v0.10.0? Well, the deployer was written before v0.12.0 was even created, so it doesn't have a good way to know. The codegen version is also tricky because it relies on some compiler tricks to prevent an app from compiling if it has code generated with a stale version of `weaver generate`. I'm not sure how to implement these tricks without hardcoding a codegen version. Because of these challenges, I decided to stick with our current approach to versioning, for now at least. To clean things up a bit though, I moved all versioning related code to `runtime/version.go`. I also moved some code to the `bin` package because it felt more appropriate there. [1]: golang/go#29228 [2]: https://pkg.go.dev/runtime/debug#ReadBuildInfo
> Module Version We want a `weaver version` command that prints out the weaver module version the `weaver` binary was built with, or failing that, the commit at which the binary was built. Unfortunately, both of these things are hard. There is currently no nice way to automatically get the version of the main module in a go program [1]. There is a way to get the git commit using `debug.ReadBuildInfo()` [2], but when `go install`ing a binary, the version control information is stripped. Browsing existing open source projects, it seems the standard practice is to hard code the module version in the code. This PR does that and updates the `weaver version` command to use it: ``` $ weaver version weaver v0.17.0 linux/amd64 ``` > Other Versions The weaver repo has two other versioned APIs: the deployer API version and the codegen version. Currently, the deployer API version is the latest module version where the deployer API changed (and the same for the codegen version). We discussed offline the idea of replacing the three versions (module, deployer API, codegen) with just the module version. Then, we could write additional code to check version compatibility. Is codegen v0.17.3 incompatible with v0.12.0, for example? When trying to implement this, however, I ran into some problems. For example, let's say a deployer is at version v0.10.0 and tries to deploy an app at version v0.12.0. Is deployer API version v0.12.0 compatible with version v0.10.0? Well, the deployer was written before v0.12.0 was even created, so it doesn't have a good way to know. The codegen version is also tricky because it relies on some compiler tricks to prevent an app from compiling if it has code generated with a stale version of `weaver generate`. I'm not sure how to implement these tricks without hardcoding a codegen version. Because of these challenges, I decided to stick with our current approach to versioning, for now at least. To clean things up a bit though, I moved all versioning related code to `runtime/version.go`. I also moved some code to the `bin` package because it felt more appropriate there. [1]: golang/go#29228 [2]: https://pkg.go.dev/runtime/debug#ReadBuildInfo
I was wondering if there have been any updates on this since the last comment in March 2022; potentially in other issue's I may not be aware of? |
Due to golang being annoying the VCS version isn't recorded in debug.ReadBuildInfo when using `go build`. If you have too much time, see: - golang/go#29228 - golang/go#50603
What version of Go are you using (
go version
)?What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Repro case is https://github.com/mark-rushakoff/debug-module-version-demo. It's a module, and its main.go contents are a simple use of
debug.ReadBuildInfo
:What did you expect to see?
I expected to see the first line print
github.com/mark-rushakoff/debug-module-version-demo version v0.0.0-20181213...
when checked out at an arbitrary commit, orgit.luolix.top/mark-rushakoff/debug-module-version-demo version v0.0.1
when checked out at tag v0.0.1. I tried bothgo run .
andgo build . && ./debug-module-version-demo
but both cases printed(devel)
.What did you see instead?
Based on the behavior I've observed, it looks as though the main module returned by
debug.ReadBuildInfo
is hardcoded to(devel)
for the main module, which I assume is intended behavior. If so, that's unfortunate for use cases likemycmd version
to easily print the module version of the software being built; but it should be documented.The current documentation at https://tip.golang.org/pkg/runtime/debug/#ReadBuildInfo does not mention
(devel)
in any way, nor does it mention any special behavior of theMain
module./cc @hyangah since you're on git blame for src/runtime/debug/mod.go.
The text was updated successfully, but these errors were encountered: